From 92c59963f82f81aa3202657e7fdbb2592924ede3 Mon Sep 17 00:00:00 2001 From: "cedeel@gmail.com" Date: Thu, 14 Jun 2012 13:06:06 +0000 Subject: Attempt to bring sanity to newlines across systems. git-svn-id: http://mc-server.googlecode.com/svn/trunk@606 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- WebServer/Globals.cpp | 20 +- WebServer/Socket.cpp | 744 +- WebServer/StdHelpers.cpp | 124 +- WebServer/UrlHelper.cpp | 330 +- WebServer/WebServer.cpp | 994 +- WebServer/base64.cpp | 198 +- WebServer/cEvents.cpp | 250 +- converter/source/MemoryLeak.h | 36 +- converter/source/cDeNotch.cpp | 8 +- converter/source/cMakeDir.cpp | 46 +- converter/source/cMakeDir.h | 12 +- converter/source/main.cpp | 8 +- iniFile/iniFile.cpp | 1212 +- iniFile/iniFile.h | 372 +- source/Bindings.cpp | 42674 +++++++++---------- source/Bindings.h | 16 +- source/BioGen.cpp | 586 +- source/BioGen.h | 342 +- source/BlockID.cpp | 650 +- source/BlockID.h | 1282 +- source/ChunkDef.h | 984 +- source/ChunkSender.cpp | 600 +- source/ChunkSender.h | 306 +- source/CompoGen.cpp | 854 +- source/CompoGen.h | 308 +- source/CraftingRecipes.cpp | 1530 +- source/CraftingRecipes.h | 344 +- source/Defines.h | 586 +- source/Endianness.h | 140 +- source/FastNBT.cpp | 1060 +- source/FastNBT.h | 548 +- source/FileDefine.h | 40 +- source/FinishGen.cpp | 570 +- source/FinishGen.h | 180 +- source/Globals.cpp | 20 +- source/Globals.h | 404 +- source/HeiGen.cpp | 604 +- source/HeiGen.h | 274 +- source/LeakFinder.cpp | 2080 +- source/LeakFinder.h | 290 +- source/LightingThread.cpp | 1062 +- source/LightingThread.h | 352 +- source/LuaFunctions.h | 34 +- source/LuaItems.h | 104 +- source/ManualBindings.cpp | 1228 +- source/ManualBindings.h | 14 +- source/Matrix4f.cpp | 8 +- source/Matrix4f.h | 222 +- source/MemoryLeak.h | 38 +- source/MersenneTwister.h | 912 +- source/PacketID.h | 122 +- source/SquirrelBindings.cpp | 280 +- source/SquirrelBindings.h | 30 +- source/StackWalker.cpp | 2690 +- source/StackWalker.h | 428 +- source/StringCompression.cpp | 110 +- source/StringCompression.h | 34 +- source/StringUtils.cpp | 464 +- source/StringUtils.h | 124 +- source/StructGen.cpp | 928 +- source/StructGen.h | 244 +- source/Trees.cpp | 1076 +- source/Trees.h | 170 +- source/Vector3d.cpp | 44 +- source/Vector3d.h | 82 +- source/Vector3f.cpp | 66 +- source/Vector3f.h | 92 +- source/Vector3i.cpp | 30 +- source/Vector3i.h | 74 +- source/WSSAnvil.cpp | 1910 +- source/WSSAnvil.h | 262 +- source/WSSCompact.cpp | 1884 +- source/WSSCompact.h | 288 +- source/WorldStorage.cpp | 758 +- source/WorldStorage.h | 262 +- source/cAggressiveMonster.cpp | 154 +- source/cAuthenticator.cpp | 548 +- source/cAuthenticator.h | 170 +- source/cBlockEntity.h | 186 +- source/cBlockToPickup.cpp | 646 +- source/cBlockToPickup.h | 56 +- source/cBlockingTCPLink.cpp | 300 +- source/cBlockingTCPLink.h | 56 +- source/cCavespider.cpp | 118 +- source/cChatColor.cpp | 78 +- source/cChatColor.h | 86 +- source/cChestEntity.cpp | 468 +- source/cChestEntity.h | 132 +- source/cChicken.cpp | 112 +- source/cChicken.h | 28 +- source/cChunk.cpp | 3286 +- source/cChunk.h | 542 +- source/cChunk.inl.h | 68 +- source/cChunkGenerator.cpp | 1088 +- source/cChunkGenerator.h | 452 +- source/cChunkMap.cpp | 2970 +- source/cChunkMap.h | 562 +- source/cClientHandle.cpp | 4168 +- source/cClientHandle.h | 478 +- source/cCow.cpp | 112 +- source/cCraftingWindow.cpp | 262 +- source/cCraftingWindow.h | 24 +- source/cCreativeInventory.cpp | 76 +- source/cCreativeInventory.h | 26 +- source/cCreeper.cpp | 104 +- source/cCriticalSection.cpp | 314 +- source/cCriticalSection.h | 142 +- source/cCuboid.cpp | 38 +- source/cCuboid.h | 78 +- source/cDoors.h | 122 +- source/cEnderman.cpp | 126 +- source/cEnderman.h | 30 +- source/cEntity.cpp | 764 +- source/cEntity.h | 296 +- source/cEvent.cpp | 236 +- source/cEvent.h | 94 +- source/cFile.cpp | 542 +- source/cFile.h | 216 +- source/cFileFormatUpdater.cpp | 286 +- source/cFileFormatUpdater.h | 20 +- source/cFireSimulator.cpp | 262 +- source/cFireSimulator.h | 94 +- source/cFluidSimulator.cpp | 1376 +- source/cFluidSimulator.h | 108 +- source/cFurnaceEntity.cpp | 802 +- source/cFurnaceEntity.h | 148 +- source/cFurnaceRecipe.cpp | 480 +- source/cFurnaceRecipe.h | 92 +- source/cFurnaceWindow.cpp | 92 +- source/cFurnaceWindow.h | 30 +- source/cGhast.cpp | 98 +- source/cGhast.h | 28 +- source/cGroup.cpp | 72 +- source/cGroup.h | 78 +- source/cGroupManager.cpp | 214 +- source/cGroupManager.h | 32 +- source/cHeartBeat.cpp | 288 +- source/cHeartBeat.h | 56 +- source/cInventory.cpp | 720 +- source/cInventory.h | 164 +- source/cIsThread.cpp | 334 +- source/cIsThread.h | 156 +- source/cItem.cpp | 102 +- source/cItem.h | 228 +- source/cLadder.h | 84 +- source/cLavaSimulator.cpp | 38 +- source/cLavaSimulator.h | 22 +- source/cLog.cpp | 318 +- source/cLog.h | 64 +- source/cLuaChunk.cpp | 8 +- source/cLuaChunk.h | 276 +- source/cLuaCommandBinder.cpp | 244 +- source/cLuaCommandBinder.h | 84 +- source/cMCLogger.cpp | 382 +- source/cMCLogger.h | 120 +- source/cMakeDir.cpp | 50 +- source/cMakeDir.h | 32 +- source/cMonster.cpp | 1120 +- source/cMonster.h | 202 +- source/cMonsterConfig.cpp | 228 +- source/cMonsterConfig.h | 32 +- source/cNoise.cpp | 608 +- source/cNoise.h | 162 +- source/cPassiveAggressiveMonster.cpp | 74 +- source/cPassiveMonster.cpp | 90 +- source/cPawn.cpp | 504 +- source/cPawn.h | 164 +- source/cPickup.cpp | 632 +- source/cPickup.h | 106 +- source/cPig.cpp | 102 +- source/cPig.h | 28 +- source/cPiston.cpp | 330 +- source/cPiston.h | 120 +- source/cPlayer.cpp | 2124 +- source/cPlayer.h | 292 +- source/cPlugin.cpp | 168 +- source/cPlugin.h | 226 +- source/cPluginManager.cpp | 1496 +- source/cPluginManager.h | 242 +- source/cPlugin_Lua.cpp | 194 +- source/cPlugin_Lua.h | 62 +- source/cPlugin_NewLua.cpp | 1100 +- source/cPlugin_NewLua.h | 118 +- source/cRedstone.cpp | 746 +- source/cRedstone.h | 244 +- source/cRedstoneSimulator.cpp | 1402 +- source/cRedstoneSimulator.h | 178 +- source/cReferenceManager.cpp | 84 +- source/cReferenceManager.h | 68 +- source/cRoot.cpp | 788 +- source/cRoot.h | 218 +- source/cSandSimulator.cpp | 182 +- source/cSandSimulator.h | 80 +- source/cSemaphore.cpp | 182 +- source/cSemaphore.h | 34 +- source/cServer.cpp | 1476 +- source/cServer.h | 264 +- source/cSheep.cpp | 130 +- source/cSheep.h | 34 +- source/cSign.h | 62 +- source/cSignEntity.cpp | 280 +- source/cSignEntity.h | 90 +- source/cSilverfish.cpp | 50 +- source/cSilverfish.h | 24 +- source/cSimulator.cpp | 66 +- source/cSimulator.h | 38 +- source/cSimulatorManager.cpp | 134 +- source/cSimulatorManager.h | 78 +- source/cSkeleton.cpp | 130 +- source/cSkeleton.h | 32 +- source/cSleep.cpp | 38 +- source/cSleep.h | 12 +- source/cSlime.cpp | 104 +- source/cSlime.h | 28 +- source/cSocket.cpp | 708 +- source/cSocket.h | 172 +- source/cSocketThreads.cpp | 1430 +- source/cSocketThreads.h | 348 +- source/cSpider.cpp | 100 +- source/cSpider.h | 28 +- source/cSquid.cpp | 118 +- source/cSquid.h | 36 +- source/cStairs.h | 56 +- source/cStep.h | 30 +- source/cStringMap.cpp | 44 +- source/cStringMap.h | 58 +- source/cSurvivalInventory.cpp | 190 +- source/cSurvivalInventory.h | 44 +- source/cTCPLink.cpp | 258 +- source/cTCPLink.h | 44 +- source/cThread.cpp | 236 +- source/cThread.h | 50 +- source/cTimer.cpp | 78 +- source/cTimer.h | 28 +- source/cTorch.h | 186 +- source/cTracer.cpp | 700 +- source/cTracer.h | 66 +- source/cWaterSimulator.cpp | 44 +- source/cWaterSimulator.h | 20 +- source/cWebAdmin.cpp | 766 +- source/cWebAdmin.h | 136 +- source/cWebPlugin.cpp | 50 +- source/cWebPlugin.h | 46 +- source/cWebPlugin_Lua.cpp | 368 +- source/cWebPlugin_Lua.h | 56 +- source/cWindow.cpp | 664 +- source/cWindow.h | 170 +- source/cWindowOwner.h | 58 +- source/cWolf.cpp | 40 +- source/cWolf.h | 24 +- source/cWorld.cpp | 3690 +- source/cWorld.h | 816 +- source/cZombie.cpp | 132 +- source/cZombie.h | 30 +- source/cZombiepigman.cpp | 134 +- source/cZombiepigman.h | 30 +- source/main.cpp | 408 +- source/md5/md5.cpp | 728 +- source/md5/md5.h | 184 +- source/packets/cPacket.cpp | 614 +- source/packets/cPacket.h | 188 +- source/packets/cPacket_13.cpp | 40 +- source/packets/cPacket_13.h | 68 +- source/packets/cPacket_AddToInventory.cpp | 40 +- source/packets/cPacket_AddToInventory.h | 52 +- source/packets/cPacket_ArmAnim.cpp | 62 +- source/packets/cPacket_ArmAnim.h | 40 +- source/packets/cPacket_BlockChange.cpp | 44 +- source/packets/cPacket_BlockChange.h | 52 +- source/packets/cPacket_BlockDig.cpp | 72 +- source/packets/cPacket_BlockDig.h | 64 +- source/packets/cPacket_BlockPlace.cpp | 72 +- source/packets/cPacket_BlockPlace.h | 80 +- source/packets/cPacket_Chat.cpp | 58 +- source/packets/cPacket_Chat.h | 44 +- source/packets/cPacket_CollectItem.cpp | 38 +- source/packets/cPacket_CollectItem.h | 54 +- source/packets/cPacket_CreativeInventoryAction.cpp | 134 +- source/packets/cPacket_DestroyEntity.cpp | 60 +- source/packets/cPacket_DestroyEntity.h | 66 +- source/packets/cPacket_Disconnect.cpp | 58 +- source/packets/cPacket_Disconnect.h | 52 +- source/packets/cPacket_EntityEquipment.cpp | 96 +- source/packets/cPacket_EntityEquipment.h | 68 +- source/packets/cPacket_EntityLook.cpp | 128 +- source/packets/cPacket_EntityLook.h | 118 +- source/packets/cPacket_EntityStatus.cpp | 38 +- source/packets/cPacket_EntityStatus.h | 62 +- source/packets/cPacket_Flying.cpp | 38 +- source/packets/cPacket_Flying.h | 54 +- source/packets/cPacket_Handshake.cpp | 58 +- source/packets/cPacket_Handshake.h | 50 +- source/packets/cPacket_InventoryProgressBar.cpp | 40 +- source/packets/cPacket_InventoryProgressBar.h | 62 +- source/packets/cPacket_InventorySlot.cpp | 46 +- source/packets/cPacket_InventorySlot.h | 88 +- source/packets/cPacket_ItemData.cpp | 162 +- source/packets/cPacket_ItemData.h | 68 +- source/packets/cPacket_ItemSwitch.cpp | 58 +- source/packets/cPacket_ItemSwitch.h | 56 +- source/packets/cPacket_KeepAlive.cpp | 58 +- source/packets/cPacket_KeepAlive.h | 54 +- source/packets/cPacket_Login.cpp | 104 +- source/packets/cPacket_Login.h | 84 +- source/packets/cPacket_MapChunk.cpp | 308 +- source/packets/cPacket_MapChunk.h | 90 +- source/packets/cPacket_MultiBlock.cpp | 100 +- source/packets/cPacket_MultiBlock.h | 94 +- source/packets/cPacket_NamedEntitySpawn.cpp | 68 +- source/packets/cPacket_NamedEntitySpawn.h | 80 +- source/packets/cPacket_PickupSpawn.cpp | 94 +- source/packets/cPacket_PickupSpawn.h | 92 +- source/packets/cPacket_Ping.h | 48 +- source/packets/cPacket_Player.cpp | 486 +- source/packets/cPacket_Player.h | 300 +- source/packets/cPacket_PreChunk.cpp | 40 +- source/packets/cPacket_PreChunk.h | 72 +- source/packets/cPacket_RelativeEntityMove.cpp | 42 +- source/packets/cPacket_RelativeEntityMove.h | 66 +- source/packets/cPacket_RelativeEntityMoveLook.cpp | 48 +- source/packets/cPacket_RelativeEntityMoveLook.h | 74 +- source/packets/cPacket_Respawn.cpp | 78 +- source/packets/cPacket_Respawn.h | 74 +- source/packets/cPacket_SpawnMob.cpp | 150 +- source/packets/cPacket_SpawnMob.h | 78 +- source/packets/cPacket_TeleportEntity.cpp | 82 +- source/packets/cPacket_TeleportEntity.h | 78 +- source/packets/cPacket_TimeUpdate.cpp | 58 +- source/packets/cPacket_TimeUpdate.h | 58 +- source/packets/cPacket_UpdateHealth.cpp | 40 +- source/packets/cPacket_UpdateHealth.h | 64 +- source/packets/cPacket_UpdateSign.cpp | 82 +- source/packets/cPacket_UpdateSign.h | 72 +- source/packets/cPacket_UseEntity.cpp | 42 +- source/packets/cPacket_UseEntity.h | 62 +- source/packets/cPacket_WholeInventory.cpp | 152 +- source/packets/cPacket_WholeInventory.h | 94 +- source/packets/cPacket_WindowClick.cpp | 86 +- source/packets/cPacket_WindowClick.h | 104 +- source/packets/cPacket_WindowClose.cpp | 58 +- source/packets/cPacket_WindowClose.h | 56 +- source/packets/cPacket_WindowOpen.cpp | 42 +- source/packets/cPacket_WindowOpen.h | 64 +- source/tolua_base.h | 256 +- squirrel_3_0_1_stable/include/sqstdaux.h | 32 +- squirrel_3_0_1_stable/include/sqstdblob.h | 40 +- squirrel_3_0_1_stable/include/sqstdio.h | 106 +- squirrel_3_0_1_stable/include/sqstdmath.h | 30 +- squirrel_3_0_1_stable/include/sqstdstring.h | 66 +- squirrel_3_0_1_stable/include/sqstdsystem.h | 30 +- squirrel_3_0_1_stable/include/squirrel.h | 1000 +- squirrel_3_0_1_stable/sqstdlib/sqstdaux.cpp | 258 +- squirrel_3_0_1_stable/sqstdlib/sqstdblob.cpp | 550 +- squirrel_3_0_1_stable/sqstdlib/sqstdblobimpl.h | 216 +- squirrel_3_0_1_stable/sqstdlib/sqstdio.cpp | 838 +- squirrel_3_0_1_stable/sqstdlib/sqstdmath.cpp | 214 +- squirrel_3_0_1_stable/sqstdlib/sqstdrex.cpp | 1276 +- squirrel_3_0_1_stable/sqstdlib/sqstdstream.cpp | 672 +- squirrel_3_0_1_stable/sqstdlib/sqstdstream.h | 36 +- squirrel_3_0_1_stable/sqstdlib/sqstdstring.cpp | 756 +- squirrel_3_0_1_stable/sqstdlib/sqstdsystem.cpp | 294 +- squirrel_3_0_1_stable/squirrel/sqapi.cpp | 2912 +- squirrel_3_0_1_stable/squirrel/sqarray.h | 188 +- squirrel_3_0_1_stable/squirrel/sqbaselib.cpp | 2220 +- squirrel_3_0_1_stable/squirrel/sqclass.cpp | 426 +- squirrel_3_0_1_stable/squirrel/sqclass.h | 316 +- squirrel_3_0_1_stable/squirrel/sqclosure.h | 386 +- squirrel_3_0_1_stable/squirrel/sqcompiler.cpp | 3008 +- squirrel_3_0_1_stable/squirrel/sqcompiler.h | 154 +- squirrel_3_0_1_stable/squirrel/sqdebug.cpp | 232 +- squirrel_3_0_1_stable/squirrel/sqfuncproto.h | 308 +- squirrel_3_0_1_stable/squirrel/sqfuncstate.cpp | 1304 +- squirrel_3_0_1_stable/squirrel/sqfuncstate.h | 182 +- squirrel_3_0_1_stable/squirrel/sqlexer.cpp | 978 +- squirrel_3_0_1_stable/squirrel/sqlexer.h | 94 +- squirrel_3_0_1_stable/squirrel/sqmem.cpp | 18 +- squirrel_3_0_1_stable/squirrel/sqobject.cpp | 1310 +- squirrel_3_0_1_stable/squirrel/sqobject.h | 708 +- squirrel_3_0_1_stable/squirrel/sqopcodes.h | 264 +- squirrel_3_0_1_stable/squirrel/sqpcheader.h | 38 +- squirrel_3_0_1_stable/squirrel/sqstate.cpp | 1296 +- squirrel_3_0_1_stable/squirrel/sqstate.h | 288 +- squirrel_3_0_1_stable/squirrel/sqstring.h | 62 +- squirrel_3_0_1_stable/squirrel/sqtable.cpp | 440 +- squirrel_3_0_1_stable/squirrel/sqtable.h | 184 +- squirrel_3_0_1_stable/squirrel/squserdata.h | 80 +- squirrel_3_0_1_stable/squirrel/squtils.h | 224 +- squirrel_3_0_1_stable/squirrel/sqvm.cpp | 3428 +- squirrel_3_0_1_stable/squirrel/sqvm.h | 416 +- tolua++-1.0.93/src/bin/toluabind.c | 308 +- 390 files changed, 86875 insertions(+), 86875 deletions(-) diff --git a/WebServer/Globals.cpp b/WebServer/Globals.cpp index 2c60fd698..13c6ae709 100644 --- a/WebServer/Globals.cpp +++ b/WebServer/Globals.cpp @@ -1,10 +1,10 @@ - -// Globals.cpp - -// This file is used for precompiled header generation in MSVC environments - -#include "Globals.h" - - - - + +// Globals.cpp + +// This file is used for precompiled header generation in MSVC environments + +#include "Globals.h" + + + + diff --git a/WebServer/Socket.cpp b/WebServer/Socket.cpp index 430461fe8..2dde93b22 100644 --- a/WebServer/Socket.cpp +++ b/WebServer/Socket.cpp @@ -1,372 +1,372 @@ -/* - Socket.cpp - - Copyright (C) 2002-2004 René Nyffenegger - - This source code is provided 'as-is', without any express or implied - warranty. In no event will the author be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this source code must not be misrepresented; you must not - claim that you wrote the original source code. If you use this source code - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original source code. - - 3. This notice may not be removed or altered from any source distribution. - - René Nyffenegger rene.nyffenegger@adp-gmbh.ch -*/ - -/* - Note on point 2: - THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 -*/ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "Socket.h" -#include - -#ifndef _WIN32 - #include - #include - #include - #define SD_SEND 0x01 -#else - #define MSG_NOSIGNAL (0) -#endif - -#ifdef __MAC_NA - #define MSG_NOSIGNAL (0) -#endif - -#ifndef MSG_NOSIGNAL - #define MSG_NOSIGNAL 0 -#endif // MSG_NOSIGNAL - -using namespace std; - -int Socket::nofSockets_= 0; - - - - - -void Socket::Start() -{ - #ifdef _WIN32 - if (!nofSockets_) - { - WSADATA info; - if (WSAStartup(MAKEWORD(2,0), &info)) - { - throw "Could not start WSA"; - } - } - #endif - ++nofSockets_; -} - - - - - -void Socket::End() -{ -#ifdef _WIN32 - WSACleanup(); -#endif -} - - - - - -Socket::Socket() : - s_(INVALID_SOCKET) -{ - Start(); - // UDP: use SOCK_DGRAM instead of SOCK_STREAM - s_ = socket(AF_INET,SOCK_STREAM,0); - - if (!IsValid()) - { - throw "INVALID_SOCKET"; - } - - refCounter_ = new int(1); -} - - - - - -Socket::Socket(SOCKET s) : s_(s) -{ - Start(); - refCounter_ = new int(1); -}; - - - - - -Socket::~Socket() -{ - if (! --(*refCounter_)) - { - Close(); - delete refCounter_; - } - - --nofSockets_; - if (!nofSockets_) - { - End(); - } -} - - - - - -Socket::Socket(const Socket& o) -{ - refCounter_=o.refCounter_; - (*refCounter_)++; - s_ =o.s_; - - nofSockets_++; -} - - - - - -Socket& Socket::operator=(Socket& o) -{ - (*o.refCounter_)++; - - refCounter_ = o.refCounter_; - s_ = o.s_; - - nofSockets_++; - - return *this; -} - - - - - -bool Socket::IsValid(void) const -{ - #ifdef _WIN32 - return (s_ != INVALID_SOCKET); - #else - return (s_ >= 0); - #endif -} - - - - - -void Socket::Close( bool a_WaitSend /* = false */ ) -{ - if (IsValid()) - { - if (a_WaitSend) - { - assert( shutdown(s_, SD_SEND ) == 0 ); - char c; - while( recv(s_, &c, 1, 0 ) > 0 ) - {} - } - - #ifndef _WIN32 - // Linux needs to shut the socket down first, otherwise the socket keeps blocking accept() and select() calls! - // Ref.: http://forum.mc-server.org/showthread.php?tid=344 - if (shutdown(s_, SHUT_RDWR) != 0) - { - LOGWARN("Error on shutting down socket %d", s_); - } - #endif // _WIN32 - - closesocket(s_); - - s_ = INVALID_SOCKET; - } -} - - - - - -std::string Socket::ReceiveLine() -{ - std::string ret; - while (1) - { - char r; - - if (recv(s_, &r, 1, 0) <= 0 ) - { - return ""; - } - ret += r; - if (r == '\n') return ret; - } -} - - - - - -std::string Socket::ReceiveBytes( unsigned int a_Length ) -{ - std::string ret; - while( ret.size() < a_Length ) - { - char r; - - if (recv(s_, &r, 1, 0) <= 0 ) - { - return ""; - } - ret += r; - } - return ret; -} - - - - - -void Socket::SendLine(std::string s) -{ - s += '\n'; - if( send(s_,s.c_str(),s.length(),MSG_NOSIGNAL) <= 0 ) - { - //printf("SendLine Socket error!! \n" ); - Close(); - } -} - - - - - -void Socket::SendBytes(const std::string& s) -{ - if( send(s_,s.c_str(),s.length(), MSG_NOSIGNAL) <= 0 ) - { - //printf("SendBytes Socket error!! \n" ); - Close(); - } -} - - - - - -SocketServer::SocketServer(int port, int connections, TypeSocket type) -{ - sockaddr_in sa; - - memset(&sa, 0, sizeof(sa)); - - sa.sin_family = PF_INET; - sa.sin_port = htons(port); - s_ = socket(AF_INET, SOCK_STREAM, 0); - - if (!IsValid()) - { - LOG("WebServer: INVALID_SOCKET"); - } - - if(type==NonBlockingSocket) - { - return; - } - - #ifdef _WIN32 - char yes = 1; - #else - int yes = 1; - #endif - - if (setsockopt(s_,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) - { - LOG("WebServer: setsockopt == -1"); - return; - } - - /* bind the socket to the internet address */ - if (bind(s_, (sockaddr *)&sa, sizeof(sockaddr_in)) == SOCKET_ERROR) - { - closesocket(s_); - LOG("WebServer: INVALID_SOCKET"); - } - - listen(s_, connections); -} - - - - - -Socket* SocketServer::Accept() -{ - Socket * r = new Socket(accept(s_, 0, 0)); - if (!r->IsValid()) - { - delete r; - r = NULL; - } - - return r; -} - - - - - -SocketSelect::SocketSelect(Socket const * const s1, Socket const * const s2, TypeSocket type) -{ - FD_ZERO(&fds_); - SOCKET Highest = s1->s_; - FD_SET(const_cast(s1)->s_,&fds_); - if(s2) - { - FD_SET(const_cast(s2)->s_,&fds_); - if (s2->s_ > Highest) - { - Highest = s2->s_; - } - } - if (select(Highest + 1, &fds_, NULL, NULL, NULL) == SOCKET_ERROR) - { - throw "Error in select"; - } -} - - - - - -bool SocketSelect::Readable(Socket const* const s) -{ - return (FD_ISSET(s->s_,&fds_) != 0); -} - - - - +/* + Socket.cpp + + Copyright (C) 2002-2004 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch +*/ + +/* + Note on point 2: + THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 +*/ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "Socket.h" +#include + +#ifndef _WIN32 + #include + #include + #include + #define SD_SEND 0x01 +#else + #define MSG_NOSIGNAL (0) +#endif + +#ifdef __MAC_NA + #define MSG_NOSIGNAL (0) +#endif + +#ifndef MSG_NOSIGNAL + #define MSG_NOSIGNAL 0 +#endif // MSG_NOSIGNAL + +using namespace std; + +int Socket::nofSockets_= 0; + + + + + +void Socket::Start() +{ + #ifdef _WIN32 + if (!nofSockets_) + { + WSADATA info; + if (WSAStartup(MAKEWORD(2,0), &info)) + { + throw "Could not start WSA"; + } + } + #endif + ++nofSockets_; +} + + + + + +void Socket::End() +{ +#ifdef _WIN32 + WSACleanup(); +#endif +} + + + + + +Socket::Socket() : + s_(INVALID_SOCKET) +{ + Start(); + // UDP: use SOCK_DGRAM instead of SOCK_STREAM + s_ = socket(AF_INET,SOCK_STREAM,0); + + if (!IsValid()) + { + throw "INVALID_SOCKET"; + } + + refCounter_ = new int(1); +} + + + + + +Socket::Socket(SOCKET s) : s_(s) +{ + Start(); + refCounter_ = new int(1); +}; + + + + + +Socket::~Socket() +{ + if (! --(*refCounter_)) + { + Close(); + delete refCounter_; + } + + --nofSockets_; + if (!nofSockets_) + { + End(); + } +} + + + + + +Socket::Socket(const Socket& o) +{ + refCounter_=o.refCounter_; + (*refCounter_)++; + s_ =o.s_; + + nofSockets_++; +} + + + + + +Socket& Socket::operator=(Socket& o) +{ + (*o.refCounter_)++; + + refCounter_ = o.refCounter_; + s_ = o.s_; + + nofSockets_++; + + return *this; +} + + + + + +bool Socket::IsValid(void) const +{ + #ifdef _WIN32 + return (s_ != INVALID_SOCKET); + #else + return (s_ >= 0); + #endif +} + + + + + +void Socket::Close( bool a_WaitSend /* = false */ ) +{ + if (IsValid()) + { + if (a_WaitSend) + { + assert( shutdown(s_, SD_SEND ) == 0 ); + char c; + while( recv(s_, &c, 1, 0 ) > 0 ) + {} + } + + #ifndef _WIN32 + // Linux needs to shut the socket down first, otherwise the socket keeps blocking accept() and select() calls! + // Ref.: http://forum.mc-server.org/showthread.php?tid=344 + if (shutdown(s_, SHUT_RDWR) != 0) + { + LOGWARN("Error on shutting down socket %d", s_); + } + #endif // _WIN32 + + closesocket(s_); + + s_ = INVALID_SOCKET; + } +} + + + + + +std::string Socket::ReceiveLine() +{ + std::string ret; + while (1) + { + char r; + + if (recv(s_, &r, 1, 0) <= 0 ) + { + return ""; + } + ret += r; + if (r == '\n') return ret; + } +} + + + + + +std::string Socket::ReceiveBytes( unsigned int a_Length ) +{ + std::string ret; + while( ret.size() < a_Length ) + { + char r; + + if (recv(s_, &r, 1, 0) <= 0 ) + { + return ""; + } + ret += r; + } + return ret; +} + + + + + +void Socket::SendLine(std::string s) +{ + s += '\n'; + if( send(s_,s.c_str(),s.length(),MSG_NOSIGNAL) <= 0 ) + { + //printf("SendLine Socket error!! \n" ); + Close(); + } +} + + + + + +void Socket::SendBytes(const std::string& s) +{ + if( send(s_,s.c_str(),s.length(), MSG_NOSIGNAL) <= 0 ) + { + //printf("SendBytes Socket error!! \n" ); + Close(); + } +} + + + + + +SocketServer::SocketServer(int port, int connections, TypeSocket type) +{ + sockaddr_in sa; + + memset(&sa, 0, sizeof(sa)); + + sa.sin_family = PF_INET; + sa.sin_port = htons(port); + s_ = socket(AF_INET, SOCK_STREAM, 0); + + if (!IsValid()) + { + LOG("WebServer: INVALID_SOCKET"); + } + + if(type==NonBlockingSocket) + { + return; + } + + #ifdef _WIN32 + char yes = 1; + #else + int yes = 1; + #endif + + if (setsockopt(s_,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) + { + LOG("WebServer: setsockopt == -1"); + return; + } + + /* bind the socket to the internet address */ + if (bind(s_, (sockaddr *)&sa, sizeof(sockaddr_in)) == SOCKET_ERROR) + { + closesocket(s_); + LOG("WebServer: INVALID_SOCKET"); + } + + listen(s_, connections); +} + + + + + +Socket* SocketServer::Accept() +{ + Socket * r = new Socket(accept(s_, 0, 0)); + if (!r->IsValid()) + { + delete r; + r = NULL; + } + + return r; +} + + + + + +SocketSelect::SocketSelect(Socket const * const s1, Socket const * const s2, TypeSocket type) +{ + FD_ZERO(&fds_); + SOCKET Highest = s1->s_; + FD_SET(const_cast(s1)->s_,&fds_); + if(s2) + { + FD_SET(const_cast(s2)->s_,&fds_); + if (s2->s_ > Highest) + { + Highest = s2->s_; + } + } + if (select(Highest + 1, &fds_, NULL, NULL, NULL) == SOCKET_ERROR) + { + throw "Error in select"; + } +} + + + + + +bool SocketSelect::Readable(Socket const* const s) +{ + return (FD_ISSET(s->s_,&fds_) != 0); +} + + + + diff --git a/WebServer/StdHelpers.cpp b/WebServer/StdHelpers.cpp index f858c0bc4..63e48a7d2 100644 --- a/WebServer/StdHelpers.cpp +++ b/WebServer/StdHelpers.cpp @@ -1,62 +1,62 @@ -/* - stdHelpers.cpp - - Copyright (C) 2002-2004 René Nyffenegger - - This source code is provided 'as-is', without any express or implied - warranty. In no event will the author be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this source code must not be misrepresented; you must not - claim that you wrote the original source code. If you use this source code - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original source code. - - 3. This notice may not be removed or altered from any source distribution. - - René Nyffenegger rene.nyffenegger@adp-gmbh.ch -*/ - -/* - Note on point 2: - THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 -*/ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "StdHelpers.h" -#include - -std::string ReplaceInStr(const std::string& in, const std::string& search_for, const std::string& replace_with) { - std::string ret = in; - - std::string::size_type pos = ret.find(search_for); - - while (pos != std::string::npos) { - ret = ret.replace(pos, search_for.size(), replace_with); - pos = pos - search_for.size() + replace_with.size() + 1; - pos = ret.find(search_for, pos); - } - - return ret; -} - -// std:toupper and std::tolower are overloaded. Well... -// http://gcc.gnu.org/ml/libstdc++/2002-11/msg00180.html -char toLower_ (char c) { return std::tolower(c); } -char toUpper_ (char c) { return std::toupper(c); } - -void ToUpper(std::string& s) { - std::transform(s.begin(), s.end(), s.begin(),toUpper_); -} - -void ToLower(std::string& s) { - std::transform(s.begin(), s.end(), s.begin(),toLower_); -} +/* + stdHelpers.cpp + + Copyright (C) 2002-2004 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch +*/ + +/* + Note on point 2: + THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 +*/ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "StdHelpers.h" +#include + +std::string ReplaceInStr(const std::string& in, const std::string& search_for, const std::string& replace_with) { + std::string ret = in; + + std::string::size_type pos = ret.find(search_for); + + while (pos != std::string::npos) { + ret = ret.replace(pos, search_for.size(), replace_with); + pos = pos - search_for.size() + replace_with.size() + 1; + pos = ret.find(search_for, pos); + } + + return ret; +} + +// std:toupper and std::tolower are overloaded. Well... +// http://gcc.gnu.org/ml/libstdc++/2002-11/msg00180.html +char toLower_ (char c) { return std::tolower(c); } +char toUpper_ (char c) { return std::toupper(c); } + +void ToUpper(std::string& s) { + std::transform(s.begin(), s.end(), s.begin(),toUpper_); +} + +void ToLower(std::string& s) { + std::transform(s.begin(), s.end(), s.begin(),toLower_); +} diff --git a/WebServer/UrlHelper.cpp b/WebServer/UrlHelper.cpp index 44f1166fd..e0a67687b 100644 --- a/WebServer/UrlHelper.cpp +++ b/WebServer/UrlHelper.cpp @@ -1,165 +1,165 @@ -/* - UrlHelper.cpp - - Copyright (C) 2002-2004 René Nyffenegger - - This source code is provided 'as-is', without any express or implied - warranty. In no event will the author be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this source code must not be misrepresented; you must not - claim that you wrote the original source code. If you use this source code - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original source code. - - 3. This notice may not be removed or altered from any source distribution. - - René Nyffenegger rene.nyffenegger@adp-gmbh.ch -*/ - -/* - Note on point 2: - THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 -*/ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "UrlHelper.h" -#include "Tracer.h" -#include "StdHelpers.h" - -#include -#include - -bool RemoveProtocolFromUrl(std::string const& url, std::string& protocol, std::string& rest) { - TraceFunc("RemoveProtocolFromUrl"); - Trace(std::string("url='")+url+"'"); - std::string::size_type pos_colon = url.find(":"); - - if (pos_colon == std::string::npos) { - rest = url; - return false; - } - - if (url.size() < pos_colon + 2) { - rest = url; - return false; - } - - if (url[pos_colon+1] != '/' || - url[pos_colon+2] != '/') { - rest = url; - return false; - } - - protocol = url.substr(0,pos_colon); - rest = url.substr(3+pos_colon); // Skipping three characters ( '://' ) - - return true; -} - -void SplitGetReq(std::string get_req, std::string& path, std::map& params) { - TraceFunc("SplitGetReq"); - - // Remove trailing newlines - if (get_req[get_req.size()-1] == '\x0d' || - get_req[get_req.size()-1] == '\x0a') - get_req=get_req.substr(0, get_req.size()-1); - - if (get_req[get_req.size()-1] == '\x0d' || - get_req[get_req.size()-1] == '\x0a') - get_req=get_req.substr(0, get_req.size()-1); - - // Remove potential Trailing HTTP/1.x - if (get_req.size() > 7) { - if (get_req.substr(get_req.size()-8, 7) == "HTTP/1.") { - get_req=get_req.substr(0, get_req.size()-9); - } - } - - std::string::size_type qm = get_req.find("?"); - if (qm != std::string::npos) { - std::string url_params = get_req.substr(qm+1); - - path = get_req.substr(0, qm); - - // Appending a '&' so that there are as many '&' as name-value pairs. - // It makes it easier to split the url for name value pairs, he he he - url_params += "&"; - - std::string::size_type next_amp = url_params.find("&"); - - while (next_amp != std::string::npos) { - std::string name_value = url_params.substr(0,next_amp); - url_params = url_params.substr(next_amp+1); - next_amp = url_params.find("&"); - - std::string::size_type pos_equal = name_value.find("="); - - std::string nam = name_value.substr(0,pos_equal); - std::string val = name_value.substr(pos_equal+1); - - std::string::size_type pos_plus; - while ( (pos_plus = val.find("+")) != std::string::npos ) { - val.replace(pos_plus, 1, " "); - } - - // Replacing %xy notation - std::string::size_type pos_hex = 0; - while ( (pos_hex = val.find("%", pos_hex)) != std::string::npos ) { - std::stringstream h; - h << val.substr(pos_hex+1, 2); - h << std::hex; - - int i; - h>>i; - - std::stringstream f; - f << static_cast(i); - std::string s; - f >> s; - - val.replace(pos_hex, 3, s); - pos_hex ++; - } - - params.insert(std::map::value_type(nam, val)); - } - } - else { - path = get_req; - } -} - -void SplitUrl(std::string const& url, std::string& protocol, std::string& server, std::string& path) { - TraceFunc("SplitUrl"); - RemoveProtocolFromUrl(url, protocol, server); - - if (protocol == "http") { - std::string::size_type pos_slash = server.find("/"); - - if (pos_slash != std::string::npos) { - Trace("slash found"); - path = server.substr(pos_slash); - server = server.substr(0, pos_slash); - } - else { - Trace("slash not found"); - path = "/"; - } - } - else if (protocol == "file") { - path = ReplaceInStr(server, "\\", "/"); - server = ""; - } - else { - std::cerr << "unknown protocol in SplitUrl: '" << protocol << "'" << std::endl; - } -} +/* + UrlHelper.cpp + + Copyright (C) 2002-2004 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch +*/ + +/* + Note on point 2: + THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 +*/ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "UrlHelper.h" +#include "Tracer.h" +#include "StdHelpers.h" + +#include +#include + +bool RemoveProtocolFromUrl(std::string const& url, std::string& protocol, std::string& rest) { + TraceFunc("RemoveProtocolFromUrl"); + Trace(std::string("url='")+url+"'"); + std::string::size_type pos_colon = url.find(":"); + + if (pos_colon == std::string::npos) { + rest = url; + return false; + } + + if (url.size() < pos_colon + 2) { + rest = url; + return false; + } + + if (url[pos_colon+1] != '/' || + url[pos_colon+2] != '/') { + rest = url; + return false; + } + + protocol = url.substr(0,pos_colon); + rest = url.substr(3+pos_colon); // Skipping three characters ( '://' ) + + return true; +} + +void SplitGetReq(std::string get_req, std::string& path, std::map& params) { + TraceFunc("SplitGetReq"); + + // Remove trailing newlines + if (get_req[get_req.size()-1] == '\x0d' || + get_req[get_req.size()-1] == '\x0a') + get_req=get_req.substr(0, get_req.size()-1); + + if (get_req[get_req.size()-1] == '\x0d' || + get_req[get_req.size()-1] == '\x0a') + get_req=get_req.substr(0, get_req.size()-1); + + // Remove potential Trailing HTTP/1.x + if (get_req.size() > 7) { + if (get_req.substr(get_req.size()-8, 7) == "HTTP/1.") { + get_req=get_req.substr(0, get_req.size()-9); + } + } + + std::string::size_type qm = get_req.find("?"); + if (qm != std::string::npos) { + std::string url_params = get_req.substr(qm+1); + + path = get_req.substr(0, qm); + + // Appending a '&' so that there are as many '&' as name-value pairs. + // It makes it easier to split the url for name value pairs, he he he + url_params += "&"; + + std::string::size_type next_amp = url_params.find("&"); + + while (next_amp != std::string::npos) { + std::string name_value = url_params.substr(0,next_amp); + url_params = url_params.substr(next_amp+1); + next_amp = url_params.find("&"); + + std::string::size_type pos_equal = name_value.find("="); + + std::string nam = name_value.substr(0,pos_equal); + std::string val = name_value.substr(pos_equal+1); + + std::string::size_type pos_plus; + while ( (pos_plus = val.find("+")) != std::string::npos ) { + val.replace(pos_plus, 1, " "); + } + + // Replacing %xy notation + std::string::size_type pos_hex = 0; + while ( (pos_hex = val.find("%", pos_hex)) != std::string::npos ) { + std::stringstream h; + h << val.substr(pos_hex+1, 2); + h << std::hex; + + int i; + h>>i; + + std::stringstream f; + f << static_cast(i); + std::string s; + f >> s; + + val.replace(pos_hex, 3, s); + pos_hex ++; + } + + params.insert(std::map::value_type(nam, val)); + } + } + else { + path = get_req; + } +} + +void SplitUrl(std::string const& url, std::string& protocol, std::string& server, std::string& path) { + TraceFunc("SplitUrl"); + RemoveProtocolFromUrl(url, protocol, server); + + if (protocol == "http") { + std::string::size_type pos_slash = server.find("/"); + + if (pos_slash != std::string::npos) { + Trace("slash found"); + path = server.substr(pos_slash); + server = server.substr(0, pos_slash); + } + else { + Trace("slash not found"); + path = "/"; + } + } + else if (protocol == "file") { + path = ReplaceInStr(server, "\\", "/"); + server = ""; + } + else { + std::cerr << "unknown protocol in SplitUrl: '" << protocol << "'" << std::endl; + } +} diff --git a/WebServer/WebServer.cpp b/WebServer/WebServer.cpp index 8be690bd1..089be4352 100644 --- a/WebServer/WebServer.cpp +++ b/WebServer/WebServer.cpp @@ -1,497 +1,497 @@ -/* - WebServer.cpp - - Copyright (C) 2003-2007 René Nyffenegger - - This source code is provided 'as-is', without any express or implied - warranty. In no event will the author be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this source code must not be misrepresented; you must not - claim that you wrote the original source code. If you use this source code - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original source code. - - 3. This notice may not be removed or altered from any source distribution. - - René Nyffenegger rene.nyffenegger@adp-gmbh.ch - - Thanks to Tom Lynn who pointed out an error in this source code. -*/ - -/* - Note on point 2: - THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 -*/ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include -#ifdef _WIN32 - #include -#endif -#include -#include - - -#include "WebServer.h" -#include "cEvents.h" -#include "Socket.h" -#include "UrlHelper.h" -#include "base64.h" - - - - - -webserver::request_func webserver::request_func_ = NULL; - - - - - -static std::string EatLine( std::string& a_String ) -{ - std::string RetVal = ""; - unsigned int StringSize = a_String.size(); - const char* c = a_String.c_str(); - - for( unsigned int i = 0; i < StringSize; ++i, ++c) - { - if( *c == '\n' ) - { - RetVal += *c; -// ++i; ++c; -// if( i < StringSize ) -// { -// if( *c == '\r' ) -// { -// RetVal += *c; -// } -// } - break; - } - RetVal += *c; - } - a_String = a_String.substr( RetVal.size() ); - return RetVal; -} - - - - - -// Turns -// "blabla my string with \"quotes\"!" -// into -// blabla my string with "quotes"! -static std::string GetQuotedString( const std::string& a_String ) -{ - std::string RetVal; - - bool bGotFirstQuote = false; - bool bIgnoreNext = false; - unsigned int StrLen = a_String.size(); - for( unsigned int i = 0; i < StrLen; ++i ) - { - if( bIgnoreNext == false ) - { - if( a_String[i] == '\"' ) - { - if( bGotFirstQuote == false ) - { - bGotFirstQuote = true; - } - else - { - break; - } - continue; - } - else if( a_String[i] == '\\' ) // Escape character - { - bIgnoreNext = true; - continue; - } - } - RetVal.push_back( a_String[i] ); - bIgnoreNext = false; - } - - return RetVal; -} - - - - - -void ParseMultipartFormData( webserver::http_request& req, Socket* s) -{ - static const std::string multipart_form_data = "multipart/form-data"; - if(req.content_type_.substr(0, multipart_form_data.size()) == multipart_form_data) // Difficult data... :( - { - AStringVector ContentTypeData = StringSplit( req.content_type_, "; " ); - - std::string boundary; - // Find boundary - for( unsigned int i = 0; i < ContentTypeData.size(); ++i ) - { - static const std::string boundary_ = "boundary="; - if( ContentTypeData[i].substr(0, boundary_.size()) == boundary_ ) // Found boundary - { - boundary = ContentTypeData[i].substr( boundary_.size() ); - } - } - - //LOGINFO("Boundary: %s", boundary.c_str() ); - std::string boundary_start = "--" + boundary; - std::string boundary_end = boundary_start + "--"; - - std::string Content = s->ReceiveBytes( req.content_length_ ); - - //printf("Total content: \n%s\n", Content.c_str() ); - - // Should start with boundary! - std::string line = EatLine( Content ); - if( line.substr(0, boundary_start.size() ) != boundary_start ) - { - // Something was wrong! :( - Content.clear(); - } - - while( !Content.empty() ) - { - webserver::formdata FormData; - - static const std::string content_disposition = "Content-Disposition: "; - static const std::string content_type = "Content-Type: "; - - std::string f_disposition; - - while( 1 ) - { - std::string line = EatLine( Content ); - if( line.empty() ) - break; - - unsigned int pos_cr_lf = line.find_first_of("\x0a\x0d"); - if (pos_cr_lf == 0) break; // Empty line, indicates end of mime thingy - - if( line.substr(0, content_disposition.size() ) == content_disposition ) - { - f_disposition = line.substr(content_disposition.size()); - LOGINFO("Disposition: %s", f_disposition.c_str() ); - } - else if( line.substr(0, content_type.size() ) == content_type ) - { - FormData.content_type_ = line.substr(content_type.size()); - } - - //LOGINFO("Got line: '%s'", line.c_str() ); - } - - // Check if we got the proper headers - if( !f_disposition.empty() ) - { - static const std::string disp_name = "name="; - static const std::string disp_filename = "filename="; - - // Parse the disposition - AStringVector DispositionData = StringSplit( f_disposition, "; " ); - for( unsigned int i = 0; i < DispositionData.size(); ++i ) - { - if( DispositionData[i].substr(0, disp_name.size()) == disp_name ) - { - FormData.name_ = GetQuotedString( DispositionData[i].substr(disp_name.size()) ); - } - else if( DispositionData[i].substr(0, disp_filename.size()) == disp_filename ) - { - FormData.filename_ = GetQuotedString( DispositionData[i].substr(disp_filename.size()) ); - } - } - - std::string ContentValue; - // Parse until boundary_end is found - while( 1 ) - { - std::string line = EatLine( Content ); - if( line.empty() ) - break; - - if( line.substr(0, boundary_end.size() ) == boundary_end ) - { - break; - } - else if( line.substr(0, boundary_start.size() ) == boundary_start ) - { - break; - } - ContentValue.append( line.c_str(), line.size() ); - } - - - FormData.value_ = ContentValue; - } - - req.multipart_formdata_.push_back( FormData ); - } - } -} - - - - - -#ifdef _WIN32 -unsigned webserver::Request(void* ptr_s) -#else -void* webserver::Request(void* ptr_s) -#endif -{ - Socket* s = (reinterpret_cast(ptr_s)); - - std::string line = s->ReceiveLine(); - if (line.empty()) - { - s->Close(); - delete s; - return 0; - } - - http_request req; - std::string path; - std::map params; - size_t posStartPath = 0; - - if (line.find("GET") == 0) - { - req.method_="GET"; - posStartPath = line.find_first_not_of(" ",3); - } - else if (line.find("POST") == 0) - { - req.method_="POST"; - posStartPath = line.find_first_not_of(" ",4); - } - - SplitGetReq(line.substr(posStartPath), path, params); - - req.status_ = "202 OK"; - req.s_ = s; - req.path_ = path; - req.params_ = params; - - static const std::string authorization = "Authorization: Basic "; - static const std::string accept = "Accept: " ; - static const std::string accept_language = "Accept-Language: " ; - static const std::string accept_encoding = "Accept-Encoding: " ; - static const std::string user_agent = "User-Agent: " ; - static const std::string content_length = "Content-Length: " ; - static const std::string content_type = "Content-Type: " ; - - while(1) - { - line=s->ReceiveLine(); - if (line.empty()) - { - break; - } - - unsigned int pos_cr_lf = line.find_first_of("\x0a\x0d"); - if (pos_cr_lf == 0) break; - - line = line.substr(0,pos_cr_lf); - - if (line.substr(0, authorization.size()) == authorization) - { - req.authentication_given_ = true; - std::string encoded = line.substr(authorization.size()); - std::string decoded = base64_decode(encoded); - - unsigned int pos_colon = decoded.find(":"); - - req.username_ = decoded.substr(0, pos_colon); - req.password_ = decoded.substr(pos_colon+1 ); - } - else if (line.substr(0, accept.size()) == accept) - { - req.accept_ = line.substr(accept.size()); - } - else if (line.substr(0, accept_language.size()) == accept_language) - { - req.accept_language_ = line.substr(accept_language.size()); - } - else if (line.substr(0, accept_encoding.size()) == accept_encoding) - { - req.accept_encoding_ = line.substr(accept_encoding.size()); - } - else if (line.substr(0, user_agent.size()) == user_agent) - { - req.user_agent_ = line.substr(user_agent.size()); - } - else if (line.substr(0, content_length.size()) == content_length) - { - req.content_length_ = atoi( line.substr(content_length.size()).c_str() ); - } - else if (line.substr(0, content_type.size()) == content_type) - { - req.content_type_ = line.substr(content_type.size()); - } - } - - if( (req.method_.compare("POST") == 0) && (req.content_length_ > 0) ) - { - // The only content type we can parse at the moment, the default HTML post data - if( req.content_type_.compare( "application/x-www-form-urlencoded" ) == 0 ) - { - std::string Content = s->ReceiveBytes( req.content_length_ ); - Content.insert( 0, "/ ?" ); // Little hack, inserts dummy URL so that SplitGetReq() can work with this content - - std::string dummy; - std::map post_params; - SplitGetReq(Content, dummy, post_params); - - req.params_post_ = post_params; - } - else - { - ParseMultipartFormData( req, s ); - } - } - - request_func_(&req); - - std::stringstream str_str; - str_str << req.answer_.size(); - - time_t ltime; - time(<ime); - tm* gmt= gmtime(<ime); - -#ifdef _WIN32 - static std::string const serverName = "MCServerWebAdmin (Windows)"; -#elif __APPLE__ - static std::string const serverName = "MCServerWebAdmin (MacOSX)"; -#else - static std::string const serverName = "MCServerWebAdmin (Linux)"; -#endif - - - char* asctime_remove_nl = std::asctime(gmt); - asctime_remove_nl[24] = 0; - - s->SendBytes("HTTP/1.1 "); - - if (! req.auth_realm_.empty() ) - { - s->SendLine("401 Unauthorized"); - s->SendBytes("WWW-Authenticate: Basic Realm=\""); - s->SendBytes(req.auth_realm_); - s->SendLine("\""); - } - else - { - s->SendLine(req.status_); - } - s->SendLine(std::string("Date: ") + asctime_remove_nl + " GMT"); - s->SendLine(std::string("Server: ") +serverName); - s->SendLine("Connection: close"); - s->SendLine("Content-Type: text/html; charset=ISO-8859-1"); - s->SendLine("Content-Length: " + str_str.str()); - s->SendLine(""); - s->SendLine(req.answer_); - - s->Close( true ); // true = wait for all data to be sent before closing - delete s; - - - return 0; -} - - - - - -void webserver::Stop() -{ - m_bStop = true; - m_Socket->Close(); - m_Events->Wait(); -} - - - - - -bool webserver::Begin() -{ - if (!m_Socket->IsValid()) - { - LOGINFO("WebAdmin: The server socket is invalid. Terminating WebAdmin."); - return false; - } - m_bStop = false; - while ( !m_bStop ) - { - Socket * ptr_s = m_Socket->Accept(); - if (m_bStop) - { - if (ptr_s != 0) - { - ptr_s->Close(); - delete ptr_s; - } - break; - } - if (ptr_s == NULL) - { - LOGINFO("WebAdmin: Accepted socket is NULL. Terminating WebAdmin to avoid busywait."); - return false; - } - - #ifdef _WIN32 - unsigned ret; - HANDLE hHandle = reinterpret_cast(_beginthreadex(NULL, 0, Request, (void *)ptr_s, 0, &ret)); - CloseHandle(hHandle); - #else - // Mattes: TODO: this handle probably leaks! - pthread_t * hHandle = new pthread_t; - pthread_create( hHandle, NULL, Request, ptr_s); - #endif - } - m_Events->Set(); - return true; -} - - - - - -webserver::webserver(unsigned int port_to_listen, request_func r) -{ - m_Socket = new SocketServer(port_to_listen, 1); - - request_func_ = r; - m_Events = new cEvents(); -} - - - - - -webserver::~webserver() -{ - delete m_Socket; - delete m_Events; -} - - - - +/* + WebServer.cpp + + Copyright (C) 2003-2007 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch + + Thanks to Tom Lynn who pointed out an error in this source code. +*/ + +/* + Note on point 2: + THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 +*/ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include +#ifdef _WIN32 + #include +#endif +#include +#include + + +#include "WebServer.h" +#include "cEvents.h" +#include "Socket.h" +#include "UrlHelper.h" +#include "base64.h" + + + + + +webserver::request_func webserver::request_func_ = NULL; + + + + + +static std::string EatLine( std::string& a_String ) +{ + std::string RetVal = ""; + unsigned int StringSize = a_String.size(); + const char* c = a_String.c_str(); + + for( unsigned int i = 0; i < StringSize; ++i, ++c) + { + if( *c == '\n' ) + { + RetVal += *c; +// ++i; ++c; +// if( i < StringSize ) +// { +// if( *c == '\r' ) +// { +// RetVal += *c; +// } +// } + break; + } + RetVal += *c; + } + a_String = a_String.substr( RetVal.size() ); + return RetVal; +} + + + + + +// Turns +// "blabla my string with \"quotes\"!" +// into +// blabla my string with "quotes"! +static std::string GetQuotedString( const std::string& a_String ) +{ + std::string RetVal; + + bool bGotFirstQuote = false; + bool bIgnoreNext = false; + unsigned int StrLen = a_String.size(); + for( unsigned int i = 0; i < StrLen; ++i ) + { + if( bIgnoreNext == false ) + { + if( a_String[i] == '\"' ) + { + if( bGotFirstQuote == false ) + { + bGotFirstQuote = true; + } + else + { + break; + } + continue; + } + else if( a_String[i] == '\\' ) // Escape character + { + bIgnoreNext = true; + continue; + } + } + RetVal.push_back( a_String[i] ); + bIgnoreNext = false; + } + + return RetVal; +} + + + + + +void ParseMultipartFormData( webserver::http_request& req, Socket* s) +{ + static const std::string multipart_form_data = "multipart/form-data"; + if(req.content_type_.substr(0, multipart_form_data.size()) == multipart_form_data) // Difficult data... :( + { + AStringVector ContentTypeData = StringSplit( req.content_type_, "; " ); + + std::string boundary; + // Find boundary + for( unsigned int i = 0; i < ContentTypeData.size(); ++i ) + { + static const std::string boundary_ = "boundary="; + if( ContentTypeData[i].substr(0, boundary_.size()) == boundary_ ) // Found boundary + { + boundary = ContentTypeData[i].substr( boundary_.size() ); + } + } + + //LOGINFO("Boundary: %s", boundary.c_str() ); + std::string boundary_start = "--" + boundary; + std::string boundary_end = boundary_start + "--"; + + std::string Content = s->ReceiveBytes( req.content_length_ ); + + //printf("Total content: \n%s\n", Content.c_str() ); + + // Should start with boundary! + std::string line = EatLine( Content ); + if( line.substr(0, boundary_start.size() ) != boundary_start ) + { + // Something was wrong! :( + Content.clear(); + } + + while( !Content.empty() ) + { + webserver::formdata FormData; + + static const std::string content_disposition = "Content-Disposition: "; + static const std::string content_type = "Content-Type: "; + + std::string f_disposition; + + while( 1 ) + { + std::string line = EatLine( Content ); + if( line.empty() ) + break; + + unsigned int pos_cr_lf = line.find_first_of("\x0a\x0d"); + if (pos_cr_lf == 0) break; // Empty line, indicates end of mime thingy + + if( line.substr(0, content_disposition.size() ) == content_disposition ) + { + f_disposition = line.substr(content_disposition.size()); + LOGINFO("Disposition: %s", f_disposition.c_str() ); + } + else if( line.substr(0, content_type.size() ) == content_type ) + { + FormData.content_type_ = line.substr(content_type.size()); + } + + //LOGINFO("Got line: '%s'", line.c_str() ); + } + + // Check if we got the proper headers + if( !f_disposition.empty() ) + { + static const std::string disp_name = "name="; + static const std::string disp_filename = "filename="; + + // Parse the disposition + AStringVector DispositionData = StringSplit( f_disposition, "; " ); + for( unsigned int i = 0; i < DispositionData.size(); ++i ) + { + if( DispositionData[i].substr(0, disp_name.size()) == disp_name ) + { + FormData.name_ = GetQuotedString( DispositionData[i].substr(disp_name.size()) ); + } + else if( DispositionData[i].substr(0, disp_filename.size()) == disp_filename ) + { + FormData.filename_ = GetQuotedString( DispositionData[i].substr(disp_filename.size()) ); + } + } + + std::string ContentValue; + // Parse until boundary_end is found + while( 1 ) + { + std::string line = EatLine( Content ); + if( line.empty() ) + break; + + if( line.substr(0, boundary_end.size() ) == boundary_end ) + { + break; + } + else if( line.substr(0, boundary_start.size() ) == boundary_start ) + { + break; + } + ContentValue.append( line.c_str(), line.size() ); + } + + + FormData.value_ = ContentValue; + } + + req.multipart_formdata_.push_back( FormData ); + } + } +} + + + + + +#ifdef _WIN32 +unsigned webserver::Request(void* ptr_s) +#else +void* webserver::Request(void* ptr_s) +#endif +{ + Socket* s = (reinterpret_cast(ptr_s)); + + std::string line = s->ReceiveLine(); + if (line.empty()) + { + s->Close(); + delete s; + return 0; + } + + http_request req; + std::string path; + std::map params; + size_t posStartPath = 0; + + if (line.find("GET") == 0) + { + req.method_="GET"; + posStartPath = line.find_first_not_of(" ",3); + } + else if (line.find("POST") == 0) + { + req.method_="POST"; + posStartPath = line.find_first_not_of(" ",4); + } + + SplitGetReq(line.substr(posStartPath), path, params); + + req.status_ = "202 OK"; + req.s_ = s; + req.path_ = path; + req.params_ = params; + + static const std::string authorization = "Authorization: Basic "; + static const std::string accept = "Accept: " ; + static const std::string accept_language = "Accept-Language: " ; + static const std::string accept_encoding = "Accept-Encoding: " ; + static const std::string user_agent = "User-Agent: " ; + static const std::string content_length = "Content-Length: " ; + static const std::string content_type = "Content-Type: " ; + + while(1) + { + line=s->ReceiveLine(); + if (line.empty()) + { + break; + } + + unsigned int pos_cr_lf = line.find_first_of("\x0a\x0d"); + if (pos_cr_lf == 0) break; + + line = line.substr(0,pos_cr_lf); + + if (line.substr(0, authorization.size()) == authorization) + { + req.authentication_given_ = true; + std::string encoded = line.substr(authorization.size()); + std::string decoded = base64_decode(encoded); + + unsigned int pos_colon = decoded.find(":"); + + req.username_ = decoded.substr(0, pos_colon); + req.password_ = decoded.substr(pos_colon+1 ); + } + else if (line.substr(0, accept.size()) == accept) + { + req.accept_ = line.substr(accept.size()); + } + else if (line.substr(0, accept_language.size()) == accept_language) + { + req.accept_language_ = line.substr(accept_language.size()); + } + else if (line.substr(0, accept_encoding.size()) == accept_encoding) + { + req.accept_encoding_ = line.substr(accept_encoding.size()); + } + else if (line.substr(0, user_agent.size()) == user_agent) + { + req.user_agent_ = line.substr(user_agent.size()); + } + else if (line.substr(0, content_length.size()) == content_length) + { + req.content_length_ = atoi( line.substr(content_length.size()).c_str() ); + } + else if (line.substr(0, content_type.size()) == content_type) + { + req.content_type_ = line.substr(content_type.size()); + } + } + + if( (req.method_.compare("POST") == 0) && (req.content_length_ > 0) ) + { + // The only content type we can parse at the moment, the default HTML post data + if( req.content_type_.compare( "application/x-www-form-urlencoded" ) == 0 ) + { + std::string Content = s->ReceiveBytes( req.content_length_ ); + Content.insert( 0, "/ ?" ); // Little hack, inserts dummy URL so that SplitGetReq() can work with this content + + std::string dummy; + std::map post_params; + SplitGetReq(Content, dummy, post_params); + + req.params_post_ = post_params; + } + else + { + ParseMultipartFormData( req, s ); + } + } + + request_func_(&req); + + std::stringstream str_str; + str_str << req.answer_.size(); + + time_t ltime; + time(<ime); + tm* gmt= gmtime(<ime); + +#ifdef _WIN32 + static std::string const serverName = "MCServerWebAdmin (Windows)"; +#elif __APPLE__ + static std::string const serverName = "MCServerWebAdmin (MacOSX)"; +#else + static std::string const serverName = "MCServerWebAdmin (Linux)"; +#endif + + + char* asctime_remove_nl = std::asctime(gmt); + asctime_remove_nl[24] = 0; + + s->SendBytes("HTTP/1.1 "); + + if (! req.auth_realm_.empty() ) + { + s->SendLine("401 Unauthorized"); + s->SendBytes("WWW-Authenticate: Basic Realm=\""); + s->SendBytes(req.auth_realm_); + s->SendLine("\""); + } + else + { + s->SendLine(req.status_); + } + s->SendLine(std::string("Date: ") + asctime_remove_nl + " GMT"); + s->SendLine(std::string("Server: ") +serverName); + s->SendLine("Connection: close"); + s->SendLine("Content-Type: text/html; charset=ISO-8859-1"); + s->SendLine("Content-Length: " + str_str.str()); + s->SendLine(""); + s->SendLine(req.answer_); + + s->Close( true ); // true = wait for all data to be sent before closing + delete s; + + + return 0; +} + + + + + +void webserver::Stop() +{ + m_bStop = true; + m_Socket->Close(); + m_Events->Wait(); +} + + + + + +bool webserver::Begin() +{ + if (!m_Socket->IsValid()) + { + LOGINFO("WebAdmin: The server socket is invalid. Terminating WebAdmin."); + return false; + } + m_bStop = false; + while ( !m_bStop ) + { + Socket * ptr_s = m_Socket->Accept(); + if (m_bStop) + { + if (ptr_s != 0) + { + ptr_s->Close(); + delete ptr_s; + } + break; + } + if (ptr_s == NULL) + { + LOGINFO("WebAdmin: Accepted socket is NULL. Terminating WebAdmin to avoid busywait."); + return false; + } + + #ifdef _WIN32 + unsigned ret; + HANDLE hHandle = reinterpret_cast(_beginthreadex(NULL, 0, Request, (void *)ptr_s, 0, &ret)); + CloseHandle(hHandle); + #else + // Mattes: TODO: this handle probably leaks! + pthread_t * hHandle = new pthread_t; + pthread_create( hHandle, NULL, Request, ptr_s); + #endif + } + m_Events->Set(); + return true; +} + + + + + +webserver::webserver(unsigned int port_to_listen, request_func r) +{ + m_Socket = new SocketServer(port_to_listen, 1); + + request_func_ = r; + m_Events = new cEvents(); +} + + + + + +webserver::~webserver() +{ + delete m_Socket; + delete m_Events; +} + + + + diff --git a/WebServer/base64.cpp b/WebServer/base64.cpp index 72cd7cd59..4c19b600b 100644 --- a/WebServer/base64.cpp +++ b/WebServer/base64.cpp @@ -1,99 +1,99 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "base64.h" -#include - -static const std::string base64_chars = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; - - -static inline bool is_base64(unsigned char c) { - return (isalnum(c) || (c == '+') || (c == '/')); -} - -std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) { - std::string ret; - int i = 0; - int j = 0; - unsigned char char_array_3[3]; - unsigned char char_array_4[4]; - - while (in_len--) { - char_array_3[i++] = *(bytes_to_encode++); - if (i == 3) { - char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; - char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); - char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); - char_array_4[3] = char_array_3[2] & 0x3f; - - for(i = 0; (i <4) ; i++) - ret += base64_chars[char_array_4[i]]; - i = 0; - } - } - - if (i) - { - for(j = i; j < 3; j++) - char_array_3[j] = '\0'; - - char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; - char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); - char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); - char_array_4[3] = char_array_3[2] & 0x3f; - - for (j = 0; (j < i + 1); j++) - ret += base64_chars[char_array_4[j]]; - - while((i++ < 3)) - ret += '='; - - } - - return ret; - -} - -std::string base64_decode(std::string const& encoded_string) { - int in_len = encoded_string.size(); - int i = 0; - int j = 0; - int in_ = 0; - unsigned char char_array_4[4], char_array_3[3]; - std::string ret; - - while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { - char_array_4[i++] = encoded_string[in_]; in_++; - if (i ==4) { - for (i = 0; i <4; i++) - char_array_4[i] = base64_chars.find(char_array_4[i]); - - char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); - char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); - char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; - - for (i = 0; (i < 3); i++) - ret += char_array_3[i]; - i = 0; - } - } - - if (i) { - for (j = i; j <4; j++) - char_array_4[j] = 0; - - for (j = 0; j <4; j++) - char_array_4[j] = base64_chars.find(char_array_4[j]); - - char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); - char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); - char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; - - for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; - } - - return ret; -} + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "base64.h" +#include + +static const std::string base64_chars = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + + +static inline bool is_base64(unsigned char c) { + return (isalnum(c) || (c == '+') || (c == '/')); +} + +std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) { + std::string ret; + int i = 0; + int j = 0; + unsigned char char_array_3[3]; + unsigned char char_array_4[4]; + + while (in_len--) { + char_array_3[i++] = *(bytes_to_encode++); + if (i == 3) { + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for(i = 0; (i <4) ; i++) + ret += base64_chars[char_array_4[i]]; + i = 0; + } + } + + if (i) + { + for(j = i; j < 3; j++) + char_array_3[j] = '\0'; + + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for (j = 0; (j < i + 1); j++) + ret += base64_chars[char_array_4[j]]; + + while((i++ < 3)) + ret += '='; + + } + + return ret; + +} + +std::string base64_decode(std::string const& encoded_string) { + int in_len = encoded_string.size(); + int i = 0; + int j = 0; + int in_ = 0; + unsigned char char_array_4[4], char_array_3[3]; + std::string ret; + + while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { + char_array_4[i++] = encoded_string[in_]; in_++; + if (i ==4) { + for (i = 0; i <4; i++) + char_array_4[i] = base64_chars.find(char_array_4[i]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (i = 0; (i < 3); i++) + ret += char_array_3[i]; + i = 0; + } + } + + if (i) { + for (j = i; j <4; j++) + char_array_4[j] = 0; + + for (j = 0; j <4; j++) + char_array_4[j] = base64_chars.find(char_array_4[j]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; + } + + return ret; +} diff --git a/WebServer/cEvents.cpp b/WebServer/cEvents.cpp index 4c9fa8775..a00a0e817 100644 --- a/WebServer/cEvents.cpp +++ b/WebServer/cEvents.cpp @@ -1,125 +1,125 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cEvents.h" - - - - - -cEvents::cEvents( unsigned int a_NumEvents /* = 1 */ ) - : m_NumEvents( a_NumEvents ) -#ifndef _WIN32 - , m_bNamed( false ) -#endif -{ - if( m_NumEvents < 1 ) m_NumEvents = 1; - -#ifdef _WIN32 - m_Handle = new HANDLE[ m_NumEvents ]; - for( unsigned int i = 0; i < m_NumEvents; i++) - { - ((HANDLE*)m_Handle)[i] = CreateEvent( 0, FALSE, FALSE, 0 ); - } -#else - m_Handle = new sem_t*[ m_NumEvents ]; - for( unsigned int i = 0; i < m_NumEvents; i++) - { - - sem_t* & HandlePtr = ((sem_t**)m_Handle)[i]; - HandlePtr = new sem_t; - - if( sem_init( HandlePtr, 0, 0 ) ) - { - LOG("WARNING cEvents: Could not create unnamed semaphore, fallback to named."); - m_bNamed = true; - delete HandlePtr; // named semaphores return their own address - - char c_Str[32]; - sprintf( c_Str, "cEvents%p", &HandlePtr ); - HandlePtr = sem_open( c_Str, O_CREAT, 777, 0 ); - if( HandlePtr == SEM_FAILED ) - LOG("ERROR: Could not create Event. (%i)", errno); - else - if( sem_unlink( c_Str ) != 0 ) - LOG("ERROR: Could not unlink cEvents. (%i)", errno); - } - } -#endif -} - - - - - -cEvents::~cEvents() -{ -#ifdef _WIN32 - for( unsigned int i = 0; i < m_NumEvents; i++ ) - { - CloseHandle( ((HANDLE*)m_Handle)[i] ); - } - delete [] (HANDLE*)m_Handle; -#else - for( unsigned int i = 0; i < m_NumEvents; i++ ) - { - if( m_bNamed ) - { - sem_t* & HandlePtr = ((sem_t**)m_Handle)[i]; - char c_Str[32]; - sprintf( c_Str, "cEvents%p", &HandlePtr ); - // LOG("Closing event: %s", c_Str ); - // LOG("Sem ptr: %p", HandlePtr ); - if( sem_close( HandlePtr ) != 0 ) - { - LOG("ERROR: Could not close cEvents. (%i)", errno); - } - } - else - { - sem_destroy( ((sem_t**)m_Handle)[i] ); - delete ((sem_t**)m_Handle)[i]; - } - } - delete [] (sem_t**)m_Handle; m_Handle = 0; -#endif -} - - - - - -void cEvents::Wait() -{ -#ifdef _WIN32 - WaitForMultipleObjects( m_NumEvents, (HANDLE*)m_Handle, true, INFINITE ); -#else - for(unsigned int i = 0; i < m_NumEvents; i++) - { - if( sem_wait( ((sem_t**)m_Handle)[i] ) != 0 ) - { - LOG("ERROR: Could not wait for cEvents. (%i)", errno); - } - } -#endif -} - - - - - -void cEvents::Set(unsigned int a_EventNum /* = 0 */) -{ -#ifdef _WIN32 - SetEvent( ((HANDLE*)m_Handle)[a_EventNum] ); -#else - if( sem_post( ((sem_t**)m_Handle)[a_EventNum] ) != 0 ) - { - LOG("ERROR: Could not set cEvents. (%i)", errno); - } -#endif -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cEvents.h" + + + + + +cEvents::cEvents( unsigned int a_NumEvents /* = 1 */ ) + : m_NumEvents( a_NumEvents ) +#ifndef _WIN32 + , m_bNamed( false ) +#endif +{ + if( m_NumEvents < 1 ) m_NumEvents = 1; + +#ifdef _WIN32 + m_Handle = new HANDLE[ m_NumEvents ]; + for( unsigned int i = 0; i < m_NumEvents; i++) + { + ((HANDLE*)m_Handle)[i] = CreateEvent( 0, FALSE, FALSE, 0 ); + } +#else + m_Handle = new sem_t*[ m_NumEvents ]; + for( unsigned int i = 0; i < m_NumEvents; i++) + { + + sem_t* & HandlePtr = ((sem_t**)m_Handle)[i]; + HandlePtr = new sem_t; + + if( sem_init( HandlePtr, 0, 0 ) ) + { + LOG("WARNING cEvents: Could not create unnamed semaphore, fallback to named."); + m_bNamed = true; + delete HandlePtr; // named semaphores return their own address + + char c_Str[32]; + sprintf( c_Str, "cEvents%p", &HandlePtr ); + HandlePtr = sem_open( c_Str, O_CREAT, 777, 0 ); + if( HandlePtr == SEM_FAILED ) + LOG("ERROR: Could not create Event. (%i)", errno); + else + if( sem_unlink( c_Str ) != 0 ) + LOG("ERROR: Could not unlink cEvents. (%i)", errno); + } + } +#endif +} + + + + + +cEvents::~cEvents() +{ +#ifdef _WIN32 + for( unsigned int i = 0; i < m_NumEvents; i++ ) + { + CloseHandle( ((HANDLE*)m_Handle)[i] ); + } + delete [] (HANDLE*)m_Handle; +#else + for( unsigned int i = 0; i < m_NumEvents; i++ ) + { + if( m_bNamed ) + { + sem_t* & HandlePtr = ((sem_t**)m_Handle)[i]; + char c_Str[32]; + sprintf( c_Str, "cEvents%p", &HandlePtr ); + // LOG("Closing event: %s", c_Str ); + // LOG("Sem ptr: %p", HandlePtr ); + if( sem_close( HandlePtr ) != 0 ) + { + LOG("ERROR: Could not close cEvents. (%i)", errno); + } + } + else + { + sem_destroy( ((sem_t**)m_Handle)[i] ); + delete ((sem_t**)m_Handle)[i]; + } + } + delete [] (sem_t**)m_Handle; m_Handle = 0; +#endif +} + + + + + +void cEvents::Wait() +{ +#ifdef _WIN32 + WaitForMultipleObjects( m_NumEvents, (HANDLE*)m_Handle, true, INFINITE ); +#else + for(unsigned int i = 0; i < m_NumEvents; i++) + { + if( sem_wait( ((sem_t**)m_Handle)[i] ) != 0 ) + { + LOG("ERROR: Could not wait for cEvents. (%i)", errno); + } + } +#endif +} + + + + + +void cEvents::Set(unsigned int a_EventNum /* = 0 */) +{ +#ifdef _WIN32 + SetEvent( ((HANDLE*)m_Handle)[a_EventNum] ); +#else + if( sem_post( ((sem_t**)m_Handle)[a_EventNum] ) != 0 ) + { + LOG("ERROR: Could not set cEvents. (%i)", errno); + } +#endif +} + + + + diff --git a/converter/source/MemoryLeak.h b/converter/source/MemoryLeak.h index 6ac06a302..2d62f2a4b 100644 --- a/converter/source/MemoryLeak.h +++ b/converter/source/MemoryLeak.h @@ -1,18 +1,18 @@ -#pragma once - -#ifdef _WIN32 - -#ifdef _DEBUG - -#define _CRTDBG_MAP_ALLOC -#include -#include - -#ifndef DEBUG_NEW -#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) -#define new DEBUG_NEW -#endif - -#endif - -#endif +#pragma once + +#ifdef _WIN32 + +#ifdef _DEBUG + +#define _CRTDBG_MAP_ALLOC +#include +#include + +#ifndef DEBUG_NEW +#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) +#define new DEBUG_NEW +#endif + +#endif + +#endif diff --git a/converter/source/cDeNotch.cpp b/converter/source/cDeNotch.cpp index 89075a92e..75d4ffa9d 100644 --- a/converter/source/cDeNotch.cpp +++ b/converter/source/cDeNotch.cpp @@ -25,10 +25,10 @@ inline bool fOpenFile( FILE*& a_hFile, const char* a_FileName, const char* a_Mode ) { -#ifdef _WIN32 - return fopen_s(&a_hFile, a_FileName, a_Mode ) == 0; -#else - return (a_hFile = fopen(a_FileName, a_Mode )) != 0; +#ifdef _WIN32 + return fopen_s(&a_hFile, a_FileName, a_Mode ) == 0; +#else + return (a_hFile = fopen(a_FileName, a_Mode )) != 0; #endif } diff --git a/converter/source/cMakeDir.cpp b/converter/source/cMakeDir.cpp index 60817d5aa..579d39359 100644 --- a/converter/source/cMakeDir.cpp +++ b/converter/source/cMakeDir.cpp @@ -1,24 +1,24 @@ -#include "cMakeDir.h" - -#ifndef _WIN32 -//#include // If something is missing, uncomment some of these! -//#include -//#include -#include // for mkdir -//#include -#else -#include -#endif - -void cMakeDir::MakeDir( const char* a_Directory ) -{ -#ifdef _WIN32 - SECURITY_ATTRIBUTES Attrib; - Attrib.nLength = sizeof(SECURITY_ATTRIBUTES); - Attrib.lpSecurityDescriptor = NULL; - Attrib.bInheritHandle = false; - ::CreateDirectory(a_Directory, &Attrib); -#else - mkdir(a_Directory, S_IRWXU | S_IRWXG | S_IRWXO); -#endif +#include "cMakeDir.h" + +#ifndef _WIN32 +//#include // If something is missing, uncomment some of these! +//#include +//#include +#include // for mkdir +//#include +#else +#include +#endif + +void cMakeDir::MakeDir( const char* a_Directory ) +{ +#ifdef _WIN32 + SECURITY_ATTRIBUTES Attrib; + Attrib.nLength = sizeof(SECURITY_ATTRIBUTES); + Attrib.lpSecurityDescriptor = NULL; + Attrib.bInheritHandle = false; + ::CreateDirectory(a_Directory, &Attrib); +#else + mkdir(a_Directory, S_IRWXU | S_IRWXG | S_IRWXO); +#endif } \ No newline at end of file diff --git a/converter/source/cMakeDir.h b/converter/source/cMakeDir.h index 378df2a36..240b76507 100644 --- a/converter/source/cMakeDir.h +++ b/converter/source/cMakeDir.h @@ -1,7 +1,7 @@ -#pragma once - -class cMakeDir -{ -public: - static void MakeDir( const char* a_Directory ); +#pragma once + +class cMakeDir +{ +public: + static void MakeDir( const char* a_Directory ); }; \ No newline at end of file diff --git a/converter/source/main.cpp b/converter/source/main.cpp index 6239cbd43..5df378cd6 100644 --- a/converter/source/main.cpp +++ b/converter/source/main.cpp @@ -14,8 +14,8 @@ int main () { -#ifdef _DEBUG - _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); +#ifdef _DEBUG + _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); #endif cTimer Timer; @@ -63,8 +63,8 @@ int main () clock_t progEnd = clock(); //end main program timer std::cout << "Time to complete converter: " << double(Timer.diffclock(progEnd,progBegin)) << " Seconds"<< std::endl; -#ifdef _DEBUG - _CrtDumpMemoryLeaks(); +#ifdef _DEBUG + _CrtDumpMemoryLeaks(); #endif #ifdef _WIN32 diff --git a/iniFile/iniFile.cpp b/iniFile/iniFile.cpp index 5d162ee49..8134ade8c 100644 --- a/iniFile/iniFile.cpp +++ b/iniFile/iniFile.cpp @@ -1,606 +1,606 @@ -// IniFile.cpp: Implementation of the CIniFile class. -// Written by: Adam Clauss -// Email: cabadam@houston.rr.com -// You may use this class/code as you wish in your programs. Feel free to distribute it, and -// email suggested changes to me. -// -// Rewritten by: Shane Hill -// Date: 21/08/2001 -// Email: Shane.Hill@dsto.defence.gov.au -// Reason: Remove dependancy on MFC. Code should compile on any -// platform. -////////////////////////////////////////////////////////////////////// - -/* - !! MODIFIED BY FAKETRUTH !! -*/ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -// C++ Includes -#include -#include -#include - -using namespace std; - -// C Includes -#include - -// Local Includes -#include "iniFile.h" - -#if defined(WIN32) -#define iniEOL endl -#else -#define iniEOL '\r' << endl -#endif - -#ifndef _WIN32 -#define sscanf_s(buffer, stringbuffer, ...) (sscanf(buffer, stringbuffer, __VA_ARGS__)) -#endif - - - - - -cIniFile::cIniFile( const string iniPath) -{ - Path( iniPath); - caseInsensitive = true; -} - -bool cIniFile::ReadFile() -{ - // Normally you would use ifstream, but the SGI CC compiler has - // a few bugs with ifstream. So ... fstream used. - fstream f; - string line; - string keyname, valuename, value; - string::size_type pLeft, pRight; - - f.open( path.c_str(), ios::in); - if ( f.fail()) - return false; - - while( getline( f, line)) { - // To be compatible with Win32, check for existence of '\r'. - // Win32 files have the '\r' and Unix files don't at the end of a line. - // Note that the '\r' will be written to INI files from - // Unix so that the created INI file can be read under Win32 - // without change. - unsigned int lineLength = line.length(); - if(lineLength == 0) continue; - if ( line[lineLength - 1] == '\r') - line = line.substr( 0, lineLength - 1); - - if ( line.length()) { - // Check that the user hasn't opened a binary file by checking the first - // character of each line! - if ( !isprint( line[0])) { - printf( "Failing on char %d\n", line[0]); - f.close(); - return false; - } - if (( pLeft = line.find_first_of(";#[=")) != string::npos) { - switch ( line[pLeft]) { - case '[': - if ((pRight = line.find_last_of("]")) != string::npos && - pRight > pLeft) { - keyname = line.substr( pLeft + 1, pRight - pLeft - 1); - AddKeyName( keyname); - } - break; - - case '=': - valuename = line.substr( 0, pLeft); - value = line.substr( pLeft + 1); - SetValue( keyname, valuename, value); - break; - - case ';': - case '#': - if ( !names.size()) - HeaderComment( line.substr( pLeft + 1)); - else - KeyComment( keyname, line.substr( pLeft + 1)); - break; - } - } - } - } - - f.close(); - if ( names.size()) - return true; - return false; -} - - - - - -bool cIniFile::WriteFile() -{ - unsigned commentID, keyID, valueID; - // Normally you would use ofstream, but the SGI CC compiler has - // a few bugs with ofstream. So ... fstream used. - fstream f; - - f.open( path.c_str(), ios::out); - if ( f.fail()) - return false; - - // Write header comments. - for ( commentID = 0; commentID < comments.size(); ++commentID) - f << ';' << comments[commentID] << iniEOL; - if ( comments.size()) - f << iniEOL; - - // Write keys and values. - for ( keyID = 0; keyID < keys.size(); ++keyID) { - f << '[' << names[keyID] << ']' << iniEOL; - // Comments. - for ( commentID = 0; commentID < keys[keyID].comments.size(); ++commentID) - f << ';' << keys[keyID].comments[commentID] << iniEOL; - // Values. - for ( valueID = 0; valueID < keys[keyID].names.size(); ++valueID) - f << keys[keyID].names[valueID] << '=' << keys[keyID].values[valueID] << iniEOL; - f << iniEOL; - } - f.close(); - - return true; -} - - - - - -long cIniFile::FindKey( const string & keyname) const -{ - for ( unsigned keyID = 0; keyID < names.size(); ++keyID) - if ( CheckCase( names[keyID]) == CheckCase( keyname)) - return long(keyID); - return noID; -} - - - - - -long cIniFile::FindValue( unsigned const keyID, const string & valuename) const -{ - if ( !keys.size() || keyID >= keys.size()) - return noID; - - for ( unsigned valueID = 0; valueID < keys[keyID].names.size(); ++valueID) - if ( CheckCase( keys[keyID].names[valueID]) == CheckCase( valuename)) - return long(valueID); - return noID; -} - - - - - -unsigned cIniFile::AddKeyName( const string & keyname) -{ - names.resize( names.size() + 1, keyname); - keys.resize( keys.size() + 1); - return names.size() - 1; -} - - - - - -string cIniFile::KeyName( unsigned const keyID) const -{ - if ( keyID < names.size()) - return names[keyID]; - else - return ""; -} - - - - - -unsigned cIniFile::NumValues( unsigned const keyID) -{ - if ( keyID < keys.size()) - return keys[keyID].names.size(); - return 0; -} - - - - - -unsigned cIniFile::NumValues( const string & keyname) -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return 0; - return keys[keyID].names.size(); -} - - - - - -string cIniFile::ValueName( unsigned const keyID, unsigned const valueID) const -{ - if ( keyID < keys.size() && valueID < keys[keyID].names.size()) - return keys[keyID].names[valueID]; - return ""; -} - - - - - -string cIniFile::ValueName( const string & keyname, unsigned const valueID) const -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return ""; - return ValueName( keyID, valueID); -} - - - - - -bool cIniFile::SetValue( unsigned const keyID, unsigned const valueID, const string & value) -{ - if ( keyID < keys.size() && valueID < keys[keyID].names.size()) - keys[keyID].values[valueID] = value; - - return false; -} - - - - - -bool cIniFile::SetValue( const string & keyname, const string & valuename, const string & value, bool const create) -{ - long keyID = FindKey( keyname); - if ( keyID == noID) { - if ( create) - keyID = long( AddKeyName( keyname)); - else - return false; - } - - long valueID = FindValue( unsigned(keyID), valuename); - if ( valueID == noID) { - if ( !create) - return false; - keys[keyID].names.resize( keys[keyID].names.size() + 1, valuename); - keys[keyID].values.resize( keys[keyID].values.size() + 1, value); - } else - { - if(!create) - keys[keyID].values[valueID] = value; - else - { - keys[keyID].names.resize( keys[keyID].names.size() + 1, valuename); - keys[keyID].values.resize( keys[keyID].values.size() + 1, value); - } - } - - return true; -} - - - - - -bool cIniFile::SetValueI( const string & keyname, const string & valuename, int const value, bool const create) -{ - AString Data; - Printf(Data, "%d", value); - return SetValue( keyname, valuename, Data, create); -} - - - - - -bool cIniFile::SetValueF( const string & keyname, const string & valuename, double const value, bool const create) -{ - AString Data; - Printf(Data, "%f", value); - return SetValue( keyname, valuename, Data, create); -} - - - - - -bool cIniFile::SetValueV( const string & keyname, const string & valuename, char *format, ...) -{ - va_list args; - - va_start( args, format); - - AString Data; - AppendVPrintf(Data, format, args); - va_end( args); - return SetValue( keyname, valuename, Data); -} - - - - - -string cIniFile::GetValue( unsigned const keyID, unsigned const valueID, const string & defValue) const -{ - if ( keyID < keys.size() && valueID < keys[keyID].names.size()) - return keys[keyID].values[valueID]; - return defValue; -} - - - - - -string cIniFile::GetValue( const string & keyname, const string & valuename, const string & defValue) const -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return defValue; - - long valueID = FindValue( unsigned(keyID), valuename); - if ( valueID == noID) - return defValue; - - return keys[keyID].values[valueID]; -} - - - - - -int cIniFile::GetValueI(const string & keyname, const string & valuename, int const defValue) const -{ - AString Data; - Printf(Data, "%d", defValue); - return atoi( GetValue( keyname, valuename, Data).c_str()); -} - - - - - -double cIniFile::GetValueF(const string & keyname, const string & valuename, double const defValue) const -{ - AString Data; - Printf(Data, "%f", defValue); - return atof( GetValue( keyname, valuename, Data).c_str()); -} - - - - - -AString cIniFile::GetValueSet(const AString & keyname, const AString & valuename, const AString & defValue) -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - { - SetValue(keyname, valuename, defValue); - return defValue; - } - - long valueID = FindValue( unsigned(keyID), valuename); - if ( valueID == noID) - { - SetValue(keyname, valuename, defValue); - return defValue; - } - - return keys[keyID].values[valueID]; -} - - - - - -double cIniFile::GetValueSetF(const AString & keyname, const AString & valuename, const double defValue) -{ - AString Data; - Printf(Data, "%f", defValue); - return atof(GetValueSet(keyname, valuename, Data).c_str()); -} - - - - - -int cIniFile::GetValueSetI(const AString & keyname, const AString & valuename, const int defValue) -{ - AString Data; - Printf(Data, "%d", defValue); - return atoi(GetValueSet(keyname, valuename, Data).c_str()); -} - - - - - -bool cIniFile::DeleteValueByID( const unsigned keyID, const unsigned valueID ) -{ - if ( keyID < keys.size() && valueID < keys[keyID].names.size()) - { - // This looks strange, but is neccessary. - vector::iterator npos = keys[keyID].names.begin() + valueID; - vector::iterator vpos = keys[keyID].values.begin() + valueID; - keys[keyID].names.erase( npos, npos + 1); - keys[keyID].values.erase( vpos, vpos + 1); - return true; - } - return false; -} - -bool cIniFile::DeleteValue( const string & keyname, const string & valuename) -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return false; - - long valueID = FindValue( unsigned(keyID), valuename); - if ( valueID == noID) - return false; - - return DeleteValueByID( keyID, valueID ); -} - -bool cIniFile::DeleteKey( const string & keyname) -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return false; - - // Now hopefully this destroys the vector lists within keys. - // Looking at source, this should be the case using the destructor. - // If not, I may have to do it explicitly. Memory leak check should tell. - // memleak_test.cpp shows that the following not required. - //keys[keyID].names.clear(); - //keys[keyID].values.clear(); - - vector::iterator npos = names.begin() + keyID; - vector::iterator kpos = keys.begin() + keyID; - names.erase( npos, npos + 1); - keys.erase( kpos, kpos + 1); - - return true; -} - -void cIniFile::Erase() -{ - // This loop not needed. The vector<> destructor seems to do - // all the work itself. memleak_test.cpp shows this. - //for ( unsigned i = 0; i < keys.size(); ++i) { - // keys[i].names.clear(); - // keys[i].values.clear(); - //} - names.clear(); - keys.clear(); - comments.clear(); -} - -void cIniFile::HeaderComment( const string & comment) -{ - comments.resize( comments.size() + 1, comment); -} - -string cIniFile::HeaderComment( unsigned const commentID) const -{ - if ( commentID < comments.size()) - return comments[commentID]; - return ""; -} - -bool cIniFile::DeleteHeaderComment( unsigned commentID) -{ - if ( commentID < comments.size()) { - vector::iterator cpos = comments.begin() + commentID; - comments.erase( cpos, cpos + 1); - return true; - } - return false; -} - -unsigned cIniFile::NumKeyComments( unsigned const keyID) const -{ - if ( keyID < keys.size()) - return keys[keyID].comments.size(); - return 0; -} - -unsigned cIniFile::NumKeyComments( const string & keyname) const -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return 0; - return keys[keyID].comments.size(); -} - -bool cIniFile::KeyComment( unsigned const keyID, const string & comment) -{ - if ( keyID < keys.size()) { - keys[keyID].comments.resize( keys[keyID].comments.size() + 1, comment); - return true; - } - return false; -} - -bool cIniFile::KeyComment( const string & keyname, const string & comment) -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return false; - return KeyComment( unsigned(keyID), comment); -} - -string cIniFile::KeyComment( unsigned const keyID, unsigned const commentID) const -{ - if ( keyID < keys.size() && commentID < keys[keyID].comments.size()) - return keys[keyID].comments[commentID]; - return ""; -} - -string cIniFile::KeyComment( const string & keyname, unsigned const commentID) const -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return ""; - return KeyComment( unsigned(keyID), commentID); -} - -bool cIniFile::DeleteKeyComment( unsigned const keyID, unsigned const commentID) -{ - if ( keyID < keys.size() && commentID < keys[keyID].comments.size()) { - vector::iterator cpos = keys[keyID].comments.begin() + commentID; - keys[keyID].comments.erase( cpos, cpos + 1); - return true; - } - return false; -} - -bool cIniFile::DeleteKeyComment( const string & keyname, unsigned const commentID) -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return false; - return DeleteKeyComment( unsigned(keyID), commentID); -} - -bool cIniFile::DeleteKeyComments( unsigned const keyID) -{ - if ( keyID < keys.size()) { - keys[keyID].comments.clear(); - return true; - } - return false; -} - -bool cIniFile::DeleteKeyComments( const string & keyname) -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return false; - return DeleteKeyComments( unsigned(keyID)); -} - -string cIniFile::CheckCase( string s) const -{ - if ( caseInsensitive) - for ( string::size_type i = 0; i < s.length(); ++i) - s[i] = (char)tolower(s[i]); - return s; -} +// IniFile.cpp: Implementation of the CIniFile class. +// Written by: Adam Clauss +// Email: cabadam@houston.rr.com +// You may use this class/code as you wish in your programs. Feel free to distribute it, and +// email suggested changes to me. +// +// Rewritten by: Shane Hill +// Date: 21/08/2001 +// Email: Shane.Hill@dsto.defence.gov.au +// Reason: Remove dependancy on MFC. Code should compile on any +// platform. +////////////////////////////////////////////////////////////////////// + +/* + !! MODIFIED BY FAKETRUTH !! +*/ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +// C++ Includes +#include +#include +#include + +using namespace std; + +// C Includes +#include + +// Local Includes +#include "iniFile.h" + +#if defined(WIN32) +#define iniEOL endl +#else +#define iniEOL '\r' << endl +#endif + +#ifndef _WIN32 +#define sscanf_s(buffer, stringbuffer, ...) (sscanf(buffer, stringbuffer, __VA_ARGS__)) +#endif + + + + + +cIniFile::cIniFile( const string iniPath) +{ + Path( iniPath); + caseInsensitive = true; +} + +bool cIniFile::ReadFile() +{ + // Normally you would use ifstream, but the SGI CC compiler has + // a few bugs with ifstream. So ... fstream used. + fstream f; + string line; + string keyname, valuename, value; + string::size_type pLeft, pRight; + + f.open( path.c_str(), ios::in); + if ( f.fail()) + return false; + + while( getline( f, line)) { + // To be compatible with Win32, check for existence of '\r'. + // Win32 files have the '\r' and Unix files don't at the end of a line. + // Note that the '\r' will be written to INI files from + // Unix so that the created INI file can be read under Win32 + // without change. + unsigned int lineLength = line.length(); + if(lineLength == 0) continue; + if ( line[lineLength - 1] == '\r') + line = line.substr( 0, lineLength - 1); + + if ( line.length()) { + // Check that the user hasn't opened a binary file by checking the first + // character of each line! + if ( !isprint( line[0])) { + printf( "Failing on char %d\n", line[0]); + f.close(); + return false; + } + if (( pLeft = line.find_first_of(";#[=")) != string::npos) { + switch ( line[pLeft]) { + case '[': + if ((pRight = line.find_last_of("]")) != string::npos && + pRight > pLeft) { + keyname = line.substr( pLeft + 1, pRight - pLeft - 1); + AddKeyName( keyname); + } + break; + + case '=': + valuename = line.substr( 0, pLeft); + value = line.substr( pLeft + 1); + SetValue( keyname, valuename, value); + break; + + case ';': + case '#': + if ( !names.size()) + HeaderComment( line.substr( pLeft + 1)); + else + KeyComment( keyname, line.substr( pLeft + 1)); + break; + } + } + } + } + + f.close(); + if ( names.size()) + return true; + return false; +} + + + + + +bool cIniFile::WriteFile() +{ + unsigned commentID, keyID, valueID; + // Normally you would use ofstream, but the SGI CC compiler has + // a few bugs with ofstream. So ... fstream used. + fstream f; + + f.open( path.c_str(), ios::out); + if ( f.fail()) + return false; + + // Write header comments. + for ( commentID = 0; commentID < comments.size(); ++commentID) + f << ';' << comments[commentID] << iniEOL; + if ( comments.size()) + f << iniEOL; + + // Write keys and values. + for ( keyID = 0; keyID < keys.size(); ++keyID) { + f << '[' << names[keyID] << ']' << iniEOL; + // Comments. + for ( commentID = 0; commentID < keys[keyID].comments.size(); ++commentID) + f << ';' << keys[keyID].comments[commentID] << iniEOL; + // Values. + for ( valueID = 0; valueID < keys[keyID].names.size(); ++valueID) + f << keys[keyID].names[valueID] << '=' << keys[keyID].values[valueID] << iniEOL; + f << iniEOL; + } + f.close(); + + return true; +} + + + + + +long cIniFile::FindKey( const string & keyname) const +{ + for ( unsigned keyID = 0; keyID < names.size(); ++keyID) + if ( CheckCase( names[keyID]) == CheckCase( keyname)) + return long(keyID); + return noID; +} + + + + + +long cIniFile::FindValue( unsigned const keyID, const string & valuename) const +{ + if ( !keys.size() || keyID >= keys.size()) + return noID; + + for ( unsigned valueID = 0; valueID < keys[keyID].names.size(); ++valueID) + if ( CheckCase( keys[keyID].names[valueID]) == CheckCase( valuename)) + return long(valueID); + return noID; +} + + + + + +unsigned cIniFile::AddKeyName( const string & keyname) +{ + names.resize( names.size() + 1, keyname); + keys.resize( keys.size() + 1); + return names.size() - 1; +} + + + + + +string cIniFile::KeyName( unsigned const keyID) const +{ + if ( keyID < names.size()) + return names[keyID]; + else + return ""; +} + + + + + +unsigned cIniFile::NumValues( unsigned const keyID) +{ + if ( keyID < keys.size()) + return keys[keyID].names.size(); + return 0; +} + + + + + +unsigned cIniFile::NumValues( const string & keyname) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return 0; + return keys[keyID].names.size(); +} + + + + + +string cIniFile::ValueName( unsigned const keyID, unsigned const valueID) const +{ + if ( keyID < keys.size() && valueID < keys[keyID].names.size()) + return keys[keyID].names[valueID]; + return ""; +} + + + + + +string cIniFile::ValueName( const string & keyname, unsigned const valueID) const +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return ""; + return ValueName( keyID, valueID); +} + + + + + +bool cIniFile::SetValue( unsigned const keyID, unsigned const valueID, const string & value) +{ + if ( keyID < keys.size() && valueID < keys[keyID].names.size()) + keys[keyID].values[valueID] = value; + + return false; +} + + + + + +bool cIniFile::SetValue( const string & keyname, const string & valuename, const string & value, bool const create) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) { + if ( create) + keyID = long( AddKeyName( keyname)); + else + return false; + } + + long valueID = FindValue( unsigned(keyID), valuename); + if ( valueID == noID) { + if ( !create) + return false; + keys[keyID].names.resize( keys[keyID].names.size() + 1, valuename); + keys[keyID].values.resize( keys[keyID].values.size() + 1, value); + } else + { + if(!create) + keys[keyID].values[valueID] = value; + else + { + keys[keyID].names.resize( keys[keyID].names.size() + 1, valuename); + keys[keyID].values.resize( keys[keyID].values.size() + 1, value); + } + } + + return true; +} + + + + + +bool cIniFile::SetValueI( const string & keyname, const string & valuename, int const value, bool const create) +{ + AString Data; + Printf(Data, "%d", value); + return SetValue( keyname, valuename, Data, create); +} + + + + + +bool cIniFile::SetValueF( const string & keyname, const string & valuename, double const value, bool const create) +{ + AString Data; + Printf(Data, "%f", value); + return SetValue( keyname, valuename, Data, create); +} + + + + + +bool cIniFile::SetValueV( const string & keyname, const string & valuename, char *format, ...) +{ + va_list args; + + va_start( args, format); + + AString Data; + AppendVPrintf(Data, format, args); + va_end( args); + return SetValue( keyname, valuename, Data); +} + + + + + +string cIniFile::GetValue( unsigned const keyID, unsigned const valueID, const string & defValue) const +{ + if ( keyID < keys.size() && valueID < keys[keyID].names.size()) + return keys[keyID].values[valueID]; + return defValue; +} + + + + + +string cIniFile::GetValue( const string & keyname, const string & valuename, const string & defValue) const +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return defValue; + + long valueID = FindValue( unsigned(keyID), valuename); + if ( valueID == noID) + return defValue; + + return keys[keyID].values[valueID]; +} + + + + + +int cIniFile::GetValueI(const string & keyname, const string & valuename, int const defValue) const +{ + AString Data; + Printf(Data, "%d", defValue); + return atoi( GetValue( keyname, valuename, Data).c_str()); +} + + + + + +double cIniFile::GetValueF(const string & keyname, const string & valuename, double const defValue) const +{ + AString Data; + Printf(Data, "%f", defValue); + return atof( GetValue( keyname, valuename, Data).c_str()); +} + + + + + +AString cIniFile::GetValueSet(const AString & keyname, const AString & valuename, const AString & defValue) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + { + SetValue(keyname, valuename, defValue); + return defValue; + } + + long valueID = FindValue( unsigned(keyID), valuename); + if ( valueID == noID) + { + SetValue(keyname, valuename, defValue); + return defValue; + } + + return keys[keyID].values[valueID]; +} + + + + + +double cIniFile::GetValueSetF(const AString & keyname, const AString & valuename, const double defValue) +{ + AString Data; + Printf(Data, "%f", defValue); + return atof(GetValueSet(keyname, valuename, Data).c_str()); +} + + + + + +int cIniFile::GetValueSetI(const AString & keyname, const AString & valuename, const int defValue) +{ + AString Data; + Printf(Data, "%d", defValue); + return atoi(GetValueSet(keyname, valuename, Data).c_str()); +} + + + + + +bool cIniFile::DeleteValueByID( const unsigned keyID, const unsigned valueID ) +{ + if ( keyID < keys.size() && valueID < keys[keyID].names.size()) + { + // This looks strange, but is neccessary. + vector::iterator npos = keys[keyID].names.begin() + valueID; + vector::iterator vpos = keys[keyID].values.begin() + valueID; + keys[keyID].names.erase( npos, npos + 1); + keys[keyID].values.erase( vpos, vpos + 1); + return true; + } + return false; +} + +bool cIniFile::DeleteValue( const string & keyname, const string & valuename) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return false; + + long valueID = FindValue( unsigned(keyID), valuename); + if ( valueID == noID) + return false; + + return DeleteValueByID( keyID, valueID ); +} + +bool cIniFile::DeleteKey( const string & keyname) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return false; + + // Now hopefully this destroys the vector lists within keys. + // Looking at source, this should be the case using the destructor. + // If not, I may have to do it explicitly. Memory leak check should tell. + // memleak_test.cpp shows that the following not required. + //keys[keyID].names.clear(); + //keys[keyID].values.clear(); + + vector::iterator npos = names.begin() + keyID; + vector::iterator kpos = keys.begin() + keyID; + names.erase( npos, npos + 1); + keys.erase( kpos, kpos + 1); + + return true; +} + +void cIniFile::Erase() +{ + // This loop not needed. The vector<> destructor seems to do + // all the work itself. memleak_test.cpp shows this. + //for ( unsigned i = 0; i < keys.size(); ++i) { + // keys[i].names.clear(); + // keys[i].values.clear(); + //} + names.clear(); + keys.clear(); + comments.clear(); +} + +void cIniFile::HeaderComment( const string & comment) +{ + comments.resize( comments.size() + 1, comment); +} + +string cIniFile::HeaderComment( unsigned const commentID) const +{ + if ( commentID < comments.size()) + return comments[commentID]; + return ""; +} + +bool cIniFile::DeleteHeaderComment( unsigned commentID) +{ + if ( commentID < comments.size()) { + vector::iterator cpos = comments.begin() + commentID; + comments.erase( cpos, cpos + 1); + return true; + } + return false; +} + +unsigned cIniFile::NumKeyComments( unsigned const keyID) const +{ + if ( keyID < keys.size()) + return keys[keyID].comments.size(); + return 0; +} + +unsigned cIniFile::NumKeyComments( const string & keyname) const +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return 0; + return keys[keyID].comments.size(); +} + +bool cIniFile::KeyComment( unsigned const keyID, const string & comment) +{ + if ( keyID < keys.size()) { + keys[keyID].comments.resize( keys[keyID].comments.size() + 1, comment); + return true; + } + return false; +} + +bool cIniFile::KeyComment( const string & keyname, const string & comment) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return false; + return KeyComment( unsigned(keyID), comment); +} + +string cIniFile::KeyComment( unsigned const keyID, unsigned const commentID) const +{ + if ( keyID < keys.size() && commentID < keys[keyID].comments.size()) + return keys[keyID].comments[commentID]; + return ""; +} + +string cIniFile::KeyComment( const string & keyname, unsigned const commentID) const +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return ""; + return KeyComment( unsigned(keyID), commentID); +} + +bool cIniFile::DeleteKeyComment( unsigned const keyID, unsigned const commentID) +{ + if ( keyID < keys.size() && commentID < keys[keyID].comments.size()) { + vector::iterator cpos = keys[keyID].comments.begin() + commentID; + keys[keyID].comments.erase( cpos, cpos + 1); + return true; + } + return false; +} + +bool cIniFile::DeleteKeyComment( const string & keyname, unsigned const commentID) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return false; + return DeleteKeyComment( unsigned(keyID), commentID); +} + +bool cIniFile::DeleteKeyComments( unsigned const keyID) +{ + if ( keyID < keys.size()) { + keys[keyID].comments.clear(); + return true; + } + return false; +} + +bool cIniFile::DeleteKeyComments( const string & keyname) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return false; + return DeleteKeyComments( unsigned(keyID)); +} + +string cIniFile::CheckCase( string s) const +{ + if ( caseInsensitive) + for ( string::size_type i = 0; i < s.length(); ++i) + s[i] = (char)tolower(s[i]); + return s; +} diff --git a/iniFile/iniFile.h b/iniFile/iniFile.h index 13fa15e59..58a5a52b6 100644 --- a/iniFile/iniFile.h +++ b/iniFile/iniFile.h @@ -1,186 +1,186 @@ -// IniFile.cpp: Implementation of the CIniFile class. -// Written by: Adam Clauss -// Email: cabadam@tamu.edu -// You may use this class/code as you wish in your programs. Feel free to distribute it, and -// email suggested changes to me. -// -// Rewritten by: Shane Hill -// Date: 21/08/2001 -// Email: Shane.Hill@dsto.defence.gov.au -// Reason: Remove dependancy on MFC. Code should compile on any -// platform. Tested on Windows/Linux/Irix -////////////////////////////////////////////////////////////////////// - -/* -!! MODIFIED BY FAKETRUTH and madmaxoft!! -*/ - -#ifndef CIniFile_H -#define CIniFile_H - - - - - -#define MAX_KEYNAME 128 -#define MAX_VALUENAME 128 -#define MAX_VALUEDATA 2048 - - - - - -class cIniFile //tolua_export -{ //tolua_export -private: - bool caseInsensitive; - std::string path; - struct key { - std::vector names; - std::vector values; - std::vector comments; - }; - std::vector keys; - std::vector names; - std::vector comments; - std::string CheckCase( std::string s) const; - -public: - enum errors{ noID = -1}; //tolua_export - cIniFile( const std::string iniPath = ""); //tolua_export - virtual ~cIniFile() {} - - // Sets whether or not keynames and valuenames should be case sensitive. - // The default is case insensitive. - void CaseSensitive() {caseInsensitive = false;} //tolua_export - void CaseInsensitive() {caseInsensitive = true;} //tolua_export - - // Sets path of ini file to read and write from. - void Path(const std::string & newPath) {path = newPath;} //tolua_export - std::string Path() const {return path;} //tolua_export - void SetPath(const std::string & newPath) {Path( newPath);} //tolua_export - - // Reads ini file specified using path. - // Returns true if successful, false otherwise. - bool ReadFile(); //tolua_export - - // Writes data stored in class to ini file. - bool WriteFile(); //tolua_export - - // Deletes all stored ini data. - void Erase(); //tolua_export - void Clear() {Erase();} //tolua_export - void Reset() {Erase();} //tolua_export - - // Returns index of specified key, or noID if not found. - long FindKey( const std::string & keyname) const; //tolua_export - - // Returns index of specified value, in the specified key, or noID if not found. - long FindValue( const unsigned keyID, const std::string & valuename) const; //tolua_export - - // Returns number of keys currently in the ini. - unsigned NumKeys() const {return names.size();} //tolua_export - unsigned GetNumKeys() const {return NumKeys();} //tolua_export - - // Add a key name. - unsigned AddKeyName( const std::string & keyname); //tolua_export - - // Returns key names by index. - std::string KeyName( const unsigned keyID) const; //tolua_export - std::string GetKeyName( const unsigned keyID) const {return KeyName(keyID);} //tolua_export - - // Returns number of values stored for specified key. - unsigned NumValues( const std::string & keyname); //tolua_export - unsigned GetNumValues( const std::string & keyname) {return NumValues( keyname);} //tolua_export - unsigned NumValues( const unsigned keyID); //tolua_export - unsigned GetNumValues( const unsigned keyID) {return NumValues( keyID);} //tolua_export - - // Returns value name by index for a given keyname or keyID. - std::string ValueName( const std::string & keyname, const unsigned valueID) const; //tolua_export - std::string GetValueName( const std::string & keyname, const unsigned valueID) const { //tolua_export - return ValueName( keyname, valueID); - } //tolua_export - std::string ValueName( const unsigned keyID, const unsigned valueID) const; //tolua_export - std::string GetValueName( const unsigned keyID, const unsigned valueID) const { //tolua_export - return ValueName( keyID, valueID); - } //tolua_export - - // Gets value of [keyname] valuename =. - // Overloaded to return string, int, and double. - // Returns defValue if key/value not found. - AString GetValue (const AString & keyname, const AString & valuename, const AString & defValue = "") const; // tolua_export - AString GetValue (const unsigned keyID, const unsigned valueID, const AString & defValue = "") const; // tolua_export - double GetValueF(const AString & keyname, const AString & valuename, const double defValue = 0) const; // tolua_export - int GetValueI(const AString & keyname, const AString & valuename, const int defValue = 0) const; // tolua_export - bool GetValueB(const AString & keyname, const AString & valuename, const bool defValue = false) const { // tolua_export - return ( GetValueI( keyname, valuename, int( defValue)) > 0); - } // tolua_export - - // Gets the value; if not found, write the default to the INI file - AString GetValueSet (const AString & keyname, const AString & valuename, const AString & defValue = ""); // tolua_export - double GetValueSetF(const AString & keyname, const AString & valuename, const double defValue = 0.0); // tolua_export - int GetValueSetI(const AString & keyname, const AString & valuename, const int defValue = 0); // tolua_export - bool GetValueSetB(const AString & keyname, const AString & valuename, const bool defValue = false) { // tolua_export - return (GetValueSetI(keyname, valuename, defValue ? 1 : 0) > 0); - } // tolua_export - - // Sets value of [keyname] valuename =. - // Specify the optional paramter as false (0) if you do not want it to create - // the key if it doesn't exist. Returns true if data entered, false otherwise. - // Overloaded to accept string, int, and double. - bool SetValue( const unsigned keyID, const unsigned valueID, const std::string & value); //tolua_export - bool SetValue( const std::string & keyname, const std::string & valuename, const std::string & value, const bool create = true); //tolua_export - bool SetValueI( const std::string & keyname, const std::string & valuename, const int value, const bool create = true); //tolua_export - bool SetValueB( const std::string & keyname, const std::string & valuename, const bool value, const bool create = true) { //tolua_export - return SetValueI( keyname, valuename, int(value), create); - } //tolua_export - bool SetValueF( const std::string & keyname, const std::string & valuename, const double value, const bool create = true); //tolua_export - bool SetValueV( const std::string & keyname, const std::string & valuename, char *format, ...); - - // Deletes specified value. - // Returns true if value existed and deleted, false otherwise. - bool DeleteValueByID( const unsigned keyID, const unsigned valueID ); //tolua_export - bool DeleteValue( const std::string & keyname, const std::string & valuename); //tolua_export - - // Deletes specified key and all values contained within. - // Returns true if key existed and deleted, false otherwise. - bool DeleteKey(const std::string & keyname); //tolua_export - - // Header comment functions. - // Header comments are those comments before the first key. - // - // Number of header comments. - unsigned NumHeaderComments() {return comments.size();} //tolua_export - // Add a header comment. - void HeaderComment( const std::string & comment); //tolua_export - // Return a header comment. - std::string HeaderComment( const unsigned commentID) const; //tolua_export - // Delete a header comment. - bool DeleteHeaderComment( unsigned commentID); //tolua_export - // Delete all header comments. - void DeleteHeaderComments() {comments.clear();} //tolua_export - - // Key comment functions. - // Key comments are those comments within a key. Any comments - // defined within value names will be added to this list. Therefore, - // these comments will be moved to the top of the key definition when - // the CIniFile::WriteFile() is called. - // - // Number of key comments. - unsigned NumKeyComments( const unsigned keyID) const; //tolua_export - unsigned NumKeyComments( const std::string & keyname) const; //tolua_export - // Add a key comment. - bool KeyComment( const unsigned keyID, const std::string & comment); //tolua_export - bool KeyComment( const std::string & keyname, const std::string & comment); //tolua_export - // Return a key comment. - std::string KeyComment( const unsigned keyID, const unsigned commentID) const; //tolua_export - std::string KeyComment( const std::string & keyname, const unsigned commentID) const; //tolua_export - // Delete a key comment. - bool DeleteKeyComment( const unsigned keyID, const unsigned commentID); //tolua_export - bool DeleteKeyComment( const std::string & keyname, const unsigned commentID); //tolua_export - // Delete all comments for a key. - bool DeleteKeyComments( const unsigned keyID); //tolua_export - bool DeleteKeyComments( const std::string & keyname); //tolua_export -}; //tolua_export - -#endif +// IniFile.cpp: Implementation of the CIniFile class. +// Written by: Adam Clauss +// Email: cabadam@tamu.edu +// You may use this class/code as you wish in your programs. Feel free to distribute it, and +// email suggested changes to me. +// +// Rewritten by: Shane Hill +// Date: 21/08/2001 +// Email: Shane.Hill@dsto.defence.gov.au +// Reason: Remove dependancy on MFC. Code should compile on any +// platform. Tested on Windows/Linux/Irix +////////////////////////////////////////////////////////////////////// + +/* +!! MODIFIED BY FAKETRUTH and madmaxoft!! +*/ + +#ifndef CIniFile_H +#define CIniFile_H + + + + + +#define MAX_KEYNAME 128 +#define MAX_VALUENAME 128 +#define MAX_VALUEDATA 2048 + + + + + +class cIniFile //tolua_export +{ //tolua_export +private: + bool caseInsensitive; + std::string path; + struct key { + std::vector names; + std::vector values; + std::vector comments; + }; + std::vector keys; + std::vector names; + std::vector comments; + std::string CheckCase( std::string s) const; + +public: + enum errors{ noID = -1}; //tolua_export + cIniFile( const std::string iniPath = ""); //tolua_export + virtual ~cIniFile() {} + + // Sets whether or not keynames and valuenames should be case sensitive. + // The default is case insensitive. + void CaseSensitive() {caseInsensitive = false;} //tolua_export + void CaseInsensitive() {caseInsensitive = true;} //tolua_export + + // Sets path of ini file to read and write from. + void Path(const std::string & newPath) {path = newPath;} //tolua_export + std::string Path() const {return path;} //tolua_export + void SetPath(const std::string & newPath) {Path( newPath);} //tolua_export + + // Reads ini file specified using path. + // Returns true if successful, false otherwise. + bool ReadFile(); //tolua_export + + // Writes data stored in class to ini file. + bool WriteFile(); //tolua_export + + // Deletes all stored ini data. + void Erase(); //tolua_export + void Clear() {Erase();} //tolua_export + void Reset() {Erase();} //tolua_export + + // Returns index of specified key, or noID if not found. + long FindKey( const std::string & keyname) const; //tolua_export + + // Returns index of specified value, in the specified key, or noID if not found. + long FindValue( const unsigned keyID, const std::string & valuename) const; //tolua_export + + // Returns number of keys currently in the ini. + unsigned NumKeys() const {return names.size();} //tolua_export + unsigned GetNumKeys() const {return NumKeys();} //tolua_export + + // Add a key name. + unsigned AddKeyName( const std::string & keyname); //tolua_export + + // Returns key names by index. + std::string KeyName( const unsigned keyID) const; //tolua_export + std::string GetKeyName( const unsigned keyID) const {return KeyName(keyID);} //tolua_export + + // Returns number of values stored for specified key. + unsigned NumValues( const std::string & keyname); //tolua_export + unsigned GetNumValues( const std::string & keyname) {return NumValues( keyname);} //tolua_export + unsigned NumValues( const unsigned keyID); //tolua_export + unsigned GetNumValues( const unsigned keyID) {return NumValues( keyID);} //tolua_export + + // Returns value name by index for a given keyname or keyID. + std::string ValueName( const std::string & keyname, const unsigned valueID) const; //tolua_export + std::string GetValueName( const std::string & keyname, const unsigned valueID) const { //tolua_export + return ValueName( keyname, valueID); + } //tolua_export + std::string ValueName( const unsigned keyID, const unsigned valueID) const; //tolua_export + std::string GetValueName( const unsigned keyID, const unsigned valueID) const { //tolua_export + return ValueName( keyID, valueID); + } //tolua_export + + // Gets value of [keyname] valuename =. + // Overloaded to return string, int, and double. + // Returns defValue if key/value not found. + AString GetValue (const AString & keyname, const AString & valuename, const AString & defValue = "") const; // tolua_export + AString GetValue (const unsigned keyID, const unsigned valueID, const AString & defValue = "") const; // tolua_export + double GetValueF(const AString & keyname, const AString & valuename, const double defValue = 0) const; // tolua_export + int GetValueI(const AString & keyname, const AString & valuename, const int defValue = 0) const; // tolua_export + bool GetValueB(const AString & keyname, const AString & valuename, const bool defValue = false) const { // tolua_export + return ( GetValueI( keyname, valuename, int( defValue)) > 0); + } // tolua_export + + // Gets the value; if not found, write the default to the INI file + AString GetValueSet (const AString & keyname, const AString & valuename, const AString & defValue = ""); // tolua_export + double GetValueSetF(const AString & keyname, const AString & valuename, const double defValue = 0.0); // tolua_export + int GetValueSetI(const AString & keyname, const AString & valuename, const int defValue = 0); // tolua_export + bool GetValueSetB(const AString & keyname, const AString & valuename, const bool defValue = false) { // tolua_export + return (GetValueSetI(keyname, valuename, defValue ? 1 : 0) > 0); + } // tolua_export + + // Sets value of [keyname] valuename =. + // Specify the optional paramter as false (0) if you do not want it to create + // the key if it doesn't exist. Returns true if data entered, false otherwise. + // Overloaded to accept string, int, and double. + bool SetValue( const unsigned keyID, const unsigned valueID, const std::string & value); //tolua_export + bool SetValue( const std::string & keyname, const std::string & valuename, const std::string & value, const bool create = true); //tolua_export + bool SetValueI( const std::string & keyname, const std::string & valuename, const int value, const bool create = true); //tolua_export + bool SetValueB( const std::string & keyname, const std::string & valuename, const bool value, const bool create = true) { //tolua_export + return SetValueI( keyname, valuename, int(value), create); + } //tolua_export + bool SetValueF( const std::string & keyname, const std::string & valuename, const double value, const bool create = true); //tolua_export + bool SetValueV( const std::string & keyname, const std::string & valuename, char *format, ...); + + // Deletes specified value. + // Returns true if value existed and deleted, false otherwise. + bool DeleteValueByID( const unsigned keyID, const unsigned valueID ); //tolua_export + bool DeleteValue( const std::string & keyname, const std::string & valuename); //tolua_export + + // Deletes specified key and all values contained within. + // Returns true if key existed and deleted, false otherwise. + bool DeleteKey(const std::string & keyname); //tolua_export + + // Header comment functions. + // Header comments are those comments before the first key. + // + // Number of header comments. + unsigned NumHeaderComments() {return comments.size();} //tolua_export + // Add a header comment. + void HeaderComment( const std::string & comment); //tolua_export + // Return a header comment. + std::string HeaderComment( const unsigned commentID) const; //tolua_export + // Delete a header comment. + bool DeleteHeaderComment( unsigned commentID); //tolua_export + // Delete all header comments. + void DeleteHeaderComments() {comments.clear();} //tolua_export + + // Key comment functions. + // Key comments are those comments within a key. Any comments + // defined within value names will be added to this list. Therefore, + // these comments will be moved to the top of the key definition when + // the CIniFile::WriteFile() is called. + // + // Number of key comments. + unsigned NumKeyComments( const unsigned keyID) const; //tolua_export + unsigned NumKeyComments( const std::string & keyname) const; //tolua_export + // Add a key comment. + bool KeyComment( const unsigned keyID, const std::string & comment); //tolua_export + bool KeyComment( const std::string & keyname, const std::string & comment); //tolua_export + // Return a key comment. + std::string KeyComment( const unsigned keyID, const unsigned commentID) const; //tolua_export + std::string KeyComment( const std::string & keyname, const unsigned commentID) const; //tolua_export + // Delete a key comment. + bool DeleteKeyComment( const unsigned keyID, const unsigned commentID); //tolua_export + bool DeleteKeyComment( const std::string & keyname, const unsigned commentID); //tolua_export + // Delete all comments for a key. + bool DeleteKeyComments( const unsigned keyID); //tolua_export + bool DeleteKeyComments( const std::string & keyname); //tolua_export +}; //tolua_export + +#endif diff --git a/source/Bindings.cpp b/source/Bindings.cpp index a2e7950b4..040ca67a3 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,21337 +1,21337 @@ -/* -** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on Thu Jun 14 14:20:17 2012. -*/ - -#ifndef __cplusplus -#include "stdlib.h" -#endif -#include "string.h" - -#include "tolua++.h" - -/* Exported function */ -TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S); - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules -#include "tolua_base.h" -#include "cTorch.h" -#include "cStairs.h" -#include "cStep.h" -#include "cLadder.h" -#include "../iniFile/iniFile.h" -#include "BlockID.h" -#include "PacketID.h" -#include "Defines.h" -#include "LuaFunctions.h" -#include "cStringMap.h" -#include "cChatColor.h" -#include "cClientHandle.h" -#include "cEntity.h" -#include "cPawn.h" -#include "cPlayer.h" -#include "cPluginManager.h" -#include "cPlugin.h" -#include "cPlugin_NewLua.h" -#include "cPlugin_Lua.h" -#include "cServer.h" -#include "cWorld.h" -#include "cInventory.h" -#include "cItem.h" -#include "cWebAdmin.h" -#include "cWebPlugin.h" -#include "cWebPlugin_Lua.h" -#include "cPickup.h" -#include "cRoot.h" -#include "cTCPLink.h" -#include "Vector3f.h" -#include "Vector3d.h" -#include "Vector3i.h" -#include "Matrix4f.h" -#include "cCuboid.h" -#include "cMCLogger.h" -#include "cTracer.h" -#include "cGroup.h" -#include "packets/cPacket_Login.h" -#include "packets/cPacket_BlockDig.h" -#include "packets/cPacket_BlockPlace.h" -#include "cLuaChunk.h" -#include "CraftingRecipes.h" -#include "LuaItems.h" - -/* function to release collected object via destructor */ -#ifdef __cplusplus - -static int tolua_collect_cMCLogger (lua_State* tolua_S) -{ - cMCLogger* self = (cMCLogger*) tolua_tousertype(tolua_S,1,0); - Mtolua_delete(self); - return 0; -} - -static int tolua_collect_cItem (lua_State* tolua_S) -{ - cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); - Mtolua_delete(self); - return 0; -} - -static int tolua_collect_Vector3f (lua_State* tolua_S) -{ - Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); - Mtolua_delete(self); - return 0; -} - -static int tolua_collect_cIniFile (lua_State* tolua_S) -{ - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - Mtolua_delete(self); - return 0; -} - -static int tolua_collect_cPickup (lua_State* tolua_S) -{ - cPickup* self = (cPickup*) tolua_tousertype(tolua_S,1,0); - Mtolua_delete(self); - return 0; -} - -static int tolua_collect_cPacket_BlockDig (lua_State* tolua_S) -{ - cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); - Mtolua_delete(self); - return 0; -} - -static int tolua_collect_cTracer (lua_State* tolua_S) -{ - cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); - Mtolua_delete(self); - return 0; -} - -static int tolua_collect_cPlugin (lua_State* tolua_S) -{ - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - Mtolua_delete(self); - return 0; -} - -static int tolua_collect_cCraftingGrid (lua_State* tolua_S) -{ - cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0); - Mtolua_delete(self); - return 0; -} - -static int tolua_collect_cCuboid (lua_State* tolua_S) -{ - cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0); - Mtolua_delete(self); - return 0; -} - -static int tolua_collect_cWebPlugin (lua_State* tolua_S) -{ - cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0); - Mtolua_delete(self); - return 0; -} - -static int tolua_collect_Vector3i (lua_State* tolua_S) -{ - Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); - Mtolua_delete(self); - return 0; -} - -static int tolua_collect_cEntity (lua_State* tolua_S) -{ - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); - Mtolua_delete(self); - return 0; -} - -static int tolua_collect_cTCPLink (lua_State* tolua_S) -{ - cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0); - Mtolua_delete(self); - return 0; -} - -static int tolua_collect_Vector3d (lua_State* tolua_S) -{ - Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); - Mtolua_delete(self); - return 0; -} -#endif - - -/* function to register type */ -static void tolua_reg_types (lua_State* tolua_S) -{ - tolua_usertype(tolua_S,"BLOCKTYPE"); - tolua_usertype(tolua_S,"TakeDamageInfo"); - tolua_usertype(tolua_S,"cLuaItems"); - tolua_usertype(tolua_S,"cLuaChunk"); - tolua_usertype(tolua_S,"cCraftingGrid"); - tolua_usertype(tolua_S,"cCraftingRecipe"); - tolua_usertype(tolua_S,"cPlugin"); - tolua_usertype(tolua_S,"cEntity"); - tolua_usertype(tolua_S,"NIBBLETYPE"); - tolua_usertype(tolua_S,"Lua__cPacket_BlockDig"); - tolua_usertype(tolua_S,"cTCPLink"); - tolua_usertype(tolua_S,"Lua__cTCPLink"); - tolua_usertype(tolua_S,"Json::Value"); - tolua_usertype(tolua_S,"cServer"); - tolua_usertype(tolua_S,"cRoot"); - tolua_usertype(tolua_S,"cMCLogger"); - tolua_usertype(tolua_S,"cGroup"); - tolua_usertype(tolua_S,"cTracer"); - tolua_usertype(tolua_S,"cPlugin::CommandStruct"); - tolua_usertype(tolua_S,"cPickup"); - tolua_usertype(tolua_S,"cItems"); - tolua_usertype(tolua_S,"cPacket_Login"); - tolua_usertype(tolua_S,"cClientHandle"); - tolua_usertype(tolua_S,"cStep"); - tolua_usertype(tolua_S,"cFurnaceRecipe"); - tolua_usertype(tolua_S,"cCuboid"); - tolua_usertype(tolua_S,"cChatColor"); - tolua_usertype(tolua_S,"Vector3i"); - tolua_usertype(tolua_S,"cPacket_PickupSpawn"); - tolua_usertype(tolua_S,"Lua__cWebPlugin"); - tolua_usertype(tolua_S,"Lua__cPawn"); - tolua_usertype(tolua_S,"cStairs"); - tolua_usertype(tolua_S,"cItem"); - tolua_usertype(tolua_S,"Vector3f"); - tolua_usertype(tolua_S,"cPlugin_Lua"); - tolua_usertype(tolua_S,"cWebPlugin_Lua"); - tolua_usertype(tolua_S,"Lua__cPlugin_NewLua"); - tolua_usertype(tolua_S,"cPacket"); - tolua_usertype(tolua_S,"cPacket_BlockDig"); - tolua_usertype(tolua_S,"cWebAdmin"); - tolua_usertype(tolua_S,"cCraftingRecipes"); - tolua_usertype(tolua_S,"cBlockEntity"); - tolua_usertype(tolua_S,"cGroupManager"); - tolua_usertype(tolua_S,"Lua__cPickup"); - tolua_usertype(tolua_S,"Lua__cPlugin"); - tolua_usertype(tolua_S,"cWebPlugin"); - tolua_usertype(tolua_S,"cPacket_BlockPlace"); - tolua_usertype(tolua_S,"cLadder"); - tolua_usertype(tolua_S,"cPluginManager"); - tolua_usertype(tolua_S,"HTTPFormData"); - tolua_usertype(tolua_S,"cIniFile"); - tolua_usertype(tolua_S,"Lua__cPlayer"); - tolua_usertype(tolua_S,"HTTPRequest"); - tolua_usertype(tolua_S,"cPawn"); - tolua_usertype(tolua_S,"cPlayer"); - tolua_usertype(tolua_S,"cTorch"); - tolua_usertype(tolua_S,"cStringMap"); - tolua_usertype(tolua_S,"cInventory"); - tolua_usertype(tolua_S,"cWorld"); - tolua_usertype(tolua_S,"cPlugin_NewLua"); - tolua_usertype(tolua_S,"Lua__cEntity"); - tolua_usertype(tolua_S,"Vector3d"); -} - -/* method: DirectionToMetaData of class cTorch */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cTorch_DirectionToMetaData00 -static int tolua_AllToLua_cTorch_DirectionToMetaData00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cTorch",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - char a_Direction = ((char) tolua_tonumber(tolua_S,2,0)); - { - char tolua_ret = (char) cTorch::DirectionToMetaData(a_Direction); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'DirectionToMetaData'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: MetaDataToDirection of class cTorch */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cTorch_MetaDataToDirection00 -static int tolua_AllToLua_cTorch_MetaDataToDirection00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cTorch",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - char a_MetaData = ((char) tolua_tonumber(tolua_S,2,0)); - { - char tolua_ret = (char) cTorch::MetaDataToDirection(a_MetaData); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'MetaDataToDirection'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: RotationToMetaData of class cStairs */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cStairs_RotationToMetaData00 -static int tolua_AllToLua_cStairs_RotationToMetaData00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cStairs",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - float a_Rotation = ((float) tolua_tonumber(tolua_S,2,0)); - int a_Direction = ((int) tolua_tonumber(tolua_S,3,0)); - { - char tolua_ret = (char) cStairs::RotationToMetaData(a_Rotation,a_Direction); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'RotationToMetaData'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: DirectionToMetaData of class cStep */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cStep_DirectionToMetaData00 -static int tolua_AllToLua_cStep_DirectionToMetaData00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cStep",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - int a_Direction = ((int) tolua_tonumber(tolua_S,2,0)); - { - char tolua_ret = (char) cStep::DirectionToMetaData(a_Direction); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'DirectionToMetaData'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: DirectionToMetaData of class cLadder */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLadder_DirectionToMetaData00 -static int tolua_AllToLua_cLadder_DirectionToMetaData00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cLadder",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - char a_Direction = ((char) tolua_tonumber(tolua_S,2,0)); - { - char tolua_ret = (char) cLadder::DirectionToMetaData(a_Direction); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'DirectionToMetaData'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: MetaDataToDirection of class cLadder */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLadder_MetaDataToDirection00 -static int tolua_AllToLua_cLadder_MetaDataToDirection00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cLadder",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - char a_MetaData = ((char) tolua_tonumber(tolua_S,2,0)); - { - char tolua_ret = (char) cLadder::MetaDataToDirection(a_MetaData); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'MetaDataToDirection'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_new00 -static int tolua_AllToLua_cIniFile_new00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,1,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const std::string iniPath = ((const std::string) tolua_tocppstring(tolua_S,2,"")); - { - cIniFile* tolua_ret = (cIniFile*) Mtolua_new((cIniFile)(iniPath)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cIniFile"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_new00_local -static int tolua_AllToLua_cIniFile_new00_local(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,1,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const std::string iniPath = ((const std::string) tolua_tocppstring(tolua_S,2,"")); - { - cIniFile* tolua_ret = (cIniFile*) Mtolua_new((cIniFile)(iniPath)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cIniFile"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: CaseSensitive of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_CaseSensitive00 -static int tolua_AllToLua_cIniFile_CaseSensitive00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CaseSensitive'", NULL); -#endif - { - self->CaseSensitive(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'CaseSensitive'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: CaseInsensitive of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_CaseInsensitive00 -static int tolua_AllToLua_cIniFile_CaseInsensitive00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CaseInsensitive'", NULL); -#endif - { - self->CaseInsensitive(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'CaseInsensitive'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Path of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Path00 -static int tolua_AllToLua_cIniFile_Path00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const std::string newPath = ((const std::string) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Path'", NULL); -#endif - { - self->Path(newPath); - tolua_pushcppstring(tolua_S,(const char*)newPath); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Path'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Path of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Path01 -static int tolua_AllToLua_cIniFile_Path01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Path'", NULL); -#endif - { - std::string tolua_ret = (std::string) self->Path(); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_cIniFile_Path00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetPath of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetPath00 -static int tolua_AllToLua_cIniFile_SetPath00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const std::string newPath = ((const std::string) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPath'", NULL); -#endif - { - self->SetPath(newPath); - tolua_pushcppstring(tolua_S,(const char*)newPath); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetPath'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: ReadFile of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_ReadFile00 -static int tolua_AllToLua_cIniFile_ReadFile00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ReadFile'", NULL); -#endif - { - bool tolua_ret = (bool) self->ReadFile(); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'ReadFile'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: WriteFile of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_WriteFile00 -static int tolua_AllToLua_cIniFile_WriteFile00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'WriteFile'", NULL); -#endif - { - bool tolua_ret = (bool) self->WriteFile(); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'WriteFile'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Erase of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Erase00 -static int tolua_AllToLua_cIniFile_Erase00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Erase'", NULL); -#endif - { - self->Erase(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Erase'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Clear of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Clear00 -static int tolua_AllToLua_cIniFile_Clear00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL); -#endif - { - self->Clear(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Reset of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Reset00 -static int tolua_AllToLua_cIniFile_Reset00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Reset'", NULL); -#endif - { - self->Reset(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Reset'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: FindKey of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_FindKey00 -static int tolua_AllToLua_cIniFile_FindKey00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); - const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'FindKey'", NULL); -#endif - { - long tolua_ret = (long) self->FindKey(keyname); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - } - } - return 2; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'FindKey'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: FindValue of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_FindValue00 -static int tolua_AllToLua_cIniFile_FindValue00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_iscppstring(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); - const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); - const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'FindValue'", NULL); -#endif - { - long tolua_ret = (long) self->FindValue(keyID,valuename); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)valuename); - } - } - return 2; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'FindValue'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: NumKeys of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumKeys00 -static int tolua_AllToLua_cIniFile_NumKeys00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumKeys'", NULL); -#endif - { - unsigned tolua_ret = (unsigned) self->NumKeys(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'NumKeys'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetNumKeys of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetNumKeys00 -static int tolua_AllToLua_cIniFile_GetNumKeys00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumKeys'", NULL); -#endif - { - unsigned tolua_ret = (unsigned) self->GetNumKeys(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetNumKeys'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: AddKeyName of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_AddKeyName00 -static int tolua_AllToLua_cIniFile_AddKeyName00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddKeyName'", NULL); -#endif - { - unsigned tolua_ret = (unsigned) self->AddKeyName(keyname); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - } - } - return 2; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'AddKeyName'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: KeyName of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_KeyName00 -static int tolua_AllToLua_cIniFile_KeyName00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); - const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KeyName'", NULL); -#endif - { - std::string tolua_ret = (std::string) self->KeyName(keyID); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'KeyName'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetKeyName of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetKeyName00 -static int tolua_AllToLua_cIniFile_GetKeyName00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); - const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetKeyName'", NULL); -#endif - { - std::string tolua_ret = (std::string) self->GetKeyName(keyID); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetKeyName'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: NumValues of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumValues00 -static int tolua_AllToLua_cIniFile_NumValues00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumValues'", NULL); -#endif - { - unsigned tolua_ret = (unsigned) self->NumValues(keyname); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - } - } - return 2; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'NumValues'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetNumValues of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetNumValues00 -static int tolua_AllToLua_cIniFile_GetNumValues00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumValues'", NULL); -#endif - { - unsigned tolua_ret = (unsigned) self->GetNumValues(keyname); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - } - } - return 2; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetNumValues'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: NumValues of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumValues01 -static int tolua_AllToLua_cIniFile_NumValues01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumValues'", NULL); -#endif - { - unsigned tolua_ret = (unsigned) self->NumValues(keyID); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_cIniFile_NumValues00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetNumValues of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetNumValues01 -static int tolua_AllToLua_cIniFile_GetNumValues01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumValues'", NULL); -#endif - { - unsigned tolua_ret = (unsigned) self->GetNumValues(keyID); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_cIniFile_GetNumValues00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: ValueName of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_ValueName00 -static int tolua_AllToLua_cIniFile_ValueName00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); - const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); - const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ValueName'", NULL); -#endif - { - std::string tolua_ret = (std::string) self->ValueName(keyname,valueID); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - } - } - return 2; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'ValueName'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetValueName of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueName00 -static int tolua_AllToLua_cIniFile_GetValueName00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); - const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); - const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueName'", NULL); -#endif - { - std::string tolua_ret = (std::string) self->GetValueName(keyname,valueID); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - } - } - return 2; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetValueName'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: ValueName of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_ValueName01 -static int tolua_AllToLua_cIniFile_ValueName01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); - const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); - const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ValueName'", NULL); -#endif - { - std::string tolua_ret = (std::string) self->ValueName(keyID,valueID); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_cIniFile_ValueName00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetValueName of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueName01 -static int tolua_AllToLua_cIniFile_GetValueName01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); - const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); - const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueName'", NULL); -#endif - { - std::string tolua_ret = (std::string) self->GetValueName(keyID,valueID); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_cIniFile_GetValueName00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetValue of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValue00 -static int tolua_AllToLua_cIniFile_GetValue00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_iscppstring(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); - const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); - const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValue'", NULL); -#endif - { - AString tolua_ret = (AString) self->GetValue(keyname,valuename); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - tolua_pushcppstring(tolua_S,(const char*)valuename); - } - } - return 3; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetValue'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetValue of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValue01 -static int tolua_AllToLua_cIniFile_GetValue01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_iscppstring(tolua_S,3,0,&tolua_err) || - !tolua_iscppstring(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); - const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); - const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); - const AString defValue = ((const AString) tolua_tocppstring(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValue'", NULL); -#endif - { - AString tolua_ret = (AString) self->GetValue(keyname,valuename,defValue); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - tolua_pushcppstring(tolua_S,(const char*)valuename); - tolua_pushcppstring(tolua_S,(const char*)defValue); - } - } - return 4; -tolua_lerror: - return tolua_AllToLua_cIniFile_GetValue00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetValue of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValue02 -static int tolua_AllToLua_cIniFile_GetValue02(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); - const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); - const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValue'", NULL); -#endif - { - AString tolua_ret = (AString) self->GetValue(keyID,valueID); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_cIniFile_GetValue01(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetValue of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValue03 -static int tolua_AllToLua_cIniFile_GetValue03(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_iscppstring(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); - const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); - const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); - const AString defValue = ((const AString) tolua_tocppstring(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValue'", NULL); -#endif - { - AString tolua_ret = (AString) self->GetValue(keyID,valueID,defValue); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)defValue); - } - } - return 2; -tolua_lerror: - return tolua_AllToLua_cIniFile_GetValue02(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetValueF of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueF00 -static int tolua_AllToLua_cIniFile_GetValueF00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_iscppstring(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,1,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); - const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); - const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); - const double defValue = ((const double) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueF'", NULL); -#endif - { - double tolua_ret = (double) self->GetValueF(keyname,valuename,defValue); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - tolua_pushcppstring(tolua_S,(const char*)valuename); - } - } - return 3; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetValueF'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetValueI of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueI00 -static int tolua_AllToLua_cIniFile_GetValueI00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_iscppstring(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,1,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); - const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); - const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); - const int defValue = ((const int) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueI'", NULL); -#endif - { - int tolua_ret = (int) self->GetValueI(keyname,valuename,defValue); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - tolua_pushcppstring(tolua_S,(const char*)valuename); - } - } - return 3; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetValueI'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetValueB of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueB00 -static int tolua_AllToLua_cIniFile_GetValueB00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_iscppstring(tolua_S,3,0,&tolua_err) || - !tolua_isboolean(tolua_S,4,1,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); - const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); - const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); - const bool defValue = ((const bool) tolua_toboolean(tolua_S,4,false)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueB'", NULL); -#endif - { - bool tolua_ret = (bool) self->GetValueB(keyname,valuename,defValue); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - tolua_pushcppstring(tolua_S,(const char*)valuename); - } - } - return 3; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetValueB'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetValueSet of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueSet00 -static int tolua_AllToLua_cIniFile_GetValueSet00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_iscppstring(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); - const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueSet'", NULL); -#endif - { - AString tolua_ret = (AString) self->GetValueSet(keyname,valuename); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - tolua_pushcppstring(tolua_S,(const char*)valuename); - } - } - return 3; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetValueSet'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetValueSet of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueSet01 -static int tolua_AllToLua_cIniFile_GetValueSet01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_iscppstring(tolua_S,3,0,&tolua_err) || - !tolua_iscppstring(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); - const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); - const AString defValue = ((const AString) tolua_tocppstring(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueSet'", NULL); -#endif - { - AString tolua_ret = (AString) self->GetValueSet(keyname,valuename,defValue); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - tolua_pushcppstring(tolua_S,(const char*)valuename); - tolua_pushcppstring(tolua_S,(const char*)defValue); - } - } - return 4; -tolua_lerror: - return tolua_AllToLua_cIniFile_GetValueSet00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetValueSetF of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueSetF00 -static int tolua_AllToLua_cIniFile_GetValueSetF00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_iscppstring(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,1,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); - const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); - const double defValue = ((const double) tolua_tonumber(tolua_S,4,0.0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueSetF'", NULL); -#endif - { - double tolua_ret = (double) self->GetValueSetF(keyname,valuename,defValue); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - tolua_pushcppstring(tolua_S,(const char*)valuename); - } - } - return 3; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetValueSetF'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetValueSetI of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueSetI00 -static int tolua_AllToLua_cIniFile_GetValueSetI00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_iscppstring(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,1,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); - const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); - const int defValue = ((const int) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueSetI'", NULL); -#endif - { - int tolua_ret = (int) self->GetValueSetI(keyname,valuename,defValue); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - tolua_pushcppstring(tolua_S,(const char*)valuename); - } - } - return 3; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetValueSetI'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetValueSetB of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueSetB00 -static int tolua_AllToLua_cIniFile_GetValueSetB00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_iscppstring(tolua_S,3,0,&tolua_err) || - !tolua_isboolean(tolua_S,4,1,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); - const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); - const bool defValue = ((const bool) tolua_toboolean(tolua_S,4,false)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueSetB'", NULL); -#endif - { - bool tolua_ret = (bool) self->GetValueSetB(keyname,valuename,defValue); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - tolua_pushcppstring(tolua_S,(const char*)valuename); - } - } - return 3; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetValueSetB'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetValue of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetValue00 -static int tolua_AllToLua_cIniFile_SetValue00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_iscppstring(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); - const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); - const std::string value = ((const std::string) tolua_tocppstring(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValue'", NULL); -#endif - { - bool tolua_ret = (bool) self->SetValue(keyID,valueID,value); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)value); - } - } - return 2; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetValue'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetValue of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetValue01 -static int tolua_AllToLua_cIniFile_SetValue01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_iscppstring(tolua_S,3,0,&tolua_err) || - !tolua_iscppstring(tolua_S,4,0,&tolua_err) || - !tolua_isboolean(tolua_S,5,1,&tolua_err) || - !tolua_isnoobj(tolua_S,6,&tolua_err) - ) - goto tolua_lerror; - else - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); - const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0)); - const std::string value = ((const std::string) tolua_tocppstring(tolua_S,4,0)); - const bool create = ((const bool) tolua_toboolean(tolua_S,5,true)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValue'", NULL); -#endif - { - bool tolua_ret = (bool) self->SetValue(keyname,valuename,value,create); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - tolua_pushcppstring(tolua_S,(const char*)valuename); - tolua_pushcppstring(tolua_S,(const char*)value); - } - } - return 4; -tolua_lerror: - return tolua_AllToLua_cIniFile_SetValue00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetValueI of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetValueI00 -static int tolua_AllToLua_cIniFile_SetValueI00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_iscppstring(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isboolean(tolua_S,5,1,&tolua_err) || - !tolua_isnoobj(tolua_S,6,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); - const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0)); - const int value = ((const int) tolua_tonumber(tolua_S,4,0)); - const bool create = ((const bool) tolua_toboolean(tolua_S,5,true)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValueI'", NULL); -#endif - { - bool tolua_ret = (bool) self->SetValueI(keyname,valuename,value,create); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - tolua_pushcppstring(tolua_S,(const char*)valuename); - } - } - return 3; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetValueI'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetValueB of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetValueB00 -static int tolua_AllToLua_cIniFile_SetValueB00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_iscppstring(tolua_S,3,0,&tolua_err) || - !tolua_isboolean(tolua_S,4,0,&tolua_err) || - !tolua_isboolean(tolua_S,5,1,&tolua_err) || - !tolua_isnoobj(tolua_S,6,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); - const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0)); - const bool value = ((const bool) tolua_toboolean(tolua_S,4,0)); - const bool create = ((const bool) tolua_toboolean(tolua_S,5,true)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValueB'", NULL); -#endif - { - bool tolua_ret = (bool) self->SetValueB(keyname,valuename,value,create); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - tolua_pushcppstring(tolua_S,(const char*)valuename); - } - } - return 3; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetValueB'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetValueF of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetValueF00 -static int tolua_AllToLua_cIniFile_SetValueF00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_iscppstring(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isboolean(tolua_S,5,1,&tolua_err) || - !tolua_isnoobj(tolua_S,6,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); - const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0)); - const double value = ((const double) tolua_tonumber(tolua_S,4,0)); - const bool create = ((const bool) tolua_toboolean(tolua_S,5,true)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValueF'", NULL); -#endif - { - bool tolua_ret = (bool) self->SetValueF(keyname,valuename,value,create); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - tolua_pushcppstring(tolua_S,(const char*)valuename); - } - } - return 3; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetValueF'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: DeleteValueByID of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteValueByID00 -static int tolua_AllToLua_cIniFile_DeleteValueByID00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); - const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteValueByID'", NULL); -#endif - { - bool tolua_ret = (bool) self->DeleteValueByID(keyID,valueID); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'DeleteValueByID'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: DeleteValue of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteValue00 -static int tolua_AllToLua_cIniFile_DeleteValue00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_iscppstring(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); - const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteValue'", NULL); -#endif - { - bool tolua_ret = (bool) self->DeleteValue(keyname,valuename); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - tolua_pushcppstring(tolua_S,(const char*)valuename); - } - } - return 3; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'DeleteValue'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: DeleteKey of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteKey00 -static int tolua_AllToLua_cIniFile_DeleteKey00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteKey'", NULL); -#endif - { - bool tolua_ret = (bool) self->DeleteKey(keyname); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - } - } - return 2; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'DeleteKey'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: NumHeaderComments of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumHeaderComments00 -static int tolua_AllToLua_cIniFile_NumHeaderComments00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumHeaderComments'", NULL); -#endif - { - unsigned tolua_ret = (unsigned) self->NumHeaderComments(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'NumHeaderComments'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: HeaderComment of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_HeaderComment00 -static int tolua_AllToLua_cIniFile_HeaderComment00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const std::string comment = ((const std::string) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HeaderComment'", NULL); -#endif - { - self->HeaderComment(comment); - tolua_pushcppstring(tolua_S,(const char*)comment); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'HeaderComment'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: HeaderComment of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_HeaderComment01 -static int tolua_AllToLua_cIniFile_HeaderComment01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); - const unsigned commentID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HeaderComment'", NULL); -#endif - { - std::string tolua_ret = (std::string) self->HeaderComment(commentID); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_cIniFile_HeaderComment00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: DeleteHeaderComment of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteHeaderComment00 -static int tolua_AllToLua_cIniFile_DeleteHeaderComment00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - unsigned commentID = ((unsigned) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteHeaderComment'", NULL); -#endif - { - bool tolua_ret = (bool) self->DeleteHeaderComment(commentID); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'DeleteHeaderComment'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: DeleteHeaderComments of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteHeaderComments00 -static int tolua_AllToLua_cIniFile_DeleteHeaderComments00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteHeaderComments'", NULL); -#endif - { - self->DeleteHeaderComments(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'DeleteHeaderComments'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: NumKeyComments of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumKeyComments00 -static int tolua_AllToLua_cIniFile_NumKeyComments00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); - const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumKeyComments'", NULL); -#endif - { - unsigned tolua_ret = (unsigned) self->NumKeyComments(keyID); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'NumKeyComments'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: NumKeyComments of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumKeyComments01 -static int tolua_AllToLua_cIniFile_NumKeyComments01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); - const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumKeyComments'", NULL); -#endif - { - unsigned tolua_ret = (unsigned) self->NumKeyComments(keyname); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - } - } - return 2; -tolua_lerror: - return tolua_AllToLua_cIniFile_NumKeyComments00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: KeyComment of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_KeyComment00 -static int tolua_AllToLua_cIniFile_KeyComment00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_iscppstring(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); - const std::string comment = ((const std::string) tolua_tocppstring(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KeyComment'", NULL); -#endif - { - bool tolua_ret = (bool) self->KeyComment(keyID,comment); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)comment); - } - } - return 2; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'KeyComment'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: KeyComment of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_KeyComment01 -static int tolua_AllToLua_cIniFile_KeyComment01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_iscppstring(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); - const std::string comment = ((const std::string) tolua_tocppstring(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KeyComment'", NULL); -#endif - { - bool tolua_ret = (bool) self->KeyComment(keyname,comment); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - tolua_pushcppstring(tolua_S,(const char*)comment); - } - } - return 3; -tolua_lerror: - return tolua_AllToLua_cIniFile_KeyComment00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: KeyComment of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_KeyComment02 -static int tolua_AllToLua_cIniFile_KeyComment02(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); - const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); - const unsigned commentID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KeyComment'", NULL); -#endif - { - std::string tolua_ret = (std::string) self->KeyComment(keyID,commentID); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_cIniFile_KeyComment01(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: KeyComment of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_KeyComment03 -static int tolua_AllToLua_cIniFile_KeyComment03(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else - { - const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); - const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); - const unsigned commentID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KeyComment'", NULL); -#endif - { - std::string tolua_ret = (std::string) self->KeyComment(keyname,commentID); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - } - } - return 2; -tolua_lerror: - return tolua_AllToLua_cIniFile_KeyComment02(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: DeleteKeyComment of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteKeyComment00 -static int tolua_AllToLua_cIniFile_DeleteKeyComment00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); - const unsigned commentID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteKeyComment'", NULL); -#endif - { - bool tolua_ret = (bool) self->DeleteKeyComment(keyID,commentID); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'DeleteKeyComment'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: DeleteKeyComment of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteKeyComment01 -static int tolua_AllToLua_cIniFile_DeleteKeyComment01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); - const unsigned commentID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteKeyComment'", NULL); -#endif - { - bool tolua_ret = (bool) self->DeleteKeyComment(keyname,commentID); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - } - } - return 2; -tolua_lerror: - return tolua_AllToLua_cIniFile_DeleteKeyComment00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: DeleteKeyComments of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteKeyComments00 -static int tolua_AllToLua_cIniFile_DeleteKeyComments00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteKeyComments'", NULL); -#endif - { - bool tolua_ret = (bool) self->DeleteKeyComments(keyID); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'DeleteKeyComments'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: DeleteKeyComments of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteKeyComments01 -static int tolua_AllToLua_cIniFile_DeleteKeyComments01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); - const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteKeyComments'", NULL); -#endif - { - bool tolua_ret = (bool) self->DeleteKeyComments(keyname); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)keyname); - } - } - return 2; -tolua_lerror: - return tolua_AllToLua_cIniFile_DeleteKeyComments00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* function: BlockStringToType */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_BlockStringToType00 -static int tolua_AllToLua_BlockStringToType00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_iscppstring(tolua_S,1,0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const AString a_BlockTypeString = ((const AString) tolua_tocppstring(tolua_S,1,0)); - { - int tolua_ret = (int) BlockStringToType(a_BlockTypeString); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)a_BlockTypeString); - } - } - return 2; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'BlockStringToType'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* function: StringToItem */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_StringToItem00 -static int tolua_AllToLua_StringToItem00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_iscppstring(tolua_S,1,0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const AString a_ItemTypeString = ((const AString) tolua_tocppstring(tolua_S,1,0)); - cItem* a_Item = ((cItem*) tolua_tousertype(tolua_S,2,0)); - { - bool tolua_ret = (bool) StringToItem(a_ItemTypeString,*a_Item); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)a_ItemTypeString); - } - } - return 2; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'StringToItem'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: g_BlockLightValue */ -#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockLightValue -static int tolua_get_AllToLua_g_BlockLightValue(lua_State* tolua_S) -{ - int tolua_index; -#ifndef TOLUA_RELEASE - { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); - } -#endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); -#ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)g_BlockLightValue[tolua_index]); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: g_BlockLightValue */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockLightValue -static int tolua_set_AllToLua_g_BlockLightValue(lua_State* tolua_S) -{ - int tolua_index; -#ifndef TOLUA_RELEASE - { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); - } -#endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); -#ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); -#endif - g_BlockLightValue[tolua_index] = ((unsigned char) tolua_tonumber(tolua_S,3,0)); - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: g_BlockSpreadLightFalloff */ -#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockSpreadLightFalloff -static int tolua_get_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) -{ - int tolua_index; -#ifndef TOLUA_RELEASE - { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); - } -#endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); -#ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)g_BlockSpreadLightFalloff[tolua_index]); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: g_BlockSpreadLightFalloff */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockSpreadLightFalloff -static int tolua_set_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) -{ - int tolua_index; -#ifndef TOLUA_RELEASE - { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); - } -#endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); -#ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); -#endif - g_BlockSpreadLightFalloff[tolua_index] = ((unsigned char) tolua_tonumber(tolua_S,3,0)); - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: g_BlockTransparent */ -#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockTransparent -static int tolua_get_AllToLua_g_BlockTransparent(lua_State* tolua_S) -{ - int tolua_index; -#ifndef TOLUA_RELEASE - { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); - } -#endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); -#ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); -#endif - tolua_pushboolean(tolua_S,(bool)g_BlockTransparent[tolua_index]); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: g_BlockTransparent */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockTransparent -static int tolua_set_AllToLua_g_BlockTransparent(lua_State* tolua_S) -{ - int tolua_index; -#ifndef TOLUA_RELEASE - { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); - } -#endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); -#ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); -#endif - g_BlockTransparent[tolua_index] = ((bool) tolua_toboolean(tolua_S,3,0)); - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: g_BlockOneHitDig */ -#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockOneHitDig -static int tolua_get_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) -{ - int tolua_index; -#ifndef TOLUA_RELEASE - { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); - } -#endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); -#ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); -#endif - tolua_pushboolean(tolua_S,(bool)g_BlockOneHitDig[tolua_index]); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: g_BlockOneHitDig */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockOneHitDig -static int tolua_set_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) -{ - int tolua_index; -#ifndef TOLUA_RELEASE - { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); - } -#endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); -#ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); -#endif - g_BlockOneHitDig[tolua_index] = ((bool) tolua_toboolean(tolua_S,3,0)); - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* function: IsValidBlock */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_IsValidBlock00 -static int tolua_AllToLua_IsValidBlock00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isnumber(tolua_S,1,0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - int a_BlockID = ((int) tolua_tonumber(tolua_S,1,0)); - { - bool tolua_ret = (bool) IsValidBlock(a_BlockID); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'IsValidBlock'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* function: IsValidItem */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_IsValidItem00 -static int tolua_AllToLua_IsValidItem00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isnumber(tolua_S,1,0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - int a_ItemID = ((int) tolua_tonumber(tolua_S,1,0)); - { - bool tolua_ret = (bool) IsValidItem(a_ItemID); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'IsValidItem'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* function: AddDirection */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_AddDirection00 -static int tolua_AllToLua_AddDirection00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isnumber(tolua_S,1,0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isboolean(tolua_S,5,1,&tolua_err) || - !tolua_isnoobj(tolua_S,6,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - int a_X = ((int) tolua_tonumber(tolua_S,1,0)); - unsigned char a_Y = ((unsigned char) tolua_tonumber(tolua_S,2,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,3,0)); - char a_Direction = ((char) tolua_tonumber(tolua_S,4,0)); - bool a_bInverse = ((bool) tolua_toboolean(tolua_S,5,false)); - { - AddDirection(a_X,a_Y,a_Z,a_Direction,a_bInverse); - tolua_pushnumber(tolua_S,(lua_Number)a_X); - tolua_pushnumber(tolua_S,(lua_Number)a_Y); - tolua_pushnumber(tolua_S,(lua_Number)a_Z); - } - } - return 3; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'AddDirection'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* function: ItemCategory::IsPickaxe */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsPickaxe00 -static int tolua_AllToLua_ItemCategory_IsPickaxe00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isnumber(tolua_S,1,0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0)); - { - bool tolua_ret = (bool) ItemCategory::IsPickaxe(a_ItemID); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'IsPickaxe'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* function: ItemCategory::IsAxe */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsAxe00 -static int tolua_AllToLua_ItemCategory_IsAxe00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isnumber(tolua_S,1,0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0)); - { - bool tolua_ret = (bool) ItemCategory::IsAxe(a_ItemID); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'IsAxe'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* function: ItemCategory::IsSword */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsSword00 -static int tolua_AllToLua_ItemCategory_IsSword00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isnumber(tolua_S,1,0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0)); - { - bool tolua_ret = (bool) ItemCategory::IsSword(a_ItemID); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'IsSword'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* function: ItemCategory::IsHoe */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsHoe00 -static int tolua_AllToLua_ItemCategory_IsHoe00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isnumber(tolua_S,1,0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0)); - { - bool tolua_ret = (bool) ItemCategory::IsHoe(a_ItemID); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'IsHoe'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* function: ItemCategory::IsShovel */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsShovel00 -static int tolua_AllToLua_ItemCategory_IsShovel00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isnumber(tolua_S,1,0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0)); - { - bool tolua_ret = (bool) ItemCategory::IsShovel(a_ItemID); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'IsShovel'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* function: ItemCategory::IsTool */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsTool00 -static int tolua_AllToLua_ItemCategory_IsTool00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isnumber(tolua_S,1,0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0)); - { - bool tolua_ret = (bool) ItemCategory::IsTool(a_ItemID); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'IsTool'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* function: GetTime */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_GetTime00 -static int tolua_AllToLua_GetTime00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isnoobj(tolua_S,1,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - { - unsigned int tolua_ret = (unsigned int) GetTime(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetTime'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* function: GetChar */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_GetChar00 -static int tolua_AllToLua_GetChar00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_iscppstring(tolua_S,1,0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - std::string a_Str = ((std::string) tolua_tocppstring(tolua_S,1,0)); - unsigned int a_Idx = ((unsigned int) tolua_tonumber(tolua_S,2,0)); - { - std::string tolua_ret = (std::string) GetChar(a_Str,a_Idx); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)a_Str); - } - } - return 2; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetChar'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: clear of class cStringMap */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cStringMap_clear00 -static int tolua_AllToLua_cStringMap_clear00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cStringMap",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cStringMap* self = (cStringMap*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'clear'", NULL); -#endif - { - self->clear(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'clear'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: size of class cStringMap */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cStringMap_size00 -static int tolua_AllToLua_cStringMap_size00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cStringMap",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cStringMap* self = (const cStringMap*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'size'", NULL); -#endif - { - unsigned int tolua_ret = (unsigned int) self->size(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'size'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: get of class cStringMap */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cStringMap_get00 -static int tolua_AllToLua_cStringMap_get00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cStringMap",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cStringMap* self = (cStringMap*) tolua_tousertype(tolua_S,1,0); - const std::string index = ((const std::string) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'get'", NULL); -#endif - { - std::string tolua_ret = (std::string) self->get(index); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)index); - } - } - return 2; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'get'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Color of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Color -static int tolua_get_cChatColor_Color(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::Color); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Delimiter of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Delimiter -static int tolua_get_cChatColor_Delimiter(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::Delimiter); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Black of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Black -static int tolua_get_cChatColor_Black(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::Black); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Navy of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Navy -static int tolua_get_cChatColor_Navy(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::Navy); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Green of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Green -static int tolua_get_cChatColor_Green(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::Green); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Blue of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Blue -static int tolua_get_cChatColor_Blue(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::Blue); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Red of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Red -static int tolua_get_cChatColor_Red(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::Red); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Purple of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Purple -static int tolua_get_cChatColor_Purple(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::Purple); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Gold of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Gold -static int tolua_get_cChatColor_Gold(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::Gold); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: LightGray of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_LightGray -static int tolua_get_cChatColor_LightGray(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::LightGray); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Gray of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Gray -static int tolua_get_cChatColor_Gray(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::Gray); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: DarkPurple of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_DarkPurple -static int tolua_get_cChatColor_DarkPurple(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::DarkPurple); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: LightGreen of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_LightGreen -static int tolua_get_cChatColor_LightGreen(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::LightGreen); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: LightBlue of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_LightBlue -static int tolua_get_cChatColor_LightBlue(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::LightBlue); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Rose of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Rose -static int tolua_get_cChatColor_Rose(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::Rose); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: LightPurple of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_LightPurple -static int tolua_get_cChatColor_LightPurple(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::LightPurple); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Yellow of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Yellow -static int tolua_get_cChatColor_Yellow(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::Yellow); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: White of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_White -static int tolua_get_cChatColor_White(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::White); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Random of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Random -static int tolua_get_cChatColor_Random(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::Random); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Bold of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Bold -static int tolua_get_cChatColor_Bold(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::Bold); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Strikethrough of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Strikethrough -static int tolua_get_cChatColor_Strikethrough(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::Strikethrough); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Underlined of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Underlined -static int tolua_get_cChatColor_Underlined(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::Underlined); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Italic of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Italic -static int tolua_get_cChatColor_Italic(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::Italic); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Plain of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Plain -static int tolua_get_cChatColor_Plain(lua_State* tolua_S) -{ - tolua_pushcppstring(tolua_S,(const char*)cChatColor::Plain); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* method: MakeColor of class cChatColor */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cChatColor_MakeColor00 -static int tolua_AllToLua_cChatColor_MakeColor00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cChatColor",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - char a_Color = ((char) tolua_tonumber(tolua_S,2,0)); - { - const std::string tolua_ret = (const std::string) cChatColor::MakeColor(a_Color); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'MakeColor'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetPlayer of class cClientHandle */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_GetPlayer00 -static int tolua_AllToLua_cClientHandle_GetPlayer00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cClientHandle",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cClientHandle* self = (cClientHandle*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPlayer'", NULL); -#endif - { - cPlayer* tolua_ret = (cPlayer*) self->GetPlayer(); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPlayer"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetPlayer'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Kick of class cClientHandle */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_Kick00 -static int tolua_AllToLua_cClientHandle_Kick00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cClientHandle",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cClientHandle* self = (cClientHandle*) tolua_tousertype(tolua_S,1,0); - const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Kick'", NULL); -#endif - { - self->Kick(a_Reason); - tolua_pushcppstring(tolua_S,(const char*)a_Reason); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Kick'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetUsername of class cClientHandle */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_GetUsername00 -static int tolua_AllToLua_cClientHandle_GetUsername00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cClientHandle",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cClientHandle* self = (const cClientHandle*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetUsername'", NULL); -#endif - { - const AString tolua_ret = (const AString) self->GetUsername(); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetUsername'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetPing of class cClientHandle */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_GetPing00 -static int tolua_AllToLua_cClientHandle_GetPing00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cClientHandle",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cClientHandle* self = (const cClientHandle*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPing'", NULL); -#endif - { - short tolua_ret = (short) self->GetPing(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetPing'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetViewDistance of class cClientHandle */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_SetViewDistance00 -static int tolua_AllToLua_cClientHandle_SetViewDistance00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cClientHandle",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cClientHandle* self = (cClientHandle*) tolua_tousertype(tolua_S,1,0); - int a_ViewDistance = ((int) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetViewDistance'", NULL); -#endif - { - self->SetViewDistance(a_ViewDistance); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetViewDistance'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetViewDistance of class cClientHandle */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_GetViewDistance00 -static int tolua_AllToLua_cClientHandle_GetViewDistance00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cClientHandle",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cClientHandle* self = (cClientHandle*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetViewDistance'", NULL); -#endif - { - int tolua_ret = (int) self->GetViewDistance(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetViewDistance'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetUniqueID of class cClientHandle */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_GetUniqueID00 -static int tolua_AllToLua_cClientHandle_GetUniqueID00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cClientHandle",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cClientHandle* self = (const cClientHandle*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetUniqueID'", NULL); -#endif - { - int tolua_ret = (int) self->GetUniqueID(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetUniqueID'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: delete of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_delete00 -static int tolua_AllToLua_cEntity_delete00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); -#endif - Mtolua_delete(self); - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Initialize of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_Initialize00 -static int tolua_AllToLua_cEntity_Initialize00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); - cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL); -#endif - { - self->Initialize(a_World); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetEntityType of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetEntityType00 -static int tolua_AllToLua_cEntity_GetEntityType00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEntityType'", NULL); -#endif - { - unsigned int tolua_ret = (unsigned int) self->GetEntityType(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetEntityType'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: IsA of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_IsA00 -static int tolua_AllToLua_cEntity_IsA00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); - const char* a_EntityType = ((const char*) tolua_tostring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsA'", NULL); -#endif - { - bool tolua_ret = (bool) self->IsA(a_EntityType); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'IsA'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetClass of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetClass00 -static int tolua_AllToLua_cEntity_GetClass00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetClass'", NULL); -#endif - { - const char* tolua_ret = (const char*) self->GetClass(); - tolua_pushstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetClass'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetWorld of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetWorld00 -static int tolua_AllToLua_cEntity_GetWorld00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWorld'", NULL); -#endif - { - cWorld* tolua_ret = (cWorld*) self->GetWorld(); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWorld"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetWorld'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetPosition of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPosition00 -static int tolua_AllToLua_cEntity_GetPosition00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPosition'", NULL); -#endif - { - const Vector3d& tolua_ret = (const Vector3d&) self->GetPosition(); - tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const Vector3d"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetPosition'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetPosX of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPosX00 -static int tolua_AllToLua_cEntity_GetPosX00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPosX'", NULL); -#endif - { - const double tolua_ret = (const double) self->GetPosX(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetPosX'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetPosY of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPosY00 -static int tolua_AllToLua_cEntity_GetPosY00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPosY'", NULL); -#endif - { - const double tolua_ret = (const double) self->GetPosY(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetPosY'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetPosZ of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPosZ00 -static int tolua_AllToLua_cEntity_GetPosZ00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPosZ'", NULL); -#endif - { - const double tolua_ret = (const double) self->GetPosZ(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetPosZ'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetRot of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetRot00 -static int tolua_AllToLua_cEntity_GetRot00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetRot'", NULL); -#endif - { - const Vector3f& tolua_ret = (const Vector3f&) self->GetRot(); - tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const Vector3f"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetRot'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetRotation of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetRotation00 -static int tolua_AllToLua_cEntity_GetRotation00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetRotation'", NULL); -#endif - { - float tolua_ret = (float) self->GetRotation(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetRotation'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetPitch of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPitch00 -static int tolua_AllToLua_cEntity_GetPitch00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPitch'", NULL); -#endif - { - float tolua_ret = (float) self->GetPitch(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetPitch'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetRoll of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetRoll00 -static int tolua_AllToLua_cEntity_GetRoll00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetRoll'", NULL); -#endif - { - float tolua_ret = (float) self->GetRoll(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetRoll'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetLookVector of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetLookVector00 -static int tolua_AllToLua_cEntity_GetLookVector00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLookVector'", NULL); -#endif - { - Vector3f tolua_ret = (Vector3f) self->GetLookVector(); - { -#ifdef __cplusplus - void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#else - void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#endif - } - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetLookVector'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetChunkX of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetChunkX00 -static int tolua_AllToLua_cEntity_GetChunkX00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetChunkX'", NULL); -#endif - { - int tolua_ret = (int) self->GetChunkX(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetChunkX'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetChunkY of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetChunkY00 -static int tolua_AllToLua_cEntity_GetChunkY00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetChunkY'", NULL); -#endif - { - int tolua_ret = (int) self->GetChunkY(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetChunkY'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetChunkZ of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetChunkZ00 -static int tolua_AllToLua_cEntity_GetChunkZ00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetChunkZ'", NULL); -#endif - { - int tolua_ret = (int) self->GetChunkZ(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetChunkZ'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetPosX of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosX00 -static int tolua_AllToLua_cEntity_SetPosX00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); - const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPosX'", NULL); -#endif - { - self->SetPosX(a_PosX); - tolua_pushnumber(tolua_S,(lua_Number)a_PosX); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetPosX'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetPosY of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosY00 -static int tolua_AllToLua_cEntity_SetPosY00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); - const double a_PosY = ((const double) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPosY'", NULL); -#endif - { - self->SetPosY(a_PosY); - tolua_pushnumber(tolua_S,(lua_Number)a_PosY); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetPosY'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetPosZ of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosZ00 -static int tolua_AllToLua_cEntity_SetPosZ00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); - const double a_PosZ = ((const double) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPosZ'", NULL); -#endif - { - self->SetPosZ(a_PosZ); - tolua_pushnumber(tolua_S,(lua_Number)a_PosZ); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetPosZ'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetPosition of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosition00 -static int tolua_AllToLua_cEntity_SetPosition00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); - const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0)); - const double a_PosY = ((const double) tolua_tonumber(tolua_S,3,0)); - const double a_PosZ = ((const double) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPosition'", NULL); -#endif - { - self->SetPosition(a_PosX,a_PosY,a_PosZ); - tolua_pushnumber(tolua_S,(lua_Number)a_PosX); - tolua_pushnumber(tolua_S,(lua_Number)a_PosY); - tolua_pushnumber(tolua_S,(lua_Number)a_PosZ); - } - } - return 3; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetPosition'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetPosition of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosition01 -static int tolua_AllToLua_cEntity_SetPosition01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); - const Vector3d* a_Pos = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPosition'", NULL); -#endif - { - self->SetPosition(*a_Pos); - } - } - return 0; -tolua_lerror: - return tolua_AllToLua_cEntity_SetPosition00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetRot of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetRot00 -static int tolua_AllToLua_cEntity_SetRot00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); - const Vector3f* a_Rot = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetRot'", NULL); -#endif - { - self->SetRot(*a_Rot); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetRot'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetRotation of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetRotation00 -static int tolua_AllToLua_cEntity_SetRotation00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); - float a_Rotation = ((float) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetRotation'", NULL); -#endif - { - self->SetRotation(a_Rotation); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetRotation'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetPitch of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPitch00 -static int tolua_AllToLua_cEntity_SetPitch00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); - float a_Pitch = ((float) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPitch'", NULL); -#endif - { - self->SetPitch(a_Pitch); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetPitch'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetRoll of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetRoll00 -static int tolua_AllToLua_cEntity_SetRoll00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); - float a_Roll = ((float) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetRoll'", NULL); -#endif - { - self->SetRoll(a_Roll); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetRoll'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetUniqueID of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetUniqueID00 -static int tolua_AllToLua_cEntity_GetUniqueID00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetUniqueID'", NULL); -#endif - { - int tolua_ret = (int) self->GetUniqueID(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetUniqueID'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: IsDestroyed of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_IsDestroyed00 -static int tolua_AllToLua_cEntity_IsDestroyed00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsDestroyed'", NULL); -#endif - { - bool tolua_ret = (bool) self->IsDestroyed(); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'IsDestroyed'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Destroy of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_Destroy00 -static int tolua_AllToLua_cEntity_Destroy00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Destroy'", NULL); -#endif - { - self->Destroy(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Destroy'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Tick of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_Tick00 -static int tolua_AllToLua_cEntity_Tick00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); - float a_Dt = ((float) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Tick'", NULL); -#endif - { - self->Tick(a_Dt); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Tick'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SpawnOn of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SpawnOn00 -static int tolua_AllToLua_cEntity_SpawnOn00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cClientHandle",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); - cClientHandle* a_Client = ((cClientHandle*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SpawnOn'", NULL); -#endif - { - self->SpawnOn(a_Client); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SpawnOn'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - - class Lua__cEntity : public cEntity, public ToluaBase { -public: - void Initialize( cWorld* a_World) { - if (push_method("Initialize", tolua_AllToLua_cEntity_Initialize00)) { - tolua_pushusertype(lua_state, (void*)a_World, "cWorld"); - ToluaBase::dbcall(lua_state, 2, 0); - } else { - return ( void ) cEntity:: Initialize(a_World); - }; - }; - unsigned int GetEntityType( void ) { - if (push_method("GetEntityType", tolua_AllToLua_cEntity_GetEntityType00)) { - ToluaBase::dbcall(lua_state, 1, 1); - unsigned int tolua_ret = (unsigned int )tolua_tonumber(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return (unsigned int ) cEntity:: GetEntityType(); - }; - }; - bool IsA( const char* a_EntityType) { - if (push_method("IsA", tolua_AllToLua_cEntity_IsA00)) { - tolua_pushstring(lua_state, (const char*)a_EntityType); - ToluaBase::dbcall(lua_state, 2, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cEntity:: IsA(a_EntityType); - }; - }; - const char* GetClass( void ) { - if (push_method("GetClass", tolua_AllToLua_cEntity_GetClass00)) { - ToluaBase::dbcall(lua_state, 1, 1); - const char* tolua_ret = ( const char* )tolua_tostring(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( const char* ) cEntity:: GetClass(); - }; - }; - void Tick( float a_Dt) { - if (push_method("Tick", tolua_AllToLua_cEntity_Tick00)) { - tolua_pushnumber(lua_state, (lua_Number)a_Dt); - ToluaBase::dbcall(lua_state, 2, 0); - } else { - if (lua_state) - LOG("pure-virtual method cEntity::Tick not implemented."); - else { - LOG("pure-virtual method cEntity::Tick called with no lua_state. Aborting"); - ::abort(); - }; - return ( void )0; - }; - }; - - void cEntity__Initialize( cWorld* a_World) { - return ( void )cEntity::Initialize(a_World); - }; - unsigned int cEntity__GetEntityType( void ) { - return (unsigned int )cEntity::GetEntityType(); - }; - bool cEntity__IsA( const char* a_EntityType) { - return ( bool )cEntity::IsA(a_EntityType); - }; - const char* cEntity__GetClass( void ) { - return ( const char* )cEntity::GetClass(); - }; - Lua__cEntity( const double& a_X, const double& a_Y, const double& a_Z): cEntity(a_X,a_Y,a_Z){}; -}; - -/* method: tolua__set_instance of class Lua__cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_tolua__set_instance00 -static int tolua_AllToLua_Lua__cEntity_tolua__set_instance00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); - lua_State* L = tolua_S; - lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); -#endif - { - self->tolua__set_instance(L,lo); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cEntity__Initialize of class Lua__cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_cEntity__Initialize00 -static int tolua_AllToLua_Lua__cEntity_cEntity__Initialize00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); - cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cEntity__Initialize'", NULL); -#endif - { - self->cEntity__Initialize(a_World); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cEntity__Initialize'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cEntity__GetEntityType of class Lua__cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_cEntity__GetEntityType00 -static int tolua_AllToLua_Lua__cEntity_cEntity__GetEntityType00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cEntity__GetEntityType'", NULL); -#endif - { - unsigned int tolua_ret = (unsigned int) self->cEntity__GetEntityType(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cEntity__GetEntityType'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cEntity__IsA of class Lua__cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_cEntity__IsA00 -static int tolua_AllToLua_Lua__cEntity_cEntity__IsA00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); - const char* a_EntityType = ((const char*) tolua_tostring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cEntity__IsA'", NULL); -#endif - { - bool tolua_ret = (bool) self->cEntity__IsA(a_EntityType); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cEntity__IsA'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cEntity__GetClass of class Lua__cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_cEntity__GetClass00 -static int tolua_AllToLua_Lua__cEntity_cEntity__GetClass00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cEntity__GetClass'", NULL); -#endif - { - const char* tolua_ret = (const char*) self->cEntity__GetClass(); - tolua_pushstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cEntity__GetClass'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class Lua__cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_new00 -static int tolua_AllToLua_Lua__cEntity_new00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Lua__cEntity",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const double a_X = ((const double) tolua_tonumber(tolua_S,2,0)); - const double a_Y = ((const double) tolua_tonumber(tolua_S,3,0)); - const double a_Z = ((const double) tolua_tonumber(tolua_S,4,0)); - { - Lua__cEntity* tolua_ret = (Lua__cEntity*) Mtolua_new((Lua__cEntity)(a_X,a_Y,a_Z)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cEntity"); - tolua_pushnumber(tolua_S,(lua_Number)a_X); - tolua_pushnumber(tolua_S,(lua_Number)a_Y); - tolua_pushnumber(tolua_S,(lua_Number)a_Z); - } - } - return 4; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class Lua__cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_new00_local -static int tolua_AllToLua_Lua__cEntity_new00_local(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Lua__cEntity",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const double a_X = ((const double) tolua_tonumber(tolua_S,2,0)); - const double a_Y = ((const double) tolua_tonumber(tolua_S,3,0)); - const double a_Z = ((const double) tolua_tonumber(tolua_S,4,0)); - { - Lua__cEntity* tolua_ret = (Lua__cEntity*) Mtolua_new((Lua__cEntity)(a_X,a_Y,a_Z)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cEntity"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - tolua_pushnumber(tolua_S,(lua_Number)a_X); - tolua_pushnumber(tolua_S,(lua_Number)a_Y); - tolua_pushnumber(tolua_S,(lua_Number)a_Z); - } - } - return 4; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: delete of class Lua__cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_delete00 -static int tolua_AllToLua_Lua__cEntity_delete00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); -#endif - Mtolua_delete(self); - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - - -/* function to release collected object via destructor */ -#ifdef __cplusplus - -static int tolua_collect_Lua__cEntity (lua_State* tolua_S) -{ - Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); - delete self; - return 0; -} -#endif - -/* get function: Damage of class TakeDamageInfo */ -#ifndef TOLUA_DISABLE_tolua_get_TakeDamageInfo_Damage -static int tolua_get_TakeDamageInfo_Damage(lua_State* tolua_S) -{ - TakeDamageInfo* self = (TakeDamageInfo*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Damage'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->Damage); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: Damage of class TakeDamageInfo */ -#ifndef TOLUA_DISABLE_tolua_set_TakeDamageInfo_Damage -static int tolua_set_TakeDamageInfo_Damage(lua_State* tolua_S) -{ - TakeDamageInfo* self = (TakeDamageInfo*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Damage'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->Damage = ((int) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Instigator of class TakeDamageInfo */ -#ifndef TOLUA_DISABLE_tolua_get_TakeDamageInfo_Instigator_ptr -static int tolua_get_TakeDamageInfo_Instigator_ptr(lua_State* tolua_S) -{ - TakeDamageInfo* self = (TakeDamageInfo*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Instigator'",NULL); -#endif - tolua_pushusertype(tolua_S,(void*)self->Instigator,"cEntity"); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: Instigator of class TakeDamageInfo */ -#ifndef TOLUA_DISABLE_tolua_set_TakeDamageInfo_Instigator_ptr -static int tolua_set_TakeDamageInfo_Instigator_ptr(lua_State* tolua_S) -{ - TakeDamageInfo* self = (TakeDamageInfo*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Instigator'",NULL); - if (!tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->Instigator = ((cEntity*) tolua_tousertype(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* method: TeleportToEntity of class cPawn */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_TeleportToEntity00 -static int tolua_AllToLua_cPawn_TeleportToEntity00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0); - cEntity* a_Entity = ((cEntity*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TeleportToEntity'", NULL); -#endif - { - self->TeleportToEntity(a_Entity); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'TeleportToEntity'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: TeleportTo of class cPawn */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_TeleportTo00 -static int tolua_AllToLua_cPawn_TeleportTo00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0); - const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0)); - const double a_PosY = ((const double) tolua_tonumber(tolua_S,3,0)); - const double a_PosZ = ((const double) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TeleportTo'", NULL); -#endif - { - self->TeleportTo(a_PosX,a_PosY,a_PosZ); - tolua_pushnumber(tolua_S,(lua_Number)a_PosX); - tolua_pushnumber(tolua_S,(lua_Number)a_PosY); - tolua_pushnumber(tolua_S,(lua_Number)a_PosZ); - } - } - return 3; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'TeleportTo'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Heal of class cPawn */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_Heal00 -static int tolua_AllToLua_cPawn_Heal00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0); - int a_Health = ((int) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Heal'", NULL); -#endif - { - self->Heal(a_Health); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Heal'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: TakeDamage of class cPawn */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_TakeDamage00 -static int tolua_AllToLua_cPawn_TakeDamage00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0); - int a_Damage = ((int) tolua_tonumber(tolua_S,2,0)); - cEntity* a_Instigator = ((cEntity*) tolua_tousertype(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TakeDamage'", NULL); -#endif - { - self->TakeDamage(a_Damage,a_Instigator); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'TakeDamage'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: KilledBy of class cPawn */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_KilledBy00 -static int tolua_AllToLua_cPawn_KilledBy00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0); - cEntity* a_Killer = ((cEntity*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KilledBy'", NULL); -#endif - { - self->KilledBy(a_Killer); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'KilledBy'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetHealth of class cPawn */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_GetHealth00 -static int tolua_AllToLua_cPawn_GetHealth00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHealth'", NULL); -#endif - { - int tolua_ret = (int) self->GetHealth(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetHealth'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - - class Lua__cPawn : public cPawn, public ToluaBase { -public: - void TeleportToEntity( cEntity* a_Entity) { - if (push_method("TeleportToEntity", tolua_AllToLua_cPawn_TeleportToEntity00)) { - tolua_pushusertype(lua_state, (void*)a_Entity, "cEntity"); - ToluaBase::dbcall(lua_state, 2, 0); - } else { - return ( void ) cPawn:: TeleportToEntity(a_Entity); - }; - }; - void TeleportTo( const double& a_PosX, const double& a_PosY, const double& a_PosZ) { - if (push_method("TeleportTo", tolua_AllToLua_cPawn_TeleportTo00)) { - tolua_pushnumber(lua_state, (lua_Number)a_PosX); - tolua_pushnumber(lua_state, (lua_Number)a_PosY); - tolua_pushnumber(lua_state, (lua_Number)a_PosZ); - ToluaBase::dbcall(lua_state, 4, 0); - } else { - return ( void ) cPawn:: TeleportTo(a_PosX,a_PosY,a_PosZ); - }; - }; - void TakeDamage( int a_Damage, cEntity* a_Instigator) { - if (push_method("TakeDamage", tolua_AllToLua_cPawn_TakeDamage00)) { - tolua_pushnumber(lua_state, (lua_Number)a_Damage); - tolua_pushusertype(lua_state, (void*)a_Instigator, "cEntity"); - ToluaBase::dbcall(lua_state, 3, 0); - } else { - return ( void ) cPawn:: TakeDamage(a_Damage,a_Instigator); - }; - }; - void KilledBy( cEntity* a_Killer) { - if (push_method("KilledBy", tolua_AllToLua_cPawn_KilledBy00)) { - tolua_pushusertype(lua_state, (void*)a_Killer, "cEntity"); - ToluaBase::dbcall(lua_state, 2, 0); - } else { - return ( void ) cPawn:: KilledBy(a_Killer); - }; - }; - void Initialize( cWorld* a_World) { - if (push_method("Initialize", tolua_AllToLua_cEntity_Initialize00)) { - tolua_pushusertype(lua_state, (void*)a_World, "cWorld"); - ToluaBase::dbcall(lua_state, 2, 0); - } else { - return ( void ) cPawn:: Initialize(a_World); - }; - }; - unsigned int GetEntityType( void ) { - if (push_method("GetEntityType", tolua_AllToLua_cEntity_GetEntityType00)) { - ToluaBase::dbcall(lua_state, 1, 1); - unsigned int tolua_ret = (unsigned int )tolua_tonumber(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return (unsigned int ) cPawn:: GetEntityType(); - }; - }; - bool IsA( const char* a_EntityType) { - if (push_method("IsA", tolua_AllToLua_cEntity_IsA00)) { - tolua_pushstring(lua_state, (const char*)a_EntityType); - ToluaBase::dbcall(lua_state, 2, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPawn:: IsA(a_EntityType); - }; - }; - const char* GetClass( void ) { - if (push_method("GetClass", tolua_AllToLua_cEntity_GetClass00)) { - ToluaBase::dbcall(lua_state, 1, 1); - const char* tolua_ret = ( const char* )tolua_tostring(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( const char* ) cPawn:: GetClass(); - }; - }; - void Tick( float a_Dt) { - if (push_method("Tick", tolua_AllToLua_cEntity_Tick00)) { - tolua_pushnumber(lua_state, (lua_Number)a_Dt); - ToluaBase::dbcall(lua_state, 2, 0); - } else { - if (lua_state) - LOG("pure-virtual method cPawn::Tick not implemented."); - else { - LOG("pure-virtual method cPawn::Tick called with no lua_state. Aborting"); - ::abort(); - }; - return ( void )0; - }; - }; - - void cPawn__TeleportToEntity( cEntity* a_Entity) { - return ( void )cPawn::TeleportToEntity(a_Entity); - }; - void cPawn__TeleportTo( const double& a_PosX, const double& a_PosY, const double& a_PosZ) { - return ( void )cPawn::TeleportTo(a_PosX,a_PosY,a_PosZ); - }; - void cPawn__TakeDamage( int a_Damage, cEntity* a_Instigator) { - return ( void )cPawn::TakeDamage(a_Damage,a_Instigator); - }; - void cPawn__KilledBy( cEntity* a_Killer) { - return ( void )cPawn::KilledBy(a_Killer); - }; - void cPawn__Initialize( cWorld* a_World) { - return ( void )cPawn::Initialize(a_World); - }; - unsigned int cPawn__GetEntityType( void ) { - return (unsigned int )cPawn::GetEntityType(); - }; - bool cPawn__IsA( const char* a_EntityType) { - return ( bool )cPawn::IsA(a_EntityType); - }; - const char* cPawn__GetClass( void ) { - return ( const char* )cPawn::GetClass(); - }; -}; - -/* method: tolua__set_instance of class Lua__cPawn */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPawn_tolua__set_instance00 -static int tolua_AllToLua_Lua__cPawn_tolua__set_instance00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPawn",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPawn* self = (Lua__cPawn*) tolua_tousertype(tolua_S,1,0); - lua_State* L = tolua_S; - lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); -#endif - { - self->tolua__set_instance(L,lo); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPawn__TeleportToEntity of class Lua__cPawn */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPawn_cPawn__TeleportToEntity00 -static int tolua_AllToLua_Lua__cPawn_cPawn__TeleportToEntity00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPawn",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPawn* self = (Lua__cPawn*) tolua_tousertype(tolua_S,1,0); - cEntity* a_Entity = ((cEntity*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPawn__TeleportToEntity'", NULL); -#endif - { - self->cPawn__TeleportToEntity(a_Entity); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPawn__TeleportToEntity'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPawn__TeleportTo of class Lua__cPawn */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPawn_cPawn__TeleportTo00 -static int tolua_AllToLua_Lua__cPawn_cPawn__TeleportTo00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPawn",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPawn* self = (Lua__cPawn*) tolua_tousertype(tolua_S,1,0); - const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0)); - const double a_PosY = ((const double) tolua_tonumber(tolua_S,3,0)); - const double a_PosZ = ((const double) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPawn__TeleportTo'", NULL); -#endif - { - self->cPawn__TeleportTo(a_PosX,a_PosY,a_PosZ); - tolua_pushnumber(tolua_S,(lua_Number)a_PosX); - tolua_pushnumber(tolua_S,(lua_Number)a_PosY); - tolua_pushnumber(tolua_S,(lua_Number)a_PosZ); - } - } - return 3; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPawn__TeleportTo'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPawn__TakeDamage of class Lua__cPawn */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPawn_cPawn__TakeDamage00 -static int tolua_AllToLua_Lua__cPawn_cPawn__TakeDamage00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPawn",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPawn* self = (Lua__cPawn*) tolua_tousertype(tolua_S,1,0); - int a_Damage = ((int) tolua_tonumber(tolua_S,2,0)); - cEntity* a_Instigator = ((cEntity*) tolua_tousertype(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPawn__TakeDamage'", NULL); -#endif - { - self->cPawn__TakeDamage(a_Damage,a_Instigator); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPawn__TakeDamage'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPawn__KilledBy of class Lua__cPawn */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPawn_cPawn__KilledBy00 -static int tolua_AllToLua_Lua__cPawn_cPawn__KilledBy00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPawn",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPawn* self = (Lua__cPawn*) tolua_tousertype(tolua_S,1,0); - cEntity* a_Killer = ((cEntity*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPawn__KilledBy'", NULL); -#endif - { - self->cPawn__KilledBy(a_Killer); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPawn__KilledBy'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Initialize of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_Initialize00 -static int tolua_AllToLua_cPlayer_Initialize00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL); -#endif - { - self->Initialize(a_World); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetEyeHeight of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetEyeHeight00 -static int tolua_AllToLua_cPlayer_GetEyeHeight00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEyeHeight'", NULL); -#endif - { - double tolua_ret = (double) self->GetEyeHeight(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetEyeHeight'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetEyePosition of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetEyePosition00 -static int tolua_AllToLua_cPlayer_GetEyePosition00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEyePosition'", NULL); -#endif - { - Vector3d tolua_ret = (Vector3d) self->GetEyePosition(); - { -#ifdef __cplusplus - void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#else - void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#endif - } - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetEyePosition'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetFlying of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetFlying00 -static int tolua_AllToLua_cPlayer_GetFlying00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetFlying'", NULL); -#endif - { - bool tolua_ret = (bool) self->GetFlying(); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetFlying'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetStance of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetStance00 -static int tolua_AllToLua_cPlayer_GetStance00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetStance'", NULL); -#endif - { - const double tolua_ret = (const double) self->GetStance(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetStance'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetInventory of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetInventory00 -static int tolua_AllToLua_cPlayer_GetInventory00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetInventory'", NULL); -#endif - { - cInventory& tolua_ret = (cInventory&) self->GetInventory(); - tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cInventory"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetInventory'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: TeleportTo of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_TeleportTo00 -static int tolua_AllToLua_cPlayer_TeleportTo00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0)); - const double a_PosY = ((const double) tolua_tonumber(tolua_S,3,0)); - const double a_PosZ = ((const double) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TeleportTo'", NULL); -#endif - { - self->TeleportTo(a_PosX,a_PosY,a_PosZ); - tolua_pushnumber(tolua_S,(lua_Number)a_PosX); - tolua_pushnumber(tolua_S,(lua_Number)a_PosY); - tolua_pushnumber(tolua_S,(lua_Number)a_PosZ); - } - } - return 3; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'TeleportTo'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetGameMode of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetGameMode00 -static int tolua_AllToLua_cPlayer_GetGameMode00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetGameMode'", NULL); -#endif - { - eGameMode tolua_ret = (eGameMode) self->GetGameMode(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetGameMode'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetIP of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetIP00 -static int tolua_AllToLua_cPlayer_GetIP00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetIP'", NULL); -#endif - { - std::string tolua_ret = (std::string) self->GetIP(); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetIP'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetLastBlockActionTime of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetLastBlockActionTime00 -static int tolua_AllToLua_cPlayer_GetLastBlockActionTime00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLastBlockActionTime'", NULL); -#endif - { - float tolua_ret = (float) self->GetLastBlockActionTime(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetLastBlockActionTime'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetLastBlockActionCnt of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetLastBlockActionCnt00 -static int tolua_AllToLua_cPlayer_GetLastBlockActionCnt00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLastBlockActionCnt'", NULL); -#endif - { - int tolua_ret = (int) self->GetLastBlockActionCnt(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetLastBlockActionCnt'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetLastBlockActionCnt of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetLastBlockActionCnt00 -static int tolua_AllToLua_cPlayer_SetLastBlockActionCnt00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - int tolua_var_1 = ((int) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetLastBlockActionCnt'", NULL); -#endif - { - self->SetLastBlockActionCnt(tolua_var_1); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetLastBlockActionCnt'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetLastBlockActionTime of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetLastBlockActionTime00 -static int tolua_AllToLua_cPlayer_SetLastBlockActionTime00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetLastBlockActionTime'", NULL); -#endif - { - self->SetLastBlockActionTime(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetLastBlockActionTime'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetGameMode of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetGameMode00 -static int tolua_AllToLua_cPlayer_SetGameMode00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - eGameMode a_GameMode = ((eGameMode) (int) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetGameMode'", NULL); -#endif - { - self->SetGameMode(a_GameMode); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetGameMode'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: MoveTo of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_MoveTo00 -static int tolua_AllToLua_cPlayer_MoveTo00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - const Vector3d* a_NewPos = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'MoveTo'", NULL); -#endif - { - self->MoveTo(*a_NewPos); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'MoveTo'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetClientHandle of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetClientHandle00 -static int tolua_AllToLua_cPlayer_GetClientHandle00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetClientHandle'", NULL); -#endif - { - cClientHandle* tolua_ret = (cClientHandle*) self->GetClientHandle(); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cClientHandle"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetClientHandle'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SendMessage of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SendMessage00 -static int tolua_AllToLua_cPlayer_SendMessage00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - const char* a_Message = ((const char*) tolua_tostring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendMessage'", NULL); -#endif - { - self->SendMessage(a_Message); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SendMessage'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetName of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetName00 -static int tolua_AllToLua_cPlayer_GetName00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL); -#endif - { - const AString tolua_ret = (const AString) self->GetName(); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetName'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetName of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetName00 -static int tolua_AllToLua_cPlayer_SetName00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - const AString a_Name = ((const AString) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetName'", NULL); -#endif - { - self->SetName(a_Name); - tolua_pushcppstring(tolua_S,(const char*)a_Name); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetName'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: AddToGroup of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_AddToGroup00 -static int tolua_AllToLua_cPlayer_AddToGroup00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - const char* a_GroupName = ((const char*) tolua_tostring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddToGroup'", NULL); -#endif - { - self->AddToGroup(a_GroupName); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'AddToGroup'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: CanUseCommand of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_CanUseCommand00 -static int tolua_AllToLua_cPlayer_CanUseCommand00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - const char* a_Command = ((const char*) tolua_tostring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CanUseCommand'", NULL); -#endif - { - bool tolua_ret = (bool) self->CanUseCommand(a_Command); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'CanUseCommand'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: HasPermission of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_HasPermission00 -static int tolua_AllToLua_cPlayer_HasPermission00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - const char* a_Permission = ((const char*) tolua_tostring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HasPermission'", NULL); -#endif - { - bool tolua_ret = (bool) self->HasPermission(a_Permission); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'HasPermission'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: IsInGroup of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_IsInGroup00 -static int tolua_AllToLua_cPlayer_IsInGroup00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - const char* a_Group = ((const char*) tolua_tostring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsInGroup'", NULL); -#endif - { - bool tolua_ret = (bool) self->IsInGroup(a_Group); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'IsInGroup'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetColor of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetColor00 -static int tolua_AllToLua_cPlayer_GetColor00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetColor'", NULL); -#endif - { - AString tolua_ret = (AString) self->GetColor(); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetColor'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: TossItem of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_TossItem00 -static int tolua_AllToLua_cPlayer_TossItem00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isboolean(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,1,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - bool a_bDraggingItem = ((bool) tolua_toboolean(tolua_S,2,0)); - int a_Amount = ((int) tolua_tonumber(tolua_S,3,1)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TossItem'", NULL); -#endif - { - self->TossItem(a_bDraggingItem,a_Amount); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'TossItem'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Heal of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_Heal00 -static int tolua_AllToLua_cPlayer_Heal00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - int a_Health = ((int) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Heal'", NULL); -#endif - { - self->Heal(a_Health); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Heal'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: TakeDamage of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_TakeDamage00 -static int tolua_AllToLua_cPlayer_TakeDamage00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - int a_Damage = ((int) tolua_tonumber(tolua_S,2,0)); - cEntity* a_Instigator = ((cEntity*) tolua_tousertype(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TakeDamage'", NULL); -#endif - { - self->TakeDamage(a_Damage,a_Instigator); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'TakeDamage'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: KilledBy of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_KilledBy00 -static int tolua_AllToLua_cPlayer_KilledBy00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - cEntity* a_Killer = ((cEntity*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KilledBy'", NULL); -#endif - { - self->KilledBy(a_Killer); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'KilledBy'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Respawn of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_Respawn00 -static int tolua_AllToLua_cPlayer_Respawn00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Respawn'", NULL); -#endif - { - self->Respawn(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Respawn'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetVisible of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetVisible00 -static int tolua_AllToLua_cPlayer_SetVisible00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isboolean(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - bool a_bVisible = ((bool) tolua_toboolean(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetVisible'", NULL); -#endif - { - self->SetVisible(a_bVisible); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetVisible'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: IsVisible of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_IsVisible00 -static int tolua_AllToLua_cPlayer_IsVisible00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsVisible'", NULL); -#endif - { - bool tolua_ret = (bool) self->IsVisible(); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'IsVisible'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: MoveToWorld of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_MoveToWorld00 -static int tolua_AllToLua_cPlayer_MoveToWorld00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - const char* a_WorldName = ((const char*) tolua_tostring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'MoveToWorld'", NULL); -#endif - { - bool tolua_ret = (bool) self->MoveToWorld(a_WorldName); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'MoveToWorld'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: LoadPermissionsFromDisk of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_LoadPermissionsFromDisk00 -static int tolua_AllToLua_cPlayer_LoadPermissionsFromDisk00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'LoadPermissionsFromDisk'", NULL); -#endif - { - self->LoadPermissionsFromDisk(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'LoadPermissionsFromDisk'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - - class Lua__cPlayer : public cPlayer, public ToluaBase { -public: - void Initialize( cWorld* a_World) { - if (push_method("Initialize", tolua_AllToLua_cPlayer_Initialize00)) { - tolua_pushusertype(lua_state, (void*)a_World, "cWorld"); - ToluaBase::dbcall(lua_state, 2, 0); - } else { - return ( void ) cPlayer:: Initialize(a_World); - }; - }; - void TeleportTo( const double& a_PosX, const double& a_PosY, const double& a_PosZ) { - if (push_method("TeleportTo", tolua_AllToLua_cPlayer_TeleportTo00)) { - tolua_pushnumber(lua_state, (lua_Number)a_PosX); - tolua_pushnumber(lua_state, (lua_Number)a_PosY); - tolua_pushnumber(lua_state, (lua_Number)a_PosZ); - ToluaBase::dbcall(lua_state, 4, 0); - } else { - return ( void ) cPlayer:: TeleportTo(a_PosX,a_PosY,a_PosZ); - }; - }; - void MoveTo( const Vector3d& a_NewPos) { - if (push_method("MoveTo", tolua_AllToLua_cPlayer_MoveTo00)) { - tolua_pushusertype(lua_state, (void*)&a_NewPos, "const Vector3d"); - ToluaBase::dbcall(lua_state, 2, 0); - } else { - return ( void ) cPlayer:: MoveTo(a_NewPos); - }; - }; - void TeleportToEntity( cEntity* a_Entity) { - if (push_method("TeleportToEntity", tolua_AllToLua_cPawn_TeleportToEntity00)) { - tolua_pushusertype(lua_state, (void*)a_Entity, "cEntity"); - ToluaBase::dbcall(lua_state, 2, 0); - } else { - return ( void ) cPlayer:: TeleportToEntity(a_Entity); - }; - }; - void TakeDamage( int a_Damage, cEntity* a_Instigator) { - if (push_method("TakeDamage", tolua_AllToLua_cPawn_TakeDamage00)) { - tolua_pushnumber(lua_state, (lua_Number)a_Damage); - tolua_pushusertype(lua_state, (void*)a_Instigator, "cEntity"); - ToluaBase::dbcall(lua_state, 3, 0); - } else { - return ( void ) cPlayer:: TakeDamage(a_Damage,a_Instigator); - }; - }; - void KilledBy( cEntity* a_Killer) { - if (push_method("KilledBy", tolua_AllToLua_cPawn_KilledBy00)) { - tolua_pushusertype(lua_state, (void*)a_Killer, "cEntity"); - ToluaBase::dbcall(lua_state, 2, 0); - } else { - return ( void ) cPlayer:: KilledBy(a_Killer); - }; - }; - unsigned int GetEntityType( void ) { - if (push_method("GetEntityType", tolua_AllToLua_cEntity_GetEntityType00)) { - ToluaBase::dbcall(lua_state, 1, 1); - unsigned int tolua_ret = (unsigned int )tolua_tonumber(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return (unsigned int ) cPlayer:: GetEntityType(); - }; - }; - bool IsA( const char* a_EntityType) { - if (push_method("IsA", tolua_AllToLua_cEntity_IsA00)) { - tolua_pushstring(lua_state, (const char*)a_EntityType); - ToluaBase::dbcall(lua_state, 2, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlayer:: IsA(a_EntityType); - }; - }; - const char* GetClass( void ) { - if (push_method("GetClass", tolua_AllToLua_cEntity_GetClass00)) { - ToluaBase::dbcall(lua_state, 1, 1); - const char* tolua_ret = ( const char* )tolua_tostring(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( const char* ) cPlayer:: GetClass(); - }; - }; - void Tick( float a_Dt) { - if (push_method("Tick", tolua_AllToLua_cEntity_Tick00)) { - tolua_pushnumber(lua_state, (lua_Number)a_Dt); - ToluaBase::dbcall(lua_state, 2, 0); - } else { - if (lua_state) - LOG("pure-virtual method cPlayer::Tick not implemented."); - else { - LOG("pure-virtual method cPlayer::Tick called with no lua_state. Aborting"); - ::abort(); - }; - return ( void )0; - }; - }; - - void cPlayer__Initialize( cWorld* a_World) { - return ( void )cPlayer::Initialize(a_World); - }; - void cPlayer__TeleportTo( const double& a_PosX, const double& a_PosY, const double& a_PosZ) { - return ( void )cPlayer::TeleportTo(a_PosX,a_PosY,a_PosZ); - }; - void cPlayer__MoveTo( const Vector3d& a_NewPos) { - return ( void )cPlayer::MoveTo(a_NewPos); - }; - void cPlayer__TeleportToEntity( cEntity* a_Entity) { - return ( void )cPlayer::TeleportToEntity(a_Entity); - }; - void cPlayer__TakeDamage( int a_Damage, cEntity* a_Instigator) { - return ( void )cPlayer::TakeDamage(a_Damage,a_Instigator); - }; - void cPlayer__KilledBy( cEntity* a_Killer) { - return ( void )cPlayer::KilledBy(a_Killer); - }; - unsigned int cPlayer__GetEntityType( void ) { - return (unsigned int )cPlayer::GetEntityType(); - }; - bool cPlayer__IsA( const char* a_EntityType) { - return ( bool )cPlayer::IsA(a_EntityType); - }; - const char* cPlayer__GetClass( void ) { - return ( const char* )cPlayer::GetClass(); - }; -}; - -/* method: tolua__set_instance of class Lua__cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlayer_tolua__set_instance00 -static int tolua_AllToLua_Lua__cPlayer_tolua__set_instance00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlayer* self = (Lua__cPlayer*) tolua_tousertype(tolua_S,1,0); - lua_State* L = tolua_S; - lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); -#endif - { - self->tolua__set_instance(L,lo); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlayer__Initialize of class Lua__cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlayer_cPlayer__Initialize00 -static int tolua_AllToLua_Lua__cPlayer_cPlayer__Initialize00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlayer",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlayer* self = (Lua__cPlayer*) tolua_tousertype(tolua_S,1,0); - cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlayer__Initialize'", NULL); -#endif - { - self->cPlayer__Initialize(a_World); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlayer__Initialize'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlayer__TeleportTo of class Lua__cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlayer_cPlayer__TeleportTo00 -static int tolua_AllToLua_Lua__cPlayer_cPlayer__TeleportTo00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlayer",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlayer* self = (Lua__cPlayer*) tolua_tousertype(tolua_S,1,0); - const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0)); - const double a_PosY = ((const double) tolua_tonumber(tolua_S,3,0)); - const double a_PosZ = ((const double) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlayer__TeleportTo'", NULL); -#endif - { - self->cPlayer__TeleportTo(a_PosX,a_PosY,a_PosZ); - tolua_pushnumber(tolua_S,(lua_Number)a_PosX); - tolua_pushnumber(tolua_S,(lua_Number)a_PosY); - tolua_pushnumber(tolua_S,(lua_Number)a_PosZ); - } - } - return 3; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlayer__TeleportTo'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlayer__MoveTo of class Lua__cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlayer_cPlayer__MoveTo00 -static int tolua_AllToLua_Lua__cPlayer_cPlayer__MoveTo00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlayer",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlayer* self = (Lua__cPlayer*) tolua_tousertype(tolua_S,1,0); - const Vector3d* a_NewPos = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlayer__MoveTo'", NULL); -#endif - { - self->cPlayer__MoveTo(*a_NewPos); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlayer__MoveTo'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetPluginManager of class cPluginManager */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_GetPluginManager00 -static int tolua_AllToLua_cPluginManager_GetPluginManager00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cPluginManager",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - { - cPluginManager* tolua_ret = (cPluginManager*) cPluginManager::GetPluginManager(); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPluginManager"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetPluginManager'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetPlugin of class cPluginManager */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_GetPlugin00 -static int tolua_AllToLua_cPluginManager_GetPlugin00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cPluginManager",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cPluginManager* self = (const cPluginManager*) tolua_tousertype(tolua_S,1,0); - const char* a_Plugin = ((const char*) tolua_tostring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPlugin'", NULL); -#endif - { - cPlugin* tolua_ret = (cPlugin*) self->GetPlugin(a_Plugin); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPlugin"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetPlugin'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: ReloadPlugins of class cPluginManager */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_ReloadPlugins00 -static int tolua_AllToLua_cPluginManager_ReloadPlugins00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ReloadPlugins'", NULL); -#endif - { - self->ReloadPlugins(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'ReloadPlugins'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: AddPlugin of class cPluginManager */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_AddPlugin00 -static int tolua_AllToLua_cPluginManager_AddPlugin00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPlugin",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); - lua_State* a_LuaState = tolua_S; - cPlugin* a_Plugin = ((cPlugin*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddPlugin'", NULL); -#endif - { - bool tolua_ret = (bool) self->AddPlugin(a_LuaState,a_Plugin); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'AddPlugin'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: AddHook of class cPluginManager */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_AddHook00 -static int tolua_AllToLua_cPluginManager_AddHook00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPlugin",0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); - cPlugin* a_Plugin = ((cPlugin*) tolua_tousertype(tolua_S,2,0)); - cPluginManager::PluginHook a_Hook = ((cPluginManager::PluginHook) (int) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddHook'", NULL); -#endif - { - self->AddHook(a_Plugin,a_Hook); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'AddHook'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetNumPlugins of class cPluginManager */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_GetNumPlugins00 -static int tolua_AllToLua_cPluginManager_GetNumPlugins00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cPluginManager",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cPluginManager* self = (const cPluginManager*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumPlugins'", NULL); -#endif - { - unsigned int tolua_ret = (unsigned int) self->GetNumPlugins(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetNumPlugins'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: RemovePlugin of class cPluginManager */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_RemovePlugin00 -static int tolua_AllToLua_cPluginManager_RemovePlugin00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPlugin",0,&tolua_err) || - !tolua_isboolean(tolua_S,3,1,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); - cPlugin* a_Plugin = ((cPlugin*) tolua_tousertype(tolua_S,2,0)); - bool a_bDelete = ((bool) tolua_toboolean(tolua_S,3,false)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'RemovePlugin'", NULL); -#endif - { - self->RemovePlugin(a_Plugin,a_bDelete); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'RemovePlugin'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: RemoveLuaPlugin of class cPluginManager */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_RemoveLuaPlugin00 -static int tolua_AllToLua_cPluginManager_RemoveLuaPlugin00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); - std::string a_FileName = ((std::string) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'RemoveLuaPlugin'", NULL); -#endif - { - self->RemoveLuaPlugin(a_FileName); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'RemoveLuaPlugin'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetLuaPlugin of class cPluginManager */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_GetLuaPlugin00 -static int tolua_AllToLua_cPluginManager_GetLuaPlugin00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); - lua_State* a_State = tolua_S; -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLuaPlugin'", NULL); -#endif - { - cPlugin_Lua* tolua_ret = (cPlugin_Lua*) self->GetLuaPlugin(a_State); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPlugin_Lua"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetLuaPlugin'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: delete of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_delete00 -static int tolua_AllToLua_cPlugin_delete00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); -#endif - Mtolua_delete(self); - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: OnDisable of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnDisable00 -static int tolua_AllToLua_cPlugin_OnDisable00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnDisable'", NULL); -#endif - { - self->OnDisable(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'OnDisable'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Initialize of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_Initialize00 -static int tolua_AllToLua_cPlugin_Initialize00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL); -#endif - { - bool tolua_ret = (bool) self->Initialize(); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Tick of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_Tick00 -static int tolua_AllToLua_cPlugin_Tick00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - float a_Dt = ((float) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Tick'", NULL); -#endif - { - self->Tick(a_Dt); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Tick'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: OnCollectItem of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnCollectItem00 -static int tolua_AllToLua_cPlugin_OnCollectItem00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPickup",0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - cPickup* a_Pickup = ((cPickup*) tolua_tousertype(tolua_S,2,0)); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnCollectItem'", NULL); -#endif - { - bool tolua_ret = (bool) self->OnCollectItem(a_Pickup,a_Player); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'OnCollectItem'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: OnDisconnect of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnDisconnect00 -static int tolua_AllToLua_cPlugin_OnDisconnect00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,2,0)); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnDisconnect'", NULL); -#endif - { - bool tolua_ret = (bool) self->OnDisconnect(a_Reason,a_Player); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)a_Reason); - } - } - return 2; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'OnDisconnect'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: OnBlockPlace of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnBlockPlace00 -static int tolua_AllToLua_cPlugin_OnBlockPlace00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPacket_BlockPlace",0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - cPacket_BlockPlace* a_PacketData = ((cPacket_BlockPlace*) tolua_tousertype(tolua_S,2,0)); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnBlockPlace'", NULL); -#endif - { - bool tolua_ret = (bool) self->OnBlockPlace(a_PacketData,a_Player); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'OnBlockPlace'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: OnBlockDig of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnBlockDig00 -static int tolua_AllToLua_cPlugin_OnBlockDig00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPacket_BlockDig",0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || - !tolua_isusertype(tolua_S,4,"cItem",0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - cPacket_BlockDig* a_PacketData = ((cPacket_BlockDig*) tolua_tousertype(tolua_S,2,0)); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); - cItem* a_PickupItem = ((cItem*) tolua_tousertype(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnBlockDig'", NULL); -#endif - { - bool tolua_ret = (bool) self->OnBlockDig(a_PacketData,a_Player,a_PickupItem); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'OnBlockDig'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: OnChat of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnChat00 -static int tolua_AllToLua_cPlugin_OnChat00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - const char* a_Chat = ((const char*) tolua_tostring(tolua_S,2,0)); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnChat'", NULL); -#endif - { - bool tolua_ret = (bool) self->OnChat(a_Chat,a_Player); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'OnChat'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: OnLogin of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnLogin00 -static int tolua_AllToLua_cPlugin_OnLogin00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPacket_Login",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - cPacket_Login* a_PacketData = ((cPacket_Login*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnLogin'", NULL); -#endif - { - bool tolua_ret = (bool) self->OnLogin(a_PacketData); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'OnLogin'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: OnPlayerSpawn of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnPlayerSpawn00 -static int tolua_AllToLua_cPlugin_OnPlayerSpawn00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnPlayerSpawn'", NULL); -#endif - { - self->OnPlayerSpawn(a_Player); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'OnPlayerSpawn'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: OnPlayerJoin of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnPlayerJoin00 -static int tolua_AllToLua_cPlugin_OnPlayerJoin00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnPlayerJoin'", NULL); -#endif - { - bool tolua_ret = (bool) self->OnPlayerJoin(a_Player); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'OnPlayerJoin'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: OnPlayerMove of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnPlayerMove00 -static int tolua_AllToLua_cPlugin_OnPlayerMove00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnPlayerMove'", NULL); -#endif - { - self->OnPlayerMove(a_Player); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'OnPlayerMove'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: OnTakeDamage of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnTakeDamage00 -static int tolua_AllToLua_cPlugin_OnTakeDamage00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPawn",0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"TakeDamageInfo",0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - cPawn* a_Pawn = ((cPawn*) tolua_tousertype(tolua_S,2,0)); - TakeDamageInfo* a_TakeDamageInfo = ((TakeDamageInfo*) tolua_tousertype(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnTakeDamage'", NULL); -#endif - { - self->OnTakeDamage(a_Pawn,a_TakeDamageInfo); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'OnTakeDamage'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: OnKilled of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnKilled00 -static int tolua_AllToLua_cPlugin_OnKilled00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPawn",0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - cPawn* a_Killed = ((cPawn*) tolua_tousertype(tolua_S,2,0)); - cEntity* a_Killer = ((cEntity*) tolua_tousertype(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnKilled'", NULL); -#endif - { - bool tolua_ret = (bool) self->OnKilled(a_Killed,a_Killer); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'OnKilled'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: OnChunkGenerated of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnChunkGenerated00 -static int tolua_AllToLua_cPlugin_OnChunkGenerated00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); - int a_ChunkX = ((int) tolua_tonumber(tolua_S,3,0)); - int a_ChunkZ = ((int) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnChunkGenerated'", NULL); -#endif - { - self->OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'OnChunkGenerated'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: OnChunkGenerating of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnChunkGenerating00 -static int tolua_AllToLua_cPlugin_OnChunkGenerating00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isusertype(tolua_S,4,"cLuaChunk",0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - int a_ChunkX = ((int) tolua_tonumber(tolua_S,2,0)); - int a_ChunkZ = ((int) tolua_tonumber(tolua_S,3,0)); - cLuaChunk* a_pLuaChunk = ((cLuaChunk*) tolua_tousertype(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnChunkGenerating'", NULL); -#endif - { - bool tolua_ret = (bool) self->OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'OnChunkGenerating'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: OnPreCrafting of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnPreCrafting00 -static int tolua_AllToLua_cPlugin_OnPreCrafting00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) || - !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0)); - const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0)); - cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnPreCrafting'", NULL); -#endif - { - bool tolua_ret = (bool) self->OnPreCrafting(a_Player,a_Grid,a_Recipe); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'OnPreCrafting'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: OnCraftingNoRecipe of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnCraftingNoRecipe00 -static int tolua_AllToLua_cPlugin_OnCraftingNoRecipe00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) || - !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0)); - const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0)); - cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnCraftingNoRecipe'", NULL); -#endif - { - bool tolua_ret = (bool) self->OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'OnCraftingNoRecipe'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: OnPostCrafting of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnPostCrafting00 -static int tolua_AllToLua_cPlugin_OnPostCrafting00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) || - !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0)); - const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0)); - cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnPostCrafting'", NULL); -#endif - { - bool tolua_ret = (bool) self->OnPostCrafting(a_Player,a_Grid,a_Recipe); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'OnPostCrafting'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: OnBlockToPickup of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnBlockToPickup00 -static int tolua_AllToLua_cPlugin_OnBlockToPickup00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"BLOCKTYPE",0,&tolua_err)) || - (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"NIBBLETYPE",0,&tolua_err)) || - !tolua_isusertype(tolua_S,4,"const cPlayer",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"const cItem",0,&tolua_err)) || - (tolua_isvaluenil(tolua_S,6,&tolua_err) || !tolua_isusertype(tolua_S,6,"cItems",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,7,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - BLOCKTYPE a_BlockType = *((BLOCKTYPE*) tolua_tousertype(tolua_S,2,0)); - NIBBLETYPE a_BlockMeta = *((NIBBLETYPE*) tolua_tousertype(tolua_S,3,0)); - const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,4,0)); - const cItem* a_EquippedItem = ((const cItem*) tolua_tousertype(tolua_S,5,0)); - cItems* a_Pickups = ((cItems*) tolua_tousertype(tolua_S,6,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnBlockToPickup'", NULL); -#endif - { - bool tolua_ret = (bool) self->OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,*a_EquippedItem,*a_Pickups); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'OnBlockToPickup'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetName of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_GetName00 -static int tolua_AllToLua_cPlugin_GetName00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cPlugin",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cPlugin* self = (const cPlugin*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL); -#endif - { - const char* tolua_ret = (const char*) self->GetName(); - tolua_pushstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetName'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetName of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_SetName00 -static int tolua_AllToLua_cPlugin_SetName00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - const char* a_Name = ((const char*) tolua_tostring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetName'", NULL); -#endif - { - self->SetName(a_Name); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetName'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetVersion of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_GetVersion00 -static int tolua_AllToLua_cPlugin_GetVersion00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cPlugin",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cPlugin* self = (const cPlugin*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetVersion'", NULL); -#endif - { - int tolua_ret = (int) self->GetVersion(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetVersion'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetVersion of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_SetVersion00 -static int tolua_AllToLua_cPlugin_SetVersion00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - int a_Version = ((int) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetVersion'", NULL); -#endif - { - self->SetVersion(a_Version); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetVersion'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Command of class CommandStruct */ -#ifndef TOLUA_DISABLE_tolua_get_cPlugin__CommandStruct_Command -static int tolua_get_cPlugin__CommandStruct_Command(lua_State* tolua_S) -{ - cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Command'",NULL); -#endif - tolua_pushcppstring(tolua_S,(const char*)self->Command); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: Command of class CommandStruct */ -#ifndef TOLUA_DISABLE_tolua_set_cPlugin__CommandStruct_Command -static int tolua_set_cPlugin__CommandStruct_Command(lua_State* tolua_S) -{ - cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Command'",NULL); - if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->Command = ((std::string) tolua_tocppstring(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Description of class CommandStruct */ -#ifndef TOLUA_DISABLE_tolua_get_cPlugin__CommandStruct_Description -static int tolua_get_cPlugin__CommandStruct_Description(lua_State* tolua_S) -{ - cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Description'",NULL); -#endif - tolua_pushcppstring(tolua_S,(const char*)self->Description); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: Description of class CommandStruct */ -#ifndef TOLUA_DISABLE_tolua_set_cPlugin__CommandStruct_Description -static int tolua_set_cPlugin__CommandStruct_Description(lua_State* tolua_S) -{ - cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Description'",NULL); - if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->Description = ((std::string) tolua_tocppstring(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Permission of class CommandStruct */ -#ifndef TOLUA_DISABLE_tolua_get_cPlugin__CommandStruct_Permission -static int tolua_get_cPlugin__CommandStruct_Permission(lua_State* tolua_S) -{ - cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Permission'",NULL); -#endif - tolua_pushcppstring(tolua_S,(const char*)self->Permission); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: Permission of class CommandStruct */ -#ifndef TOLUA_DISABLE_tolua_set_cPlugin__CommandStruct_Permission -static int tolua_set_cPlugin__CommandStruct_Permission(lua_State* tolua_S) -{ - cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Permission'",NULL); - if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->Permission = ((std::string) tolua_tocppstring(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* method: AddCommand of class cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_AddCommand00 -static int tolua_AllToLua_cPlugin_AddCommand00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_iscppstring(tolua_S,3,0,&tolua_err) || - !tolua_iscppstring(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - std::string a_Command = ((std::string) tolua_tocppstring(tolua_S,2,0)); - std::string a_Description = ((std::string) tolua_tocppstring(tolua_S,3,0)); - std::string a_Permission = ((std::string) tolua_tocppstring(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddCommand'", NULL); -#endif - { - self->AddCommand(a_Command,a_Description,a_Permission); - tolua_pushcppstring(tolua_S,(const char*)a_Command); - tolua_pushcppstring(tolua_S,(const char*)a_Description); - tolua_pushcppstring(tolua_S,(const char*)a_Permission); - } - } - return 3; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'AddCommand'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - - class Lua__cPlugin : public cPlugin, public ToluaBase { -public: - void OnDisable( void ) { - if (push_method("OnDisable", tolua_AllToLua_cPlugin_OnDisable00)) { - ToluaBase::dbcall(lua_state, 1, 0); - } else { - return ( void ) cPlugin:: OnDisable(); - }; - }; - bool Initialize( void ) { - if (push_method("Initialize", tolua_AllToLua_cPlugin_Initialize00)) { - ToluaBase::dbcall(lua_state, 1, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - if (lua_state) - LOG("pure-virtual method cPlugin::Initialize not implemented."); - else { - LOG("pure-virtual method cPlugin::Initialize called with no lua_state. Aborting"); - ::abort(); - }; - return ( bool )0; - }; - }; - void Tick( float a_Dt) { - if (push_method("Tick", tolua_AllToLua_cPlugin_Tick00)) { - tolua_pushnumber(lua_state, (lua_Number)a_Dt); - ToluaBase::dbcall(lua_state, 2, 0); - } else { - return ( void ) cPlugin:: Tick(a_Dt); - }; - }; - bool OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player) { - if (push_method("OnCollectItem", tolua_AllToLua_cPlugin_OnCollectItem00)) { - tolua_pushusertype(lua_state, (void*)a_Pickup, "cPickup"); - tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); - ToluaBase::dbcall(lua_state, 3, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin:: OnCollectItem(a_Pickup,a_Player); - }; - }; - bool OnDisconnect( const AString& a_Reason, cPlayer* a_Player) { - if (push_method("OnDisconnect", tolua_AllToLua_cPlugin_OnDisconnect00)) { - tolua_pushcppstring(lua_state, (const char*)a_Reason); - tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); - ToluaBase::dbcall(lua_state, 3, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin:: OnDisconnect(a_Reason,a_Player); - }; - }; - bool OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player) { - if (push_method("OnBlockPlace", tolua_AllToLua_cPlugin_OnBlockPlace00)) { - tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_BlockPlace"); - tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); - ToluaBase::dbcall(lua_state, 3, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin:: OnBlockPlace(a_PacketData,a_Player); - }; - }; - bool OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem) { - if (push_method("OnBlockDig", tolua_AllToLua_cPlugin_OnBlockDig00)) { - tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_BlockDig"); - tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); - tolua_pushusertype(lua_state, (void*)a_PickupItem, "cItem"); - ToluaBase::dbcall(lua_state, 4, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin:: OnBlockDig(a_PacketData,a_Player,a_PickupItem); - }; - }; - bool OnChat( const char* a_Chat, cPlayer* a_Player) { - if (push_method("OnChat", tolua_AllToLua_cPlugin_OnChat00)) { - tolua_pushstring(lua_state, (const char*)a_Chat); - tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); - ToluaBase::dbcall(lua_state, 3, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin:: OnChat(a_Chat,a_Player); - }; - }; - bool OnLogin( cPacket_Login* a_PacketData) { - if (push_method("OnLogin", tolua_AllToLua_cPlugin_OnLogin00)) { - tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_Login"); - ToluaBase::dbcall(lua_state, 2, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin:: OnLogin(a_PacketData); - }; - }; - void OnPlayerSpawn( cPlayer* a_Player) { - if (push_method("OnPlayerSpawn", tolua_AllToLua_cPlugin_OnPlayerSpawn00)) { - tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); - ToluaBase::dbcall(lua_state, 2, 0); - } else { - return ( void ) cPlugin:: OnPlayerSpawn(a_Player); - }; - }; - bool OnPlayerJoin( cPlayer* a_Player) { - if (push_method("OnPlayerJoin", tolua_AllToLua_cPlugin_OnPlayerJoin00)) { - tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); - ToluaBase::dbcall(lua_state, 2, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin:: OnPlayerJoin(a_Player); - }; - }; - void OnPlayerMove( cPlayer* a_Player) { - if (push_method("OnPlayerMove", tolua_AllToLua_cPlugin_OnPlayerMove00)) { - tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); - ToluaBase::dbcall(lua_state, 2, 0); - } else { - return ( void ) cPlugin:: OnPlayerMove(a_Player); - }; - }; - void OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo) { - if (push_method("OnTakeDamage", tolua_AllToLua_cPlugin_OnTakeDamage00)) { - tolua_pushusertype(lua_state, (void*)a_Pawn, "cPawn"); - tolua_pushusertype(lua_state, (void*)a_TakeDamageInfo, "TakeDamageInfo"); - ToluaBase::dbcall(lua_state, 3, 0); - } else { - return ( void ) cPlugin:: OnTakeDamage(a_Pawn,a_TakeDamageInfo); - }; - }; - bool OnKilled( cPawn* a_Killed, cEntity* a_Killer) { - if (push_method("OnKilled", tolua_AllToLua_cPlugin_OnKilled00)) { - tolua_pushusertype(lua_state, (void*)a_Killed, "cPawn"); - tolua_pushusertype(lua_state, (void*)a_Killer, "cEntity"); - ToluaBase::dbcall(lua_state, 3, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin:: OnKilled(a_Killed,a_Killer); - }; - }; - void OnChunkGenerated( cWorld* a_World, int a_ChunkX, int a_ChunkZ) { - if (push_method("OnChunkGenerated", tolua_AllToLua_cPlugin_OnChunkGenerated00)) { - tolua_pushusertype(lua_state, (void*)a_World, "cWorld"); - tolua_pushnumber(lua_state, (lua_Number)a_ChunkX); - tolua_pushnumber(lua_state, (lua_Number)a_ChunkZ); - ToluaBase::dbcall(lua_state, 4, 0); - } else { - return ( void ) cPlugin:: OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ); - }; - }; - bool OnChunkGenerating( int a_ChunkX, int a_ChunkZ, cLuaChunk* a_pLuaChunk) { - if (push_method("OnChunkGenerating", tolua_AllToLua_cPlugin_OnChunkGenerating00)) { - tolua_pushnumber(lua_state, (lua_Number)a_ChunkX); - tolua_pushnumber(lua_state, (lua_Number)a_ChunkZ); - tolua_pushusertype(lua_state, (void*)a_pLuaChunk, "cLuaChunk"); - ToluaBase::dbcall(lua_state, 4, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin:: OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk); - }; - }; - bool OnPreCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { - if (push_method("OnPreCrafting", tolua_AllToLua_cPlugin_OnPreCrafting00)) { - tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); - tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid"); - tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe"); - ToluaBase::dbcall(lua_state, 4, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin:: OnPreCrafting(a_Player,a_Grid,a_Recipe); - }; - }; - bool OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { - if (push_method("OnCraftingNoRecipe", tolua_AllToLua_cPlugin_OnCraftingNoRecipe00)) { - tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); - tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid"); - tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe"); - ToluaBase::dbcall(lua_state, 4, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin:: OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); - }; - }; - bool OnPostCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { - if (push_method("OnPostCrafting", tolua_AllToLua_cPlugin_OnPostCrafting00)) { - tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); - tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid"); - tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe"); - ToluaBase::dbcall(lua_state, 4, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin:: OnPostCrafting(a_Player,a_Grid,a_Recipe); - }; - }; - bool OnBlockToPickup( BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer* a_Player, const cItem& a_EquippedItem, cItems& a_Pickups) { - if (push_method("OnBlockToPickup", tolua_AllToLua_cPlugin_OnBlockToPickup00)) { - void* tolua_obj0 = (void*)new BLOCKTYPE(a_BlockType); - tolua_pushusertype_and_takeownership(lua_state, tolua_obj0, "BLOCKTYPE"); - void* tolua_obj1 = (void*)new NIBBLETYPE(a_BlockMeta); - tolua_pushusertype_and_takeownership(lua_state, tolua_obj1, "NIBBLETYPE"); - tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); - tolua_pushusertype(lua_state, (void*)&a_EquippedItem, "const cItem"); - tolua_pushusertype(lua_state, (void*)&a_Pickups, "cItems"); - ToluaBase::dbcall(lua_state, 6, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin:: OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,a_EquippedItem,a_Pickups); - }; - }; - - void cPlugin__OnDisable( void ) { - return ( void )cPlugin::OnDisable(); - }; - void cPlugin__Tick( float a_Dt) { - return ( void )cPlugin::Tick(a_Dt); - }; - bool cPlugin__OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player) { - return ( bool )cPlugin::OnCollectItem(a_Pickup,a_Player); - }; - bool cPlugin__OnDisconnect( const AString& a_Reason, cPlayer* a_Player) { - return ( bool )cPlugin::OnDisconnect(a_Reason,a_Player); - }; - bool cPlugin__OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player) { - return ( bool )cPlugin::OnBlockPlace(a_PacketData,a_Player); - }; - bool cPlugin__OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem) { - return ( bool )cPlugin::OnBlockDig(a_PacketData,a_Player,a_PickupItem); - }; - bool cPlugin__OnChat( const char* a_Chat, cPlayer* a_Player) { - return ( bool )cPlugin::OnChat(a_Chat,a_Player); - }; - bool cPlugin__OnLogin( cPacket_Login* a_PacketData) { - return ( bool )cPlugin::OnLogin(a_PacketData); - }; - void cPlugin__OnPlayerSpawn( cPlayer* a_Player) { - return ( void )cPlugin::OnPlayerSpawn(a_Player); - }; - bool cPlugin__OnPlayerJoin( cPlayer* a_Player) { - return ( bool )cPlugin::OnPlayerJoin(a_Player); - }; - void cPlugin__OnPlayerMove( cPlayer* a_Player) { - return ( void )cPlugin::OnPlayerMove(a_Player); - }; - void cPlugin__OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo) { - return ( void )cPlugin::OnTakeDamage(a_Pawn,a_TakeDamageInfo); - }; - bool cPlugin__OnKilled( cPawn* a_Killed, cEntity* a_Killer) { - return ( bool )cPlugin::OnKilled(a_Killed,a_Killer); - }; - void cPlugin__OnChunkGenerated( cWorld* a_World, int a_ChunkX, int a_ChunkZ) { - return ( void )cPlugin::OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ); - }; - bool cPlugin__OnChunkGenerating( int a_ChunkX, int a_ChunkZ, cLuaChunk* a_pLuaChunk) { - return ( bool )cPlugin::OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk); - }; - bool cPlugin__OnPreCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { - return ( bool )cPlugin::OnPreCrafting(a_Player,a_Grid,a_Recipe); - }; - bool cPlugin__OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { - return ( bool )cPlugin::OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); - }; - bool cPlugin__OnPostCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { - return ( bool )cPlugin::OnPostCrafting(a_Player,a_Grid,a_Recipe); - }; - bool cPlugin__OnBlockToPickup( BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer* a_Player, const cItem& a_EquippedItem, cItems& a_Pickups) { - return ( bool )cPlugin::OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,a_EquippedItem,a_Pickups); - }; - Lua__cPlugin( void ): cPlugin(){}; -}; - -/* method: tolua__set_instance of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_tolua__set_instance00 -static int tolua_AllToLua_Lua__cPlugin_tolua__set_instance00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - lua_State* L = tolua_S; - lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); -#endif - { - self->tolua__set_instance(L,lo); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin__OnDisable of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisable00 -static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisable00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnDisable'", NULL); -#endif - { - self->cPlugin__OnDisable(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin__OnDisable'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin__Tick of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__Tick00 -static int tolua_AllToLua_Lua__cPlugin_cPlugin__Tick00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - float a_Dt = ((float) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__Tick'", NULL); -#endif - { - self->cPlugin__Tick(a_Dt); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin__Tick'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin__OnCollectItem of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnCollectItem00 -static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnCollectItem00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPickup",0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - cPickup* a_Pickup = ((cPickup*) tolua_tousertype(tolua_S,2,0)); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnCollectItem'", NULL); -#endif - { - bool tolua_ret = (bool) self->cPlugin__OnCollectItem(a_Pickup,a_Player); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin__OnCollectItem'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin__OnDisconnect of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisconnect00 -static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisconnect00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,2,0)); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnDisconnect'", NULL); -#endif - { - bool tolua_ret = (bool) self->cPlugin__OnDisconnect(a_Reason,a_Player); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)a_Reason); - } - } - return 2; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin__OnDisconnect'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin__OnBlockPlace of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockPlace00 -static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockPlace00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPacket_BlockPlace",0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - cPacket_BlockPlace* a_PacketData = ((cPacket_BlockPlace*) tolua_tousertype(tolua_S,2,0)); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnBlockPlace'", NULL); -#endif - { - bool tolua_ret = (bool) self->cPlugin__OnBlockPlace(a_PacketData,a_Player); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin__OnBlockPlace'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin__OnBlockDig of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockDig00 -static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockDig00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPacket_BlockDig",0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || - !tolua_isusertype(tolua_S,4,"cItem",0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - cPacket_BlockDig* a_PacketData = ((cPacket_BlockDig*) tolua_tousertype(tolua_S,2,0)); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); - cItem* a_PickupItem = ((cItem*) tolua_tousertype(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnBlockDig'", NULL); -#endif - { - bool tolua_ret = (bool) self->cPlugin__OnBlockDig(a_PacketData,a_Player,a_PickupItem); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin__OnBlockDig'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin__OnChat of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnChat00 -static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnChat00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - const char* a_Chat = ((const char*) tolua_tostring(tolua_S,2,0)); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnChat'", NULL); -#endif - { - bool tolua_ret = (bool) self->cPlugin__OnChat(a_Chat,a_Player); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin__OnChat'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin__OnLogin of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnLogin00 -static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnLogin00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPacket_Login",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - cPacket_Login* a_PacketData = ((cPacket_Login*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnLogin'", NULL); -#endif - { - bool tolua_ret = (bool) self->cPlugin__OnLogin(a_PacketData); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin__OnLogin'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin__OnPlayerSpawn of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerSpawn00 -static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerSpawn00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnPlayerSpawn'", NULL); -#endif - { - self->cPlugin__OnPlayerSpawn(a_Player); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin__OnPlayerSpawn'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin__OnPlayerJoin of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerJoin00 -static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerJoin00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnPlayerJoin'", NULL); -#endif - { - bool tolua_ret = (bool) self->cPlugin__OnPlayerJoin(a_Player); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin__OnPlayerJoin'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin__OnPlayerMove of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerMove00 -static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerMove00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnPlayerMove'", NULL); -#endif - { - self->cPlugin__OnPlayerMove(a_Player); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin__OnPlayerMove'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin__OnTakeDamage of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnTakeDamage00 -static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnTakeDamage00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPawn",0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"TakeDamageInfo",0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - cPawn* a_Pawn = ((cPawn*) tolua_tousertype(tolua_S,2,0)); - TakeDamageInfo* a_TakeDamageInfo = ((TakeDamageInfo*) tolua_tousertype(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnTakeDamage'", NULL); -#endif - { - self->cPlugin__OnTakeDamage(a_Pawn,a_TakeDamageInfo); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin__OnTakeDamage'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin__OnKilled of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnKilled00 -static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnKilled00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPawn",0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - cPawn* a_Killed = ((cPawn*) tolua_tousertype(tolua_S,2,0)); - cEntity* a_Killer = ((cEntity*) tolua_tousertype(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnKilled'", NULL); -#endif - { - bool tolua_ret = (bool) self->cPlugin__OnKilled(a_Killed,a_Killer); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin__OnKilled'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin__OnChunkGenerated of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerated00 -static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerated00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); - int a_ChunkX = ((int) tolua_tonumber(tolua_S,3,0)); - int a_ChunkZ = ((int) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnChunkGenerated'", NULL); -#endif - { - self->cPlugin__OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin__OnChunkGenerated'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin__OnChunkGenerating of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerating00 -static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerating00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isusertype(tolua_S,4,"cLuaChunk",0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - int a_ChunkX = ((int) tolua_tonumber(tolua_S,2,0)); - int a_ChunkZ = ((int) tolua_tonumber(tolua_S,3,0)); - cLuaChunk* a_pLuaChunk = ((cLuaChunk*) tolua_tousertype(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnChunkGenerating'", NULL); -#endif - { - bool tolua_ret = (bool) self->cPlugin__OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin__OnChunkGenerating'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin__OnPreCrafting of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnPreCrafting00 -static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnPreCrafting00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) || - !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0)); - const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0)); - cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnPreCrafting'", NULL); -#endif - { - bool tolua_ret = (bool) self->cPlugin__OnPreCrafting(a_Player,a_Grid,a_Recipe); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin__OnPreCrafting'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin__OnCraftingNoRecipe of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnCraftingNoRecipe00 -static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnCraftingNoRecipe00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) || - !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0)); - const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0)); - cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnCraftingNoRecipe'", NULL); -#endif - { - bool tolua_ret = (bool) self->cPlugin__OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin__OnCraftingNoRecipe'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin__OnPostCrafting of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnPostCrafting00 -static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnPostCrafting00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) || - !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0)); - const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0)); - cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnPostCrafting'", NULL); -#endif - { - bool tolua_ret = (bool) self->cPlugin__OnPostCrafting(a_Player,a_Grid,a_Recipe); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin__OnPostCrafting'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin__OnBlockToPickup of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockToPickup00 -static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockToPickup00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"BLOCKTYPE",0,&tolua_err)) || - (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"NIBBLETYPE",0,&tolua_err)) || - !tolua_isusertype(tolua_S,4,"const cPlayer",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"const cItem",0,&tolua_err)) || - (tolua_isvaluenil(tolua_S,6,&tolua_err) || !tolua_isusertype(tolua_S,6,"cItems",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,7,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - BLOCKTYPE a_BlockType = *((BLOCKTYPE*) tolua_tousertype(tolua_S,2,0)); - NIBBLETYPE a_BlockMeta = *((NIBBLETYPE*) tolua_tousertype(tolua_S,3,0)); - const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,4,0)); - const cItem* a_EquippedItem = ((const cItem*) tolua_tousertype(tolua_S,5,0)); - cItems* a_Pickups = ((cItems*) tolua_tousertype(tolua_S,6,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnBlockToPickup'", NULL); -#endif - { - bool tolua_ret = (bool) self->cPlugin__OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,*a_EquippedItem,*a_Pickups); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin__OnBlockToPickup'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_new00 -static int tolua_AllToLua_Lua__cPlugin_new00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - { - Lua__cPlugin* tolua_ret = (Lua__cPlugin*) Mtolua_new((Lua__cPlugin)()); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPlugin"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_new00_local -static int tolua_AllToLua_Lua__cPlugin_new00_local(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - { - Lua__cPlugin* tolua_ret = (Lua__cPlugin*) Mtolua_new((Lua__cPlugin)()); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPlugin"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: delete of class Lua__cPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_delete00 -static int tolua_AllToLua_Lua__cPlugin_delete00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); -#endif - Mtolua_delete(self); - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - - -/* function to release collected object via destructor */ -#ifdef __cplusplus - -static int tolua_collect_Lua__cPlugin (lua_State* tolua_S) -{ - Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - delete self; - return 0; -} -#endif - -/* method: OnDisable of class cPlugin_NewLua */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_NewLua_OnDisable00 -static int tolua_AllToLua_cPlugin_NewLua_OnDisable00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin_NewLua",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin_NewLua* self = (cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnDisable'", NULL); -#endif - { - self->OnDisable(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'OnDisable'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Initialize of class cPlugin_NewLua */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_NewLua_Initialize00 -static int tolua_AllToLua_cPlugin_NewLua_Initialize00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin_NewLua",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin_NewLua* self = (cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL); -#endif - { - bool tolua_ret = (bool) self->Initialize(); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Tick of class cPlugin_NewLua */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_NewLua_Tick00 -static int tolua_AllToLua_cPlugin_NewLua_Tick00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin_NewLua",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin_NewLua* self = (cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); - float a_Dt = ((float) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Tick'", NULL); -#endif - { - self->Tick(a_Dt); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Tick'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: CreateWebPlugin of class cPlugin_NewLua */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_NewLua_CreateWebPlugin00 -static int tolua_AllToLua_cPlugin_NewLua_CreateWebPlugin00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin_NewLua",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin_NewLua* self = (cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); - lua_State* a_LuaState = tolua_S; -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CreateWebPlugin'", NULL); -#endif - { - cWebPlugin_Lua* tolua_ret = (cWebPlugin_Lua*) self->CreateWebPlugin(a_LuaState); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWebPlugin_Lua"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'CreateWebPlugin'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - - class Lua__cPlugin_NewLua : public cPlugin_NewLua, public ToluaBase { -public: - void OnDisable( void ) { - if (push_method("OnDisable", tolua_AllToLua_cPlugin_NewLua_OnDisable00)) { - ToluaBase::dbcall(lua_state, 1, 0); - } else { - return ( void ) cPlugin_NewLua:: OnDisable(); - }; - }; - bool Initialize( void ) { - if (push_method("Initialize", tolua_AllToLua_cPlugin_NewLua_Initialize00)) { - ToluaBase::dbcall(lua_state, 1, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin_NewLua:: Initialize(); - }; - }; - void Tick( float a_Dt) { - if (push_method("Tick", tolua_AllToLua_cPlugin_NewLua_Tick00)) { - tolua_pushnumber(lua_state, (lua_Number)a_Dt); - ToluaBase::dbcall(lua_state, 2, 0); - } else { - return ( void ) cPlugin_NewLua:: Tick(a_Dt); - }; - }; - bool OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player) { - if (push_method("OnCollectItem", tolua_AllToLua_cPlugin_OnCollectItem00)) { - tolua_pushusertype(lua_state, (void*)a_Pickup, "cPickup"); - tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); - ToluaBase::dbcall(lua_state, 3, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin_NewLua:: OnCollectItem(a_Pickup,a_Player); - }; - }; - bool OnDisconnect( const AString& a_Reason, cPlayer* a_Player) { - if (push_method("OnDisconnect", tolua_AllToLua_cPlugin_OnDisconnect00)) { - tolua_pushcppstring(lua_state, (const char*)a_Reason); - tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); - ToluaBase::dbcall(lua_state, 3, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin_NewLua:: OnDisconnect(a_Reason,a_Player); - }; - }; - bool OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player) { - if (push_method("OnBlockPlace", tolua_AllToLua_cPlugin_OnBlockPlace00)) { - tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_BlockPlace"); - tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); - ToluaBase::dbcall(lua_state, 3, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin_NewLua:: OnBlockPlace(a_PacketData,a_Player); - }; - }; - bool OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem) { - if (push_method("OnBlockDig", tolua_AllToLua_cPlugin_OnBlockDig00)) { - tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_BlockDig"); - tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); - tolua_pushusertype(lua_state, (void*)a_PickupItem, "cItem"); - ToluaBase::dbcall(lua_state, 4, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin_NewLua:: OnBlockDig(a_PacketData,a_Player,a_PickupItem); - }; - }; - bool OnChat( const char* a_Chat, cPlayer* a_Player) { - if (push_method("OnChat", tolua_AllToLua_cPlugin_OnChat00)) { - tolua_pushstring(lua_state, (const char*)a_Chat); - tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); - ToluaBase::dbcall(lua_state, 3, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin_NewLua:: OnChat(a_Chat,a_Player); - }; - }; - bool OnLogin( cPacket_Login* a_PacketData) { - if (push_method("OnLogin", tolua_AllToLua_cPlugin_OnLogin00)) { - tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_Login"); - ToluaBase::dbcall(lua_state, 2, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin_NewLua:: OnLogin(a_PacketData); - }; - }; - void OnPlayerSpawn( cPlayer* a_Player) { - if (push_method("OnPlayerSpawn", tolua_AllToLua_cPlugin_OnPlayerSpawn00)) { - tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); - ToluaBase::dbcall(lua_state, 2, 0); - } else { - return ( void ) cPlugin_NewLua:: OnPlayerSpawn(a_Player); - }; - }; - bool OnPlayerJoin( cPlayer* a_Player) { - if (push_method("OnPlayerJoin", tolua_AllToLua_cPlugin_OnPlayerJoin00)) { - tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); - ToluaBase::dbcall(lua_state, 2, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin_NewLua:: OnPlayerJoin(a_Player); - }; - }; - void OnPlayerMove( cPlayer* a_Player) { - if (push_method("OnPlayerMove", tolua_AllToLua_cPlugin_OnPlayerMove00)) { - tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); - ToluaBase::dbcall(lua_state, 2, 0); - } else { - return ( void ) cPlugin_NewLua:: OnPlayerMove(a_Player); - }; - }; - void OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo) { - if (push_method("OnTakeDamage", tolua_AllToLua_cPlugin_OnTakeDamage00)) { - tolua_pushusertype(lua_state, (void*)a_Pawn, "cPawn"); - tolua_pushusertype(lua_state, (void*)a_TakeDamageInfo, "TakeDamageInfo"); - ToluaBase::dbcall(lua_state, 3, 0); - } else { - return ( void ) cPlugin_NewLua:: OnTakeDamage(a_Pawn,a_TakeDamageInfo); - }; - }; - bool OnKilled( cPawn* a_Killed, cEntity* a_Killer) { - if (push_method("OnKilled", tolua_AllToLua_cPlugin_OnKilled00)) { - tolua_pushusertype(lua_state, (void*)a_Killed, "cPawn"); - tolua_pushusertype(lua_state, (void*)a_Killer, "cEntity"); - ToluaBase::dbcall(lua_state, 3, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin_NewLua:: OnKilled(a_Killed,a_Killer); - }; - }; - void OnChunkGenerated( cWorld* a_World, int a_ChunkX, int a_ChunkZ) { - if (push_method("OnChunkGenerated", tolua_AllToLua_cPlugin_OnChunkGenerated00)) { - tolua_pushusertype(lua_state, (void*)a_World, "cWorld"); - tolua_pushnumber(lua_state, (lua_Number)a_ChunkX); - tolua_pushnumber(lua_state, (lua_Number)a_ChunkZ); - ToluaBase::dbcall(lua_state, 4, 0); - } else { - return ( void ) cPlugin_NewLua:: OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ); - }; - }; - bool OnChunkGenerating( int a_ChunkX, int a_ChunkZ, cLuaChunk* a_pLuaChunk) { - if (push_method("OnChunkGenerating", tolua_AllToLua_cPlugin_OnChunkGenerating00)) { - tolua_pushnumber(lua_state, (lua_Number)a_ChunkX); - tolua_pushnumber(lua_state, (lua_Number)a_ChunkZ); - tolua_pushusertype(lua_state, (void*)a_pLuaChunk, "cLuaChunk"); - ToluaBase::dbcall(lua_state, 4, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin_NewLua:: OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk); - }; - }; - bool OnPreCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { - if (push_method("OnPreCrafting", tolua_AllToLua_cPlugin_OnPreCrafting00)) { - tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); - tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid"); - tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe"); - ToluaBase::dbcall(lua_state, 4, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin_NewLua:: OnPreCrafting(a_Player,a_Grid,a_Recipe); - }; - }; - bool OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { - if (push_method("OnCraftingNoRecipe", tolua_AllToLua_cPlugin_OnCraftingNoRecipe00)) { - tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); - tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid"); - tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe"); - ToluaBase::dbcall(lua_state, 4, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin_NewLua:: OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); - }; - }; - bool OnPostCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { - if (push_method("OnPostCrafting", tolua_AllToLua_cPlugin_OnPostCrafting00)) { - tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); - tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid"); - tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe"); - ToluaBase::dbcall(lua_state, 4, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin_NewLua:: OnPostCrafting(a_Player,a_Grid,a_Recipe); - }; - }; - bool OnBlockToPickup( BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer* a_Player, const cItem& a_EquippedItem, cItems& a_Pickups) { - if (push_method("OnBlockToPickup", tolua_AllToLua_cPlugin_OnBlockToPickup00)) { - void* tolua_obj0 = (void*)new BLOCKTYPE(a_BlockType); - tolua_pushusertype_and_takeownership(lua_state, tolua_obj0, "BLOCKTYPE"); - void* tolua_obj1 = (void*)new NIBBLETYPE(a_BlockMeta); - tolua_pushusertype_and_takeownership(lua_state, tolua_obj1, "NIBBLETYPE"); - tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); - tolua_pushusertype(lua_state, (void*)&a_EquippedItem, "const cItem"); - tolua_pushusertype(lua_state, (void*)&a_Pickups, "cItems"); - ToluaBase::dbcall(lua_state, 6, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlugin_NewLua:: OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,a_EquippedItem,a_Pickups); - }; - }; - - void cPlugin_NewLua__OnDisable( void ) { - return ( void )cPlugin_NewLua::OnDisable(); - }; - bool cPlugin_NewLua__Initialize( void ) { - return ( bool )cPlugin_NewLua::Initialize(); - }; - void cPlugin_NewLua__Tick( float a_Dt) { - return ( void )cPlugin_NewLua::Tick(a_Dt); - }; - bool cPlugin_NewLua__OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player) { - return ( bool )cPlugin_NewLua::OnCollectItem(a_Pickup,a_Player); - }; - bool cPlugin_NewLua__OnDisconnect( const AString& a_Reason, cPlayer* a_Player) { - return ( bool )cPlugin_NewLua::OnDisconnect(a_Reason,a_Player); - }; - bool cPlugin_NewLua__OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player) { - return ( bool )cPlugin_NewLua::OnBlockPlace(a_PacketData,a_Player); - }; - bool cPlugin_NewLua__OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem) { - return ( bool )cPlugin_NewLua::OnBlockDig(a_PacketData,a_Player,a_PickupItem); - }; - bool cPlugin_NewLua__OnChat( const char* a_Chat, cPlayer* a_Player) { - return ( bool )cPlugin_NewLua::OnChat(a_Chat,a_Player); - }; - bool cPlugin_NewLua__OnLogin( cPacket_Login* a_PacketData) { - return ( bool )cPlugin_NewLua::OnLogin(a_PacketData); - }; - void cPlugin_NewLua__OnPlayerSpawn( cPlayer* a_Player) { - return ( void )cPlugin_NewLua::OnPlayerSpawn(a_Player); - }; - bool cPlugin_NewLua__OnPlayerJoin( cPlayer* a_Player) { - return ( bool )cPlugin_NewLua::OnPlayerJoin(a_Player); - }; - void cPlugin_NewLua__OnPlayerMove( cPlayer* a_Player) { - return ( void )cPlugin_NewLua::OnPlayerMove(a_Player); - }; - void cPlugin_NewLua__OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo) { - return ( void )cPlugin_NewLua::OnTakeDamage(a_Pawn,a_TakeDamageInfo); - }; - bool cPlugin_NewLua__OnKilled( cPawn* a_Killed, cEntity* a_Killer) { - return ( bool )cPlugin_NewLua::OnKilled(a_Killed,a_Killer); - }; - void cPlugin_NewLua__OnChunkGenerated( cWorld* a_World, int a_ChunkX, int a_ChunkZ) { - return ( void )cPlugin_NewLua::OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ); - }; - bool cPlugin_NewLua__OnChunkGenerating( int a_ChunkX, int a_ChunkZ, cLuaChunk* a_pLuaChunk) { - return ( bool )cPlugin_NewLua::OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk); - }; - bool cPlugin_NewLua__OnPreCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { - return ( bool )cPlugin_NewLua::OnPreCrafting(a_Player,a_Grid,a_Recipe); - }; - bool cPlugin_NewLua__OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { - return ( bool )cPlugin_NewLua::OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); - }; - bool cPlugin_NewLua__OnPostCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { - return ( bool )cPlugin_NewLua::OnPostCrafting(a_Player,a_Grid,a_Recipe); - }; - bool cPlugin_NewLua__OnBlockToPickup( BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer* a_Player, const cItem& a_EquippedItem, cItems& a_Pickups) { - return ( bool )cPlugin_NewLua::OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,a_EquippedItem,a_Pickups); - }; -}; - -/* method: tolua__set_instance of class Lua__cPlugin_NewLua */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_NewLua_tolua__set_instance00 -static int tolua_AllToLua_Lua__cPlugin_NewLua_tolua__set_instance00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin_NewLua",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin_NewLua* self = (Lua__cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); - lua_State* L = tolua_S; - lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); -#endif - { - self->tolua__set_instance(L,lo); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin_NewLua__OnDisable of class Lua__cPlugin_NewLua */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__OnDisable00 -static int tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__OnDisable00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin_NewLua",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin_NewLua* self = (Lua__cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin_NewLua__OnDisable'", NULL); -#endif - { - self->cPlugin_NewLua__OnDisable(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin_NewLua__OnDisable'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin_NewLua__Initialize of class Lua__cPlugin_NewLua */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Initialize00 -static int tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Initialize00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin_NewLua",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin_NewLua* self = (Lua__cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin_NewLua__Initialize'", NULL); -#endif - { - bool tolua_ret = (bool) self->cPlugin_NewLua__Initialize(); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin_NewLua__Initialize'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPlugin_NewLua__Tick of class Lua__cPlugin_NewLua */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Tick00 -static int tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Tick00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlugin_NewLua",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlugin_NewLua* self = (Lua__cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); - float a_Dt = ((float) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin_NewLua__Tick'", NULL); -#endif - { - self->cPlugin_NewLua__Tick(a_Dt); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlugin_NewLua__Tick'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetFileName of class cPlugin_Lua */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_Lua_GetFileName00 -static int tolua_AllToLua_cPlugin_Lua_GetFileName00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlugin_Lua",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlugin_Lua* self = (cPlugin_Lua*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetFileName'", NULL); -#endif - { - std::string tolua_ret = (std::string) self->GetFileName(); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetFileName'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetServer of class cServer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_GetServer00 -static int tolua_AllToLua_cServer_GetServer00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cServer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - { - cServer* tolua_ret = (cServer*) cServer::GetServer(); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cServer"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetServer'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: ServerCommand of class cServer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_ServerCommand00 -static int tolua_AllToLua_cServer_ServerCommand00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cServer",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cServer* self = (cServer*) tolua_tousertype(tolua_S,1,0); - const char* a_Cmd = ((const char*) tolua_tostring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ServerCommand'", NULL); -#endif - { - self->ServerCommand(a_Cmd); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'ServerCommand'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SendMessage of class cServer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_SendMessage00 -static int tolua_AllToLua_cServer_SendMessage00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cServer",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"cPlayer",1,&tolua_err) || - !tolua_isboolean(tolua_S,4,1,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cServer* self = (cServer*) tolua_tousertype(tolua_S,1,0); - const char* a_Message = ((const char*) tolua_tostring(tolua_S,2,0)); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); - bool a_bExclude = ((bool) tolua_toboolean(tolua_S,4,false)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendMessage'", NULL); -#endif - { - self->SendMessage(a_Message,a_Player,a_bExclude); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SendMessage'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetTime of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetTime00 -static int tolua_AllToLua_cWorld_GetTime00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - { - float tolua_ret = (float) cWorld::GetTime(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetTime'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetGameMode of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetGameMode00 -static int tolua_AllToLua_cWorld_GetGameMode00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetGameMode'", NULL); -#endif - { - eGameMode tolua_ret = (eGameMode) self->GetGameMode(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetGameMode'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetWorldTime of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetWorldTime00 -static int tolua_AllToLua_cWorld_SetWorldTime00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - long long a_WorldTime = ((long long) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetWorldTime'", NULL); -#endif - { - self->SetWorldTime(a_WorldTime); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetWorldTime'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetHeight of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetHeight00 -static int tolua_AllToLua_cWorld_GetHeight00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHeight'", NULL); -#endif - { - int tolua_ret = (int) self->GetHeight(a_X,a_Z); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetHeight'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: UnloadUnusedChunks of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_UnloadUnusedChunks00 -static int tolua_AllToLua_cWorld_UnloadUnusedChunks00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'UnloadUnusedChunks'", NULL); -#endif - { - self->UnloadUnusedChunks(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'UnloadUnusedChunks'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetMaxPlayers of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetMaxPlayers00 -static int tolua_AllToLua_cWorld_GetMaxPlayers00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxPlayers'", NULL); -#endif - { - unsigned int tolua_ret = (unsigned int) self->GetMaxPlayers(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetMaxPlayers'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetMaxPlayers of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetMaxPlayers00 -static int tolua_AllToLua_cWorld_SetMaxPlayers00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int iMax = ((int) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetMaxPlayers'", NULL); -#endif - { - self->SetMaxPlayers(iMax); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetMaxPlayers'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetNumPlayers of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetNumPlayers00 -static int tolua_AllToLua_cWorld_GetNumPlayers00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumPlayers'", NULL); -#endif - { - unsigned int tolua_ret = (unsigned int) self->GetNumPlayers(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetNumPlayers'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetPlayer of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetPlayer00 -static int tolua_AllToLua_cWorld_GetPlayer00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - const char* a_PlayerName = ((const char*) tolua_tostring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPlayer'", NULL); -#endif - { - cPlayer* tolua_ret = (cPlayer*) self->GetPlayer(a_PlayerName); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPlayer"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetPlayer'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: UpdateSign of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_UpdateSign00 -static int tolua_AllToLua_cWorld_UpdateSign00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_iscppstring(tolua_S,5,0,&tolua_err) || - !tolua_iscppstring(tolua_S,6,0,&tolua_err) || - !tolua_iscppstring(tolua_S,7,0,&tolua_err) || - !tolua_iscppstring(tolua_S,8,0,&tolua_err) || - !tolua_isnoobj(tolua_S,9,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); - const AString a_Line1 = ((const AString) tolua_tocppstring(tolua_S,5,0)); - const AString a_Line2 = ((const AString) tolua_tocppstring(tolua_S,6,0)); - const AString a_Line3 = ((const AString) tolua_tocppstring(tolua_S,7,0)); - const AString a_Line4 = ((const AString) tolua_tocppstring(tolua_S,8,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'UpdateSign'", NULL); -#endif - { - self->UpdateSign(a_X,a_Y,a_Z,a_Line1,a_Line2,a_Line3,a_Line4); - tolua_pushcppstring(tolua_S,(const char*)a_Line1); - tolua_pushcppstring(tolua_S,(const char*)a_Line2); - tolua_pushcppstring(tolua_S,(const char*)a_Line3); - tolua_pushcppstring(tolua_S,(const char*)a_Line4); - } - } - return 4; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'UpdateSign'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: RegenerateChunk of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_RegenerateChunk00 -static int tolua_AllToLua_cWorld_RegenerateChunk00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_ChunkX = ((int) tolua_tonumber(tolua_S,2,0)); - int a_ChunkZ = ((int) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'RegenerateChunk'", NULL); -#endif - { - self->RegenerateChunk(a_ChunkX,a_ChunkZ); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'RegenerateChunk'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GenerateChunk of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GenerateChunk00 -static int tolua_AllToLua_cWorld_GenerateChunk00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_ChunkX = ((int) tolua_tonumber(tolua_S,2,0)); - int a_ChunkZ = ((int) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GenerateChunk'", NULL); -#endif - { - self->GenerateChunk(a_ChunkX,a_ChunkZ); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GenerateChunk'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetBlock of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetBlock00 -static int tolua_AllToLua_cWorld_SetBlock00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnumber(tolua_S,5,0,&tolua_err) || - !tolua_isnumber(tolua_S,6,0,&tolua_err) || - !tolua_isnoobj(tolua_S,7,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); - char a_BlockType = ((char) tolua_tonumber(tolua_S,5,0)); - char a_BlockMeta = ((char) tolua_tonumber(tolua_S,6,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBlock'", NULL); -#endif - { - self->SetBlock(a_X,a_Y,a_Z,a_BlockType,a_BlockMeta); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetBlock'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: FastSetBlock of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_FastSetBlock00 -static int tolua_AllToLua_cWorld_FastSetBlock00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnumber(tolua_S,5,0,&tolua_err) || - !tolua_isnumber(tolua_S,6,0,&tolua_err) || - !tolua_isnoobj(tolua_S,7,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); - char a_BlockType = ((char) tolua_tonumber(tolua_S,5,0)); - char a_BlockMeta = ((char) tolua_tonumber(tolua_S,6,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'FastSetBlock'", NULL); -#endif - { - self->FastSetBlock(a_X,a_Y,a_Z,a_BlockType,a_BlockMeta); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'FastSetBlock'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetBlock of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlock00 -static int tolua_AllToLua_cWorld_GetBlock00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlock'", NULL); -#endif - { - char tolua_ret = (char) self->GetBlock(a_X,a_Y,a_Z); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetBlock'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetBlock of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlock01 -static int tolua_AllToLua_cWorld_GetBlock01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - const Vector3i* a_Pos = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlock'", NULL); -#endif - { - char tolua_ret = (char) self->GetBlock(*a_Pos); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_cWorld_GetBlock00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetBlockMeta of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockMeta00 -static int tolua_AllToLua_cWorld_GetBlockMeta00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockMeta'", NULL); -#endif - { - char tolua_ret = (char) self->GetBlockMeta(a_X,a_Y,a_Z); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetBlockMeta'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetBlockMeta of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockMeta01 -static int tolua_AllToLua_cWorld_GetBlockMeta01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - const Vector3i* a_Pos = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockMeta'", NULL); -#endif - { - char tolua_ret = (char) self->GetBlockMeta(*a_Pos); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_cWorld_GetBlockMeta00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetBlockMeta of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetBlockMeta00 -static int tolua_AllToLua_cWorld_SetBlockMeta00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnumber(tolua_S,5,0,&tolua_err) || - !tolua_isnoobj(tolua_S,6,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); - char a_MetaData = ((char) tolua_tonumber(tolua_S,5,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBlockMeta'", NULL); -#endif - { - self->SetBlockMeta(a_X,a_Y,a_Z,a_MetaData); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetBlockMeta'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetBlockMeta of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetBlockMeta01 -static int tolua_AllToLua_cWorld_SetBlockMeta01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - const Vector3i* a_Pos = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); - char a_MetaData = ((char) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBlockMeta'", NULL); -#endif - { - self->SetBlockMeta(*a_Pos,a_MetaData); - } - } - return 0; -tolua_lerror: - return tolua_AllToLua_cWorld_SetBlockMeta00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetBlockSkyLight of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockSkyLight00 -static int tolua_AllToLua_cWorld_GetBlockSkyLight00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockSkyLight'", NULL); -#endif - { - char tolua_ret = (char) self->GetBlockSkyLight(a_X,a_Y,a_Z); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetBlockSkyLight'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetBlockTypeMeta of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockTypeMeta00 -static int tolua_AllToLua_cWorld_GetBlockTypeMeta00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnumber(tolua_S,5,0,&tolua_err) || - !tolua_isnumber(tolua_S,6,0,&tolua_err) || - !tolua_isnoobj(tolua_S,7,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); - int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); - int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); - char a_BlockType = ((char) tolua_tonumber(tolua_S,5,0)); - unsigned char a_BlockMeta = ((unsigned char) tolua_tonumber(tolua_S,6,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockTypeMeta'", NULL); -#endif - { - self->GetBlockTypeMeta(a_BlockX,a_BlockY,a_BlockZ,a_BlockType,a_BlockMeta); - tolua_pushnumber(tolua_S,(lua_Number)a_BlockType); - tolua_pushnumber(tolua_S,(lua_Number)a_BlockMeta); - } - } - return 2; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetBlockTypeMeta'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: DigBlock of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_DigBlock00 -static int tolua_AllToLua_cWorld_DigBlock00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DigBlock'", NULL); -#endif - { - bool tolua_ret = (bool) self->DigBlock(a_X,a_Y,a_Z); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'DigBlock'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SendBlockTo of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SendBlockTo00 -static int tolua_AllToLua_cWorld_SendBlockTo00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isusertype(tolua_S,5,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,6,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,5,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendBlockTo'", NULL); -#endif - { - self->SendBlockTo(a_X,a_Y,a_Z,a_Player); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SendBlockTo'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetSpawnX of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetSpawnX00 -static int tolua_AllToLua_cWorld_GetSpawnX00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSpawnX'", NULL); -#endif - { - const double tolua_ret = (const double) self->GetSpawnX(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetSpawnX'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetSpawnY of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetSpawnY00 -static int tolua_AllToLua_cWorld_GetSpawnY00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSpawnY'", NULL); -#endif - { - const double tolua_ret = (const double) self->GetSpawnY(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetSpawnY'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetSpawnZ of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetSpawnZ00 -static int tolua_AllToLua_cWorld_GetSpawnZ00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSpawnZ'", NULL); -#endif - { - const double tolua_ret = (const double) self->GetSpawnZ(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetSpawnZ'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetBlockEntity of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockEntity00 -static int tolua_AllToLua_cWorld_GetBlockEntity00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockEntity'", NULL); -#endif - { - OBSOLETE cBlockEntity* tolua_ret = (OBSOLETE cBlockEntity*) self->GetBlockEntity(a_X,a_Y,a_Z); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cBlockEntity"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetBlockEntity'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GrowTree of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowTree00 -static int tolua_AllToLua_cWorld_GrowTree00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); - int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); - int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowTree'", NULL); -#endif - { - self->GrowTree(a_BlockX,a_BlockY,a_BlockZ); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GrowTree'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GrowTreeFromSapling of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowTreeFromSapling00 -static int tolua_AllToLua_cWorld_GrowTreeFromSapling00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnumber(tolua_S,5,0,&tolua_err) || - !tolua_isnoobj(tolua_S,6,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); - int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); - int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); - char a_SaplingMeta = ((char) tolua_tonumber(tolua_S,5,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowTreeFromSapling'", NULL); -#endif - { - self->GrowTreeFromSapling(a_BlockX,a_BlockY,a_BlockZ,a_SaplingMeta); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GrowTreeFromSapling'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GrowTreeByBiome of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowTreeByBiome00 -static int tolua_AllToLua_cWorld_GrowTreeByBiome00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); - int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); - int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowTreeByBiome'", NULL); -#endif - { - self->GrowTreeByBiome(a_BlockX,a_BlockY,a_BlockZ); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GrowTreeByBiome'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GrowPlant of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowPlant00 -static int tolua_AllToLua_cWorld_GrowPlant00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isboolean(tolua_S,5,1,&tolua_err) || - !tolua_isnoobj(tolua_S,6,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); - int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); - int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); - bool a_IsByBonemeal = ((bool) tolua_toboolean(tolua_S,5,false)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowPlant'", NULL); -#endif - { - bool tolua_ret = (bool) self->GrowPlant(a_BlockX,a_BlockY,a_BlockZ,a_IsByBonemeal); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GrowPlant'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GrowMelonPumpkin of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowMelonPumpkin00 -static int tolua_AllToLua_cWorld_GrowMelonPumpkin00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnumber(tolua_S,5,0,&tolua_err) || - !tolua_isnoobj(tolua_S,6,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); - int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); - int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); - char a_BlockType = ((char) tolua_tonumber(tolua_S,5,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowMelonPumpkin'", NULL); -#endif - { - self->GrowMelonPumpkin(a_BlockX,a_BlockY,a_BlockZ,a_BlockType); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GrowMelonPumpkin'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetBiomeAt of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBiomeAt00 -static int tolua_AllToLua_cWorld_GetBiomeAt00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); - int a_BlockZ = ((int) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBiomeAt'", NULL); -#endif - { - int tolua_ret = (int) self->GetBiomeAt(a_BlockX,a_BlockZ); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetBiomeAt'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetName of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetName00 -static int tolua_AllToLua_cWorld_GetName00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL); -#endif - { - const AString tolua_ret = (const AString) self->GetName(); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetName'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SaveAllChunks of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SaveAllChunks00 -static int tolua_AllToLua_cWorld_SaveAllChunks00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SaveAllChunks'", NULL); -#endif - { - self->SaveAllChunks(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SaveAllChunks'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetNumChunks of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetNumChunks00 -static int tolua_AllToLua_cWorld_GetNumChunks00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumChunks'", NULL); -#endif - { - int tolua_ret = (int) self->GetNumChunks(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetNumChunks'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetGeneratorQueueLength of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetGeneratorQueueLength00 -static int tolua_AllToLua_cWorld_GetGeneratorQueueLength00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetGeneratorQueueLength'", NULL); -#endif - { - int tolua_ret = (int) self->GetGeneratorQueueLength(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetGeneratorQueueLength'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetLightingQueueLength of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetLightingQueueLength00 -static int tolua_AllToLua_cWorld_GetLightingQueueLength00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLightingQueueLength'", NULL); -#endif - { - int tolua_ret = (int) self->GetLightingQueueLength(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetLightingQueueLength'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetStorageLoadQueueLength of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetStorageLoadQueueLength00 -static int tolua_AllToLua_cWorld_GetStorageLoadQueueLength00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetStorageLoadQueueLength'", NULL); -#endif - { - int tolua_ret = (int) self->GetStorageLoadQueueLength(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetStorageLoadQueueLength'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetStorageSaveQueueLength of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetStorageSaveQueueLength00 -static int tolua_AllToLua_cWorld_GetStorageSaveQueueLength00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetStorageSaveQueueLength'", NULL); -#endif - { - int tolua_ret = (int) self->GetStorageSaveQueueLength(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetStorageSaveQueueLength'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: CastThunderbolt of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_CastThunderbolt00 -static int tolua_AllToLua_cWorld_CastThunderbolt00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CastThunderbolt'", NULL); -#endif - { - self->CastThunderbolt(a_X,a_Y,a_Z); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'CastThunderbolt'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetWeather of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetWeather00 -static int tolua_AllToLua_cWorld_SetWeather00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - eWeather a_Weather = ((eWeather) (int) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetWeather'", NULL); -#endif - { - self->SetWeather(a_Weather); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetWeather'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: ChangeWeather of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_ChangeWeather00 -static int tolua_AllToLua_cWorld_ChangeWeather00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ChangeWeather'", NULL); -#endif - { - self->ChangeWeather(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'ChangeWeather'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetWeather of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetWeather00 -static int tolua_AllToLua_cWorld_GetWeather00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWeather'", NULL); -#endif - { - eWeather tolua_ret = (eWeather) self->GetWeather(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetWeather'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetNextBlockTick of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetNextBlockTick00 -static int tolua_AllToLua_cWorld_SetNextBlockTick00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); - int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); - int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetNextBlockTick'", NULL); -#endif - { - self->SetNextBlockTick(a_BlockX,a_BlockY,a_BlockZ); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetNextBlockTick'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetMaxSugarcaneHeight of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetMaxSugarcaneHeight00 -static int tolua_AllToLua_cWorld_GetMaxSugarcaneHeight00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxSugarcaneHeight'", NULL); -#endif - { - int tolua_ret = (int) self->GetMaxSugarcaneHeight(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetMaxSugarcaneHeight'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetMaxCactusHeight of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetMaxCactusHeight00 -static int tolua_AllToLua_cWorld_GetMaxCactusHeight00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxCactusHeight'", NULL); -#endif - { - int tolua_ret = (int) self->GetMaxCactusHeight(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetMaxCactusHeight'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Clear of class cInventory */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_Clear00 -static int tolua_AllToLua_cInventory_Clear00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL); -#endif - { - self->Clear(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: AddItem of class cInventory */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_AddItem00 -static int tolua_AllToLua_cInventory_AddItem00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); - cItem* a_Item = ((cItem*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddItem'", NULL); -#endif - { - bool tolua_ret = (bool) self->AddItem(*a_Item); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'AddItem'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: RemoveItem of class cInventory */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_RemoveItem00 -static int tolua_AllToLua_cInventory_RemoveItem00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); - cItem* a_Item = ((cItem*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'RemoveItem'", NULL); -#endif - { - bool tolua_ret = (bool) self->RemoveItem(*a_Item); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'RemoveItem'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetSlot of class cInventory */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetSlot00 -static int tolua_AllToLua_cInventory_GetSlot00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); - int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSlot'", NULL); -#endif - { - cItem* tolua_ret = (cItem*) self->GetSlot(a_SlotNum); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cItem"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetSlot'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetFromHotBar of class cInventory */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetFromHotBar00 -static int tolua_AllToLua_cInventory_GetFromHotBar00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); - int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetFromHotBar'", NULL); -#endif - { - cItem* tolua_ret = (cItem*) self->GetFromHotBar(a_SlotNum); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cItem"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetFromHotBar'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetEquippedItem of class cInventory */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetEquippedItem00 -static int tolua_AllToLua_cInventory_GetEquippedItem00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEquippedItem'", NULL); -#endif - { - cItem& tolua_ret = (cItem&) self->GetEquippedItem(); - tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cItem"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetEquippedItem'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetEquippedSlot of class cInventory */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_SetEquippedSlot00 -static int tolua_AllToLua_cInventory_SetEquippedSlot00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); - int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetEquippedSlot'", NULL); -#endif - { - self->SetEquippedSlot(a_SlotNum); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetEquippedSlot'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetEquippedSlot of class cInventory */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetEquippedSlot00 -static int tolua_AllToLua_cInventory_GetEquippedSlot00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEquippedSlot'", NULL); -#endif - { - short tolua_ret = (short) self->GetEquippedSlot(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetEquippedSlot'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SendSlot of class cInventory */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_SendSlot00 -static int tolua_AllToLua_cInventory_SendSlot00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); - int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendSlot'", NULL); -#endif - { - self->SendSlot(a_SlotNum); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SendSlot'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class cItem */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_new00 -static int tolua_AllToLua_cItem_new00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cItem",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,1,&tolua_err) || - !tolua_isnumber(tolua_S,3,1,&tolua_err) || - !tolua_isnumber(tolua_S,4,1,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,E_ITEM_EMPTY)); - char a_ItemCount = ((char) tolua_tonumber(tolua_S,3,0)); - short a_ItemHealth = ((short) tolua_tonumber(tolua_S,4,0)); - { - cItem* tolua_ret = (cItem*) Mtolua_new((cItem)(a_ItemID,a_ItemCount,a_ItemHealth)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cItem"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class cItem */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_new00_local -static int tolua_AllToLua_cItem_new00_local(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cItem",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,1,&tolua_err) || - !tolua_isnumber(tolua_S,3,1,&tolua_err) || - !tolua_isnumber(tolua_S,4,1,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,E_ITEM_EMPTY)); - char a_ItemCount = ((char) tolua_tonumber(tolua_S,3,0)); - short a_ItemHealth = ((short) tolua_tonumber(tolua_S,4,0)); - { - cItem* tolua_ret = (cItem*) Mtolua_new((cItem)(a_ItemID,a_ItemCount,a_ItemHealth)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cItem"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Empty of class cItem */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_Empty00 -static int tolua_AllToLua_cItem_Empty00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Empty'", NULL); -#endif - { - self->Empty(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Empty'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Clear of class cItem */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_Clear00 -static int tolua_AllToLua_cItem_Clear00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL); -#endif - { - self->Clear(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: IsEmpty of class cItem */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_IsEmpty00 -static int tolua_AllToLua_cItem_IsEmpty00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cItem",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cItem* self = (const cItem*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsEmpty'", NULL); -#endif - { - bool tolua_ret = (bool) self->IsEmpty(); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'IsEmpty'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Equals of class cItem */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_Equals00 -static int tolua_AllToLua_cItem_Equals00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cItem",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cItem* self = (const cItem*) tolua_tousertype(tolua_S,1,0); - cItem* a_Item = ((cItem*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Equals'", NULL); -#endif - { - bool tolua_ret = (bool) self->Equals(*a_Item); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Equals'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetMaxDuration of class cItem */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_GetMaxDuration00 -static int tolua_AllToLua_cItem_GetMaxDuration00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cItem",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cItem* self = (const cItem*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxDuration'", NULL); -#endif - { - int tolua_ret = (int) self->GetMaxDuration(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetMaxDuration'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: DamageItem of class cItem */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_DamageItem00 -static int tolua_AllToLua_cItem_DamageItem00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DamageItem'", NULL); -#endif - { - bool tolua_ret = (bool) self->DamageItem(); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'DamageItem'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: HasDuration of class cItem */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_HasDuration00 -static int tolua_AllToLua_cItem_HasDuration00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HasDuration'", NULL); -#endif - { - bool tolua_ret = (bool) self->HasDuration(); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'HasDuration'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetJson of class cItem */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_GetJson00 -static int tolua_AllToLua_cItem_GetJson00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cItem",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Json::Value",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cItem* self = (const cItem*) tolua_tousertype(tolua_S,1,0); - Json::Value* a_OutValue = ((Json::Value*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetJson'", NULL); -#endif - { - self->GetJson(*a_OutValue); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetJson'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: FromJson of class cItem */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_FromJson00 -static int tolua_AllToLua_cItem_FromJson00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Json::Value",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); - const Json::Value* a_Value = ((const Json::Value*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'FromJson'", NULL); -#endif - { - self->FromJson(*a_Value); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'FromJson'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: IsEnchantable of class cItem */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_IsEnchantable00 -static int tolua_AllToLua_cItem_IsEnchantable00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cItem",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - ENUM_ITEM_ID item = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,0)); - { - bool tolua_ret = (bool) cItem::IsEnchantable(item); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'IsEnchantable'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_ItemID of class cItem */ -#ifndef TOLUA_DISABLE_tolua_get_cItem_m_ItemID -static int tolua_get_cItem_m_ItemID(lua_State* tolua_S) -{ - cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemID'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_ItemID); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_ItemID of class cItem */ -#ifndef TOLUA_DISABLE_tolua_set_cItem_m_ItemID -static int tolua_set_cItem_m_ItemID(lua_State* tolua_S) -{ - cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemID'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_ItemCount of class cItem */ -#ifndef TOLUA_DISABLE_tolua_get_cItem_m_ItemCount -static int tolua_get_cItem_m_ItemCount(lua_State* tolua_S) -{ - cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemCount'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_ItemCount); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_ItemCount of class cItem */ -#ifndef TOLUA_DISABLE_tolua_set_cItem_m_ItemCount -static int tolua_set_cItem_m_ItemCount(lua_State* tolua_S) -{ - cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemCount'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_ItemCount = ((char) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_ItemHealth of class cItem */ -#ifndef TOLUA_DISABLE_tolua_get_cItem_m_ItemHealth -static int tolua_get_cItem_m_ItemHealth(lua_State* tolua_S) -{ - cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemHealth'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_ItemHealth); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_ItemHealth of class cItem */ -#ifndef TOLUA_DISABLE_tolua_set_cItem_m_ItemHealth -static int tolua_set_cItem_m_ItemHealth(lua_State* tolua_S) -{ - cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemHealth'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_ItemHealth = ((short) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Name of class HTTPFormData */ -#ifndef TOLUA_DISABLE_tolua_get_HTTPFormData_Name -static int tolua_get_HTTPFormData_Name(lua_State* tolua_S) -{ - HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Name'",NULL); -#endif - tolua_pushcppstring(tolua_S,(const char*)self->Name); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: Name of class HTTPFormData */ -#ifndef TOLUA_DISABLE_tolua_set_HTTPFormData_Name -static int tolua_set_HTTPFormData_Name(lua_State* tolua_S) -{ - HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Name'",NULL); - if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->Name = ((std::string) tolua_tocppstring(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Value of class HTTPFormData */ -#ifndef TOLUA_DISABLE_tolua_get_HTTPFormData_Value -static int tolua_get_HTTPFormData_Value(lua_State* tolua_S) -{ - HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Value'",NULL); -#endif - tolua_pushcppstring(tolua_S,(const char*)self->Value); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: Value of class HTTPFormData */ -#ifndef TOLUA_DISABLE_tolua_set_HTTPFormData_Value -static int tolua_set_HTTPFormData_Value(lua_State* tolua_S) -{ - HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Value'",NULL); - if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->Value = ((std::string) tolua_tocppstring(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Type of class HTTPFormData */ -#ifndef TOLUA_DISABLE_tolua_get_HTTPFormData_Type -static int tolua_get_HTTPFormData_Type(lua_State* tolua_S) -{ - HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Type'",NULL); -#endif - tolua_pushcppstring(tolua_S,(const char*)self->Type); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: Type of class HTTPFormData */ -#ifndef TOLUA_DISABLE_tolua_set_HTTPFormData_Type -static int tolua_set_HTTPFormData_Type(lua_State* tolua_S) -{ - HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Type'",NULL); - if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->Type = ((std::string) tolua_tocppstring(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Method of class HTTPRequest */ -#ifndef TOLUA_DISABLE_tolua_get_HTTPRequest_Method -static int tolua_get_HTTPRequest_Method(lua_State* tolua_S) -{ - HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Method'",NULL); -#endif - tolua_pushcppstring(tolua_S,(const char*)self->Method); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: Method of class HTTPRequest */ -#ifndef TOLUA_DISABLE_tolua_set_HTTPRequest_Method -static int tolua_set_HTTPRequest_Method(lua_State* tolua_S) -{ - HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Method'",NULL); - if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->Method = ((std::string) tolua_tocppstring(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Path of class HTTPRequest */ -#ifndef TOLUA_DISABLE_tolua_get_HTTPRequest_Path -static int tolua_get_HTTPRequest_Path(lua_State* tolua_S) -{ - HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Path'",NULL); -#endif - tolua_pushcppstring(tolua_S,(const char*)self->Path); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: Path of class HTTPRequest */ -#ifndef TOLUA_DISABLE_tolua_set_HTTPRequest_Path -static int tolua_set_HTTPRequest_Path(lua_State* tolua_S) -{ - HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Path'",NULL); - if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->Path = ((std::string) tolua_tocppstring(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: Username of class HTTPRequest */ -#ifndef TOLUA_DISABLE_tolua_get_HTTPRequest_Username -static int tolua_get_HTTPRequest_Username(lua_State* tolua_S) -{ - HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Username'",NULL); -#endif - tolua_pushcppstring(tolua_S,(const char*)self->Username); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: Username of class HTTPRequest */ -#ifndef TOLUA_DISABLE_tolua_set_HTTPRequest_Username -static int tolua_set_HTTPRequest_Username(lua_State* tolua_S) -{ - HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Username'",NULL); - if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->Username = ((std::string) tolua_tocppstring(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* method: delete of class cWebPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_delete00 -static int tolua_AllToLua_cWebPlugin_delete00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); -#endif - Mtolua_delete(self); - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetName of class cWebPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_SetName00 -static int tolua_AllToLua_cWebPlugin_SetName00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0); - std::string a_Name = ((std::string) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetName'", NULL); -#endif - { - self->SetName(a_Name); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetName'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetName of class cWebPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_GetName00 -static int tolua_AllToLua_cWebPlugin_GetName00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL); -#endif - { - std::string tolua_ret = (std::string) self->GetName(); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetName'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: HandleRequest of class cWebPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_HandleRequest00 -static int tolua_AllToLua_cWebPlugin_HandleRequest00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"HTTPRequest",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0); - HTTPRequest* a_Request = ((HTTPRequest*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HandleRequest'", NULL); -#endif - { - std::string tolua_ret = (std::string) self->HandleRequest(a_Request); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'HandleRequest'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Initialize of class cWebPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_Initialize00 -static int tolua_AllToLua_cWebPlugin_Initialize00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL); -#endif - { - self->Initialize(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - - class Lua__cWebPlugin : public cWebPlugin, public ToluaBase { -public: - std::string HandleRequest( HTTPRequest* a_Request) { - if (push_method("HandleRequest", tolua_AllToLua_cWebPlugin_HandleRequest00)) { - tolua_pushusertype(lua_state, (void*)a_Request, "HTTPRequest"); - ToluaBase::dbcall(lua_state, 2, 1); - std::string tolua_ret = ( std::string )tolua_tocppstring(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - if (lua_state) - LOG("pure-virtual method cWebPlugin::HandleRequest not implemented."); - else { - LOG("pure-virtual method cWebPlugin::HandleRequest called with no lua_state. Aborting"); - ::abort(); - }; - return ""; - }; - }; - void Initialize( void ) { - if (push_method("Initialize", tolua_AllToLua_cWebPlugin_Initialize00)) { - ToluaBase::dbcall(lua_state, 1, 0); - } else { - if (lua_state) - LOG("pure-virtual method cWebPlugin::Initialize not implemented."); - else { - LOG("pure-virtual method cWebPlugin::Initialize called with no lua_state. Aborting"); - ::abort(); - }; - return ( void )0; - }; - }; - - Lua__cWebPlugin( lua_State* L): cWebPlugin(L){}; -}; - -/* method: tolua__set_instance of class Lua__cWebPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cWebPlugin_tolua__set_instance00 -static int tolua_AllToLua_Lua__cWebPlugin_tolua__set_instance00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cWebPlugin",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cWebPlugin* self = (Lua__cWebPlugin*) tolua_tousertype(tolua_S,1,0); - lua_State* L = tolua_S; - lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); -#endif - { - self->tolua__set_instance(L,lo); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class Lua__cWebPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cWebPlugin_new00 -static int tolua_AllToLua_Lua__cWebPlugin_new00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Lua__cWebPlugin",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - lua_State* L = tolua_S; - { - Lua__cWebPlugin* tolua_ret = (Lua__cWebPlugin*) Mtolua_new((Lua__cWebPlugin)(L)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cWebPlugin"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class Lua__cWebPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cWebPlugin_new00_local -static int tolua_AllToLua_Lua__cWebPlugin_new00_local(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Lua__cWebPlugin",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - lua_State* L = tolua_S; - { - Lua__cWebPlugin* tolua_ret = (Lua__cWebPlugin*) Mtolua_new((Lua__cWebPlugin)(L)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cWebPlugin"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: delete of class Lua__cWebPlugin */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cWebPlugin_delete00 -static int tolua_AllToLua_Lua__cWebPlugin_delete00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cWebPlugin",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cWebPlugin* self = (Lua__cWebPlugin*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); -#endif - Mtolua_delete(self); - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - - -/* function to release collected object via destructor */ -#ifdef __cplusplus - -static int tolua_collect_Lua__cWebPlugin (lua_State* tolua_S) -{ - Lua__cWebPlugin* self = (Lua__cWebPlugin*) tolua_tousertype(tolua_S,1,0); - delete self; - return 0; -} -#endif - -/* method: new of class cPickup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_new00 -static int tolua_AllToLua_cPickup_new00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cPickup",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"const cItem",0,&tolua_err)) || - !tolua_isnumber(tolua_S,6,1,&tolua_err) || - !tolua_isnumber(tolua_S,7,1,&tolua_err) || - !tolua_isnumber(tolua_S,8,1,&tolua_err) || - !tolua_isnoobj(tolua_S,9,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); - const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,5,0)); - float a_SpeedX = ((float) tolua_tonumber(tolua_S,6,0.f)); - float a_SpeedY = ((float) tolua_tonumber(tolua_S,7,0.f)); - float a_SpeedZ = ((float) tolua_tonumber(tolua_S,8,0.f)); - { - cPickup* tolua_ret = (cPickup*) Mtolua_new((cPickup)(a_X,a_Y,a_Z,*a_Item,a_SpeedX,a_SpeedY,a_SpeedZ)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPickup"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class cPickup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_new00_local -static int tolua_AllToLua_cPickup_new00_local(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cPickup",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"const cItem",0,&tolua_err)) || - !tolua_isnumber(tolua_S,6,1,&tolua_err) || - !tolua_isnumber(tolua_S,7,1,&tolua_err) || - !tolua_isnumber(tolua_S,8,1,&tolua_err) || - !tolua_isnoobj(tolua_S,9,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); - const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,5,0)); - float a_SpeedX = ((float) tolua_tonumber(tolua_S,6,0.f)); - float a_SpeedY = ((float) tolua_tonumber(tolua_S,7,0.f)); - float a_SpeedZ = ((float) tolua_tonumber(tolua_S,8,0.f)); - { - cPickup* tolua_ret = (cPickup*) Mtolua_new((cPickup)(a_X,a_Y,a_Z,*a_Item,a_SpeedX,a_SpeedY,a_SpeedZ)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPickup"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class cPickup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_new01 -static int tolua_AllToLua_cPickup_new01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cPickup",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPacket_PickupSpawn",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - cPacket_PickupSpawn* a_PickupSpawnPacket = ((cPacket_PickupSpawn*) tolua_tousertype(tolua_S,2,0)); - { - cPickup* tolua_ret = (cPickup*) Mtolua_new((cPickup)(a_PickupSpawnPacket)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPickup"); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_cPickup_new00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class cPickup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_new01_local -static int tolua_AllToLua_cPickup_new01_local(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cPickup",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPacket_PickupSpawn",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - cPacket_PickupSpawn* a_PickupSpawnPacket = ((cPacket_PickupSpawn*) tolua_tousertype(tolua_S,2,0)); - { - cPickup* tolua_ret = (cPickup*) Mtolua_new((cPickup)(a_PickupSpawnPacket)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPickup"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_cPickup_new00_local(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: delete of class cPickup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_delete00 -static int tolua_AllToLua_cPickup_delete00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPickup",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPickup* self = (cPickup*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); -#endif - Mtolua_delete(self); - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetItem of class cPickup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_GetItem00 -static int tolua_AllToLua_cPickup_GetItem00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPickup",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPickup* self = (cPickup*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetItem'", NULL); -#endif - { - cItem* tolua_ret = (cItem*) self->GetItem(); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cItem"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetItem'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: CollectedBy of class cPickup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_CollectedBy00 -static int tolua_AllToLua_cPickup_CollectedBy00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPickup",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPickup* self = (cPickup*) tolua_tousertype(tolua_S,1,0); - cPlayer* a_Dest = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CollectedBy'", NULL); -#endif - { - bool tolua_ret = (bool) self->CollectedBy(a_Dest); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'CollectedBy'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - - class Lua__cPickup : public cPickup, public ToluaBase { -public: - bool CollectedBy( cPlayer* a_Dest) { - if (push_method("CollectedBy", tolua_AllToLua_cPickup_CollectedBy00)) { - tolua_pushusertype(lua_state, (void*)a_Dest, "cPlayer"); - ToluaBase::dbcall(lua_state, 2, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPickup:: CollectedBy(a_Dest); - }; - }; - void Initialize( cWorld* a_World) { - if (push_method("Initialize", tolua_AllToLua_cEntity_Initialize00)) { - tolua_pushusertype(lua_state, (void*)a_World, "cWorld"); - ToluaBase::dbcall(lua_state, 2, 0); - } else { - return ( void ) cPickup:: Initialize(a_World); - }; - }; - unsigned int GetEntityType( void ) { - if (push_method("GetEntityType", tolua_AllToLua_cEntity_GetEntityType00)) { - ToluaBase::dbcall(lua_state, 1, 1); - unsigned int tolua_ret = (unsigned int )tolua_tonumber(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return (unsigned int ) cPickup:: GetEntityType(); - }; - }; - bool IsA( const char* a_EntityType) { - if (push_method("IsA", tolua_AllToLua_cEntity_IsA00)) { - tolua_pushstring(lua_state, (const char*)a_EntityType); - ToluaBase::dbcall(lua_state, 2, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPickup:: IsA(a_EntityType); - }; - }; - const char* GetClass( void ) { - if (push_method("GetClass", tolua_AllToLua_cEntity_GetClass00)) { - ToluaBase::dbcall(lua_state, 1, 1); - const char* tolua_ret = ( const char* )tolua_tostring(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( const char* ) cPickup:: GetClass(); - }; - }; - void Tick( float a_Dt) { - if (push_method("Tick", tolua_AllToLua_cEntity_Tick00)) { - tolua_pushnumber(lua_state, (lua_Number)a_Dt); - ToluaBase::dbcall(lua_state, 2, 0); - } else { - if (lua_state) - LOG("pure-virtual method cPickup::Tick not implemented."); - else { - LOG("pure-virtual method cPickup::Tick called with no lua_state. Aborting"); - ::abort(); - }; - return ( void )0; - }; - }; - - bool cPickup__CollectedBy( cPlayer* a_Dest) { - return ( bool )cPickup::CollectedBy(a_Dest); - }; - void cPickup__Initialize( cWorld* a_World) { - return ( void )cPickup::Initialize(a_World); - }; - unsigned int cPickup__GetEntityType( void ) { - return (unsigned int )cPickup::GetEntityType(); - }; - bool cPickup__IsA( const char* a_EntityType) { - return ( bool )cPickup::IsA(a_EntityType); - }; - const char* cPickup__GetClass( void ) { - return ( const char* )cPickup::GetClass(); - }; - Lua__cPickup( int a_X, int a_Y, int a_Z, const cItem& a_Item, float a_SpeedX = 0.f, float a_SpeedY = 0.f, float a_SpeedZ = 0.f): cPickup(a_X,a_Y,a_Z,a_Item,a_SpeedX,a_SpeedY,a_SpeedZ){}; - Lua__cPickup( cPacket_PickupSpawn* a_PickupSpawnPacket): cPickup(a_PickupSpawnPacket){}; -}; - -/* method: tolua__set_instance of class Lua__cPickup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_tolua__set_instance00 -static int tolua_AllToLua_Lua__cPickup_tolua__set_instance00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPickup",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPickup* self = (Lua__cPickup*) tolua_tousertype(tolua_S,1,0); - lua_State* L = tolua_S; - lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); -#endif - { - self->tolua__set_instance(L,lo); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPickup__CollectedBy of class Lua__cPickup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_cPickup__CollectedBy00 -static int tolua_AllToLua_Lua__cPickup_cPickup__CollectedBy00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPickup",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPickup* self = (Lua__cPickup*) tolua_tousertype(tolua_S,1,0); - cPlayer* a_Dest = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPickup__CollectedBy'", NULL); -#endif - { - bool tolua_ret = (bool) self->cPickup__CollectedBy(a_Dest); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPickup__CollectedBy'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class Lua__cPickup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_new00 -static int tolua_AllToLua_Lua__cPickup_new00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Lua__cPickup",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"cItem",0,&tolua_err)) || - !tolua_isnumber(tolua_S,6,1,&tolua_err) || - !tolua_isnumber(tolua_S,7,1,&tolua_err) || - !tolua_isnumber(tolua_S,8,1,&tolua_err) || - !tolua_isnoobj(tolua_S,9,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); - const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,5,0)); - float a_SpeedX = ((float) tolua_tonumber(tolua_S,6,0.f)); - float a_SpeedY = ((float) tolua_tonumber(tolua_S,7,0.f)); - float a_SpeedZ = ((float) tolua_tonumber(tolua_S,8,0.f)); - { - Lua__cPickup* tolua_ret = (Lua__cPickup*) Mtolua_new((Lua__cPickup)(a_X,a_Y,a_Z,*a_Item,a_SpeedX,a_SpeedY,a_SpeedZ)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPickup"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class Lua__cPickup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_new00_local -static int tolua_AllToLua_Lua__cPickup_new00_local(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Lua__cPickup",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"cItem",0,&tolua_err)) || - !tolua_isnumber(tolua_S,6,1,&tolua_err) || - !tolua_isnumber(tolua_S,7,1,&tolua_err) || - !tolua_isnumber(tolua_S,8,1,&tolua_err) || - !tolua_isnoobj(tolua_S,9,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); - const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,5,0)); - float a_SpeedX = ((float) tolua_tonumber(tolua_S,6,0.f)); - float a_SpeedY = ((float) tolua_tonumber(tolua_S,7,0.f)); - float a_SpeedZ = ((float) tolua_tonumber(tolua_S,8,0.f)); - { - Lua__cPickup* tolua_ret = (Lua__cPickup*) Mtolua_new((Lua__cPickup)(a_X,a_Y,a_Z,*a_Item,a_SpeedX,a_SpeedY,a_SpeedZ)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPickup"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class Lua__cPickup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_new01 -static int tolua_AllToLua_Lua__cPickup_new01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Lua__cPickup",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPacket_PickupSpawn",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - cPacket_PickupSpawn* a_PickupSpawnPacket = ((cPacket_PickupSpawn*) tolua_tousertype(tolua_S,2,0)); - { - Lua__cPickup* tolua_ret = (Lua__cPickup*) Mtolua_new((Lua__cPickup)(a_PickupSpawnPacket)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPickup"); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Lua__cPickup_new00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class Lua__cPickup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_new01_local -static int tolua_AllToLua_Lua__cPickup_new01_local(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Lua__cPickup",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cPacket_PickupSpawn",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - cPacket_PickupSpawn* a_PickupSpawnPacket = ((cPacket_PickupSpawn*) tolua_tousertype(tolua_S,2,0)); - { - Lua__cPickup* tolua_ret = (Lua__cPickup*) Mtolua_new((Lua__cPickup)(a_PickupSpawnPacket)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPickup"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Lua__cPickup_new00_local(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: delete of class Lua__cPickup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_delete00 -static int tolua_AllToLua_Lua__cPickup_delete00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPickup",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPickup* self = (Lua__cPickup*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); -#endif - Mtolua_delete(self); - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - - -/* function to release collected object via destructor */ -#ifdef __cplusplus - -static int tolua_collect_Lua__cPickup (lua_State* tolua_S) -{ - Lua__cPickup* self = (Lua__cPickup*) tolua_tousertype(tolua_S,1,0); - delete self; - return 0; -} -#endif - -/* method: Get of class cRoot */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_Get00 -static int tolua_AllToLua_cRoot_Get00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cRoot",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - { - cRoot* tolua_ret = (cRoot*) cRoot::Get(); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cRoot"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Get'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetServer of class cRoot */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetServer00 -static int tolua_AllToLua_cRoot_GetServer00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetServer'", NULL); -#endif - { - cServer* tolua_ret = (cServer*) self->GetServer(); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cServer"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetServer'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetDefaultWorld of class cRoot */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetDefaultWorld00 -static int tolua_AllToLua_cRoot_GetDefaultWorld00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetDefaultWorld'", NULL); -#endif - { - cWorld* tolua_ret = (cWorld*) self->GetDefaultWorld(); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWorld"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetDefaultWorld'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetWorld of class cRoot */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetWorld00 -static int tolua_AllToLua_cRoot_GetWorld00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); - const AString a_WorldName = ((const AString) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWorld'", NULL); -#endif - { - cWorld* tolua_ret = (cWorld*) self->GetWorld(a_WorldName); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWorld"); - tolua_pushcppstring(tolua_S,(const char*)a_WorldName); - } - } - return 2; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetWorld'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetGroupManager of class cRoot */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetGroupManager00 -static int tolua_AllToLua_cRoot_GetGroupManager00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetGroupManager'", NULL); -#endif - { - cGroupManager* tolua_ret = (cGroupManager*) self->GetGroupManager(); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cGroupManager"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetGroupManager'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetCraftingRecipes of class cRoot */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetCraftingRecipes00 -static int tolua_AllToLua_cRoot_GetCraftingRecipes00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetCraftingRecipes'", NULL); -#endif - { - cCraftingRecipes* tolua_ret = (cCraftingRecipes*) self->GetCraftingRecipes(); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCraftingRecipes"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetCraftingRecipes'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetFurnaceRecipe of class cRoot */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetFurnaceRecipe00 -static int tolua_AllToLua_cRoot_GetFurnaceRecipe00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetFurnaceRecipe'", NULL); -#endif - { - cFurnaceRecipe* tolua_ret = (cFurnaceRecipe*) self->GetFurnaceRecipe(); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cFurnaceRecipe"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetFurnaceRecipe'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetWebAdmin of class cRoot */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetWebAdmin00 -static int tolua_AllToLua_cRoot_GetWebAdmin00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWebAdmin'", NULL); -#endif - { - cWebAdmin* tolua_ret = (cWebAdmin*) self->GetWebAdmin(); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWebAdmin"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetWebAdmin'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetPluginManager of class cRoot */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetPluginManager00 -static int tolua_AllToLua_cRoot_GetPluginManager00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPluginManager'", NULL); -#endif - { - cPluginManager* tolua_ret = (cPluginManager*) self->GetPluginManager(); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPluginManager"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetPluginManager'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: ServerCommand of class cRoot */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_ServerCommand00 -static int tolua_AllToLua_cRoot_ServerCommand00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); - const char* a_Cmd = ((const char*) tolua_tostring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ServerCommand'", NULL); -#endif - { - self->ServerCommand(a_Cmd); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'ServerCommand'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetTotalChunkCount of class cRoot */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetTotalChunkCount00 -static int tolua_AllToLua_cRoot_GetTotalChunkCount00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetTotalChunkCount'", NULL); -#endif - { - int tolua_ret = (int) self->GetTotalChunkCount(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetTotalChunkCount'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: delete of class cTCPLink */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cTCPLink_delete00 -static int tolua_AllToLua_cTCPLink_delete00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cTCPLink",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); -#endif - Mtolua_delete(self); - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Connect of class cTCPLink */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cTCPLink_Connect00 -static int tolua_AllToLua_cTCPLink_Connect00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cTCPLink",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0); - const AString a_Address = ((const AString) tolua_tocppstring(tolua_S,2,0)); - unsigned int a_Port = ((unsigned int) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Connect'", NULL); -#endif - { - bool tolua_ret = (bool) self->Connect(a_Address,a_Port); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - tolua_pushcppstring(tolua_S,(const char*)a_Address); - } - } - return 2; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Connect'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Send of class cTCPLink */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cTCPLink_Send00 -static int tolua_AllToLua_cTCPLink_Send00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cTCPLink",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,1,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0); - const char* a_Data = ((const char*) tolua_tostring(tolua_S,2,0)); - unsigned int a_Size = ((unsigned int) tolua_tonumber(tolua_S,3,0)); - int a_Flags = ((int) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Send'", NULL); -#endif - { - int tolua_ret = (int) self->Send(a_Data,a_Size,a_Flags); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Send'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SendMessage of class cTCPLink */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cTCPLink_SendMessage00 -static int tolua_AllToLua_cTCPLink_SendMessage00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cTCPLink",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,1,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0); - const char* a_Message = ((const char*) tolua_tostring(tolua_S,2,0)); - int a_Flags = ((int) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendMessage'", NULL); -#endif - { - int tolua_ret = (int) self->SendMessage(a_Message,a_Flags); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SendMessage'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: CloseSocket of class cTCPLink */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cTCPLink_CloseSocket00 -static int tolua_AllToLua_cTCPLink_CloseSocket00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cTCPLink",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CloseSocket'", NULL); -#endif - { - self->CloseSocket(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'CloseSocket'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - - class Lua__cTCPLink : public cTCPLink, public ToluaBase { -public: - void ReceivedData( char* a_Data, int a_Size) { - if (push_method("ReceivedData", NULL)) { - tolua_pushstring(lua_state, (const char*)a_Data); - tolua_pushnumber(lua_state, (lua_Number)a_Size); - ToluaBase::dbcall(lua_state, 3, 0); - } else { - if (lua_state) - LOG("pure-virtual method cTCPLink::ReceivedData not implemented."); - else { - LOG("pure-virtual method cTCPLink::ReceivedData called with no lua_state. Aborting"); - ::abort(); - }; - return ( void )0; - }; - }; - - Lua__cTCPLink( void ): cTCPLink(){}; -}; - -/* method: tolua__set_instance of class Lua__cTCPLink */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cTCPLink_tolua__set_instance00 -static int tolua_AllToLua_Lua__cTCPLink_tolua__set_instance00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cTCPLink",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cTCPLink* self = (Lua__cTCPLink*) tolua_tousertype(tolua_S,1,0); - lua_State* L = tolua_S; - lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); -#endif - { - self->tolua__set_instance(L,lo); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class Lua__cTCPLink */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cTCPLink_new00 -static int tolua_AllToLua_Lua__cTCPLink_new00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Lua__cTCPLink",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - { - Lua__cTCPLink* tolua_ret = (Lua__cTCPLink*) Mtolua_new((Lua__cTCPLink)()); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cTCPLink"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class Lua__cTCPLink */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cTCPLink_new00_local -static int tolua_AllToLua_Lua__cTCPLink_new00_local(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Lua__cTCPLink",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - { - Lua__cTCPLink* tolua_ret = (Lua__cTCPLink*) Mtolua_new((Lua__cTCPLink)()); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cTCPLink"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: delete of class Lua__cTCPLink */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cTCPLink_delete00 -static int tolua_AllToLua_Lua__cTCPLink_delete00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cTCPLink",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cTCPLink* self = (Lua__cTCPLink*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); -#endif - Mtolua_delete(self); - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - - -/* function to release collected object via destructor */ -#ifdef __cplusplus - -static int tolua_collect_Lua__cTCPLink (lua_State* tolua_S) -{ - Lua__cTCPLink* self = (Lua__cTCPLink*) tolua_tousertype(tolua_S,1,0); - delete self; - return 0; -} -#endif - -/* method: new of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new00 -static int tolua_AllToLua_Vector3f_new00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); - { - Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(*v)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new00_local -static int tolua_AllToLua_Vector3f_new00_local(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); - { - Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(*v)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new01 -static int tolua_AllToLua_Vector3f_new01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); - { - Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(v)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3f_new00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new01_local -static int tolua_AllToLua_Vector3f_new01_local(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); - { - Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(v)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3f_new00_local(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new02 -static int tolua_AllToLua_Vector3f_new02(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); - { - Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(*v)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3f_new01(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new02_local -static int tolua_AllToLua_Vector3f_new02_local(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); - { - Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(*v)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3f_new01_local(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new03 -static int tolua_AllToLua_Vector3f_new03(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); - { - Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(v)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3f_new02(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new03_local -static int tolua_AllToLua_Vector3f_new03_local(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); - { - Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(v)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3f_new02_local(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new04 -static int tolua_AllToLua_Vector3f_new04(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else - { - { - Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)()); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3f_new03(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new04_local -static int tolua_AllToLua_Vector3f_new04_local(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else - { - { - Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)()); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3f_new03_local(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new05 -static int tolua_AllToLua_Vector3f_new05(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else - { - float a_x = ((float) tolua_tonumber(tolua_S,2,0)); - float a_y = ((float) tolua_tonumber(tolua_S,3,0)); - float a_z = ((float) tolua_tonumber(tolua_S,4,0)); - { - Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(a_x,a_y,a_z)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3f_new04(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new05_local -static int tolua_AllToLua_Vector3f_new05_local(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else - { - float a_x = ((float) tolua_tonumber(tolua_S,2,0)); - float a_y = ((float) tolua_tonumber(tolua_S,3,0)); - float a_z = ((float) tolua_tonumber(tolua_S,4,0)); - { - Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(a_x,a_y,a_z)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3f_new04_local(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Set of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Set00 -static int tolua_AllToLua_Vector3f_Set00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Vector3f",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); - float a_x = ((float) tolua_tonumber(tolua_S,2,0)); - float a_y = ((float) tolua_tonumber(tolua_S,3,0)); - float a_z = ((float) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Set'", NULL); -#endif - { - self->Set(a_x,a_y,a_z); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Set'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Normalize of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Normalize00 -static int tolua_AllToLua_Vector3f_Normalize00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Vector3f",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Normalize'", NULL); -#endif - { - self->Normalize(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Normalize'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: NormalizeCopy of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_NormalizeCopy00 -static int tolua_AllToLua_Vector3f_NormalizeCopy00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NormalizeCopy'", NULL); -#endif - { - Vector3f tolua_ret = (Vector3f) self->NormalizeCopy(); - { -#ifdef __cplusplus - void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#else - void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#endif - } - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'NormalizeCopy'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: NormalizeCopy of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_NormalizeCopy01 -static int tolua_AllToLua_Vector3f_NormalizeCopy01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3f",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); - Vector3f* a_V = ((Vector3f*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NormalizeCopy'", NULL); -#endif - { - self->NormalizeCopy(*a_V); - } - } - return 0; -tolua_lerror: - return tolua_AllToLua_Vector3f_NormalizeCopy00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Length of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Length00 -static int tolua_AllToLua_Vector3f_Length00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Length'", NULL); -#endif - { - float tolua_ret = (float) self->Length(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Length'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SqrLength of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_SqrLength00 -static int tolua_AllToLua_Vector3f_SqrLength00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SqrLength'", NULL); -#endif - { - float tolua_ret = (float) self->SqrLength(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SqrLength'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Dot of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Dot00 -static int tolua_AllToLua_Vector3f_Dot00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); - const Vector3f* a_V = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Dot'", NULL); -#endif - { - float tolua_ret = (float) self->Dot(*a_V); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Dot'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Cross of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Cross00 -static int tolua_AllToLua_Vector3f_Cross00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); - const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Cross'", NULL); -#endif - { - Vector3f tolua_ret = (Vector3f) self->Cross(*v); - { -#ifdef __cplusplus - void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#else - void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#endif - } - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Cross'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Equals of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Equals00 -static int tolua_AllToLua_Vector3f_Equals00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); - const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Equals'", NULL); -#endif - { - bool tolua_ret = (bool) self->Equals(*v); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Equals'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: operator+ of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__add00 -static int tolua_AllToLua_Vector3f__add00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); - const Vector3f* v2 = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator+'", NULL); -#endif - { - Vector3f tolua_ret = (Vector3f) self->operator+(*v2); - { -#ifdef __cplusplus - void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#else - void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#endif - } - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function '.add'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: operator+ of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__add01 -static int tolua_AllToLua_Vector3f__add01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); - const Vector3f* v2 = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator+'", NULL); -#endif - { - Vector3f tolua_ret = (Vector3f) self->operator+(v2); - { -#ifdef __cplusplus - void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#else - void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#endif - } - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3f__add00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: operator- of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__sub00 -static int tolua_AllToLua_Vector3f__sub00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); - const Vector3f* v2 = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator-'", NULL); -#endif - { - Vector3f tolua_ret = (Vector3f) self->operator-(*v2); - { -#ifdef __cplusplus - void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#else - void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#endif - } - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function '.sub'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: operator- of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__sub01 -static int tolua_AllToLua_Vector3f__sub01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); - const Vector3f* v2 = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator-'", NULL); -#endif - { - Vector3f tolua_ret = (Vector3f) self->operator-(v2); - { -#ifdef __cplusplus - void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#else - void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#endif - } - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3f__sub00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: operator* of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__mul00 -static int tolua_AllToLua_Vector3f__mul00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); - const float f = ((const float) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator*'", NULL); -#endif - { - Vector3f tolua_ret = (Vector3f) self->operator*(f); - { -#ifdef __cplusplus - void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#else - void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#endif - } - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function '.mul'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: operator* of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__mul01 -static int tolua_AllToLua_Vector3f__mul01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); - const Vector3f* v2 = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator*'", NULL); -#endif - { - Vector3f tolua_ret = (Vector3f) self->operator*(*v2); - { -#ifdef __cplusplus - void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#else - void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#endif - } - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3f__mul00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: x of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_get_Vector3f_x -static int tolua_get_Vector3f_x(lua_State* tolua_S) -{ - Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->x); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: x of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_set_Vector3f_x -static int tolua_set_Vector3f_x(lua_State* tolua_S) -{ - Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->x = ((float) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: y of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_get_Vector3f_y -static int tolua_get_Vector3f_y(lua_State* tolua_S) -{ - Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->y); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: y of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_set_Vector3f_y -static int tolua_set_Vector3f_y(lua_State* tolua_S) -{ - Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->y = ((float) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: z of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_get_Vector3f_z -static int tolua_get_Vector3f_z(lua_State* tolua_S) -{ - Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->z); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: z of class Vector3f */ -#ifndef TOLUA_DISABLE_tolua_set_Vector3f_z -static int tolua_set_Vector3f_z(lua_State* tolua_S) -{ - Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->z = ((float) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new00 -static int tolua_AllToLua_Vector3d_new00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); - { - Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(*v)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new00_local -static int tolua_AllToLua_Vector3d_new00_local(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); - { - Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(*v)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new01 -static int tolua_AllToLua_Vector3d_new01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); - { - Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(v)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3d_new00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new01_local -static int tolua_AllToLua_Vector3d_new01_local(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); - { - Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(v)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3d_new00_local(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new02 -static int tolua_AllToLua_Vector3d_new02(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else - { - { - Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)()); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3d_new01(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new02_local -static int tolua_AllToLua_Vector3d_new02_local(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else - { - { - Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)()); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3d_new01_local(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new03 -static int tolua_AllToLua_Vector3d_new03(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else - { - double a_x = ((double) tolua_tonumber(tolua_S,2,0)); - double a_y = ((double) tolua_tonumber(tolua_S,3,0)); - double a_z = ((double) tolua_tonumber(tolua_S,4,0)); - { - Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(a_x,a_y,a_z)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3d_new02(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new03_local -static int tolua_AllToLua_Vector3d_new03_local(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else - { - double a_x = ((double) tolua_tonumber(tolua_S,2,0)); - double a_y = ((double) tolua_tonumber(tolua_S,3,0)); - double a_z = ((double) tolua_tonumber(tolua_S,4,0)); - { - Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(a_x,a_y,a_z)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3d_new02_local(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Set of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Set00 -static int tolua_AllToLua_Vector3d_Set00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Vector3d",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); - double a_x = ((double) tolua_tonumber(tolua_S,2,0)); - double a_y = ((double) tolua_tonumber(tolua_S,3,0)); - double a_z = ((double) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Set'", NULL); -#endif - { - self->Set(a_x,a_y,a_z); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Set'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Normalize of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Normalize00 -static int tolua_AllToLua_Vector3d_Normalize00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Vector3d",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Normalize'", NULL); -#endif - { - self->Normalize(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Normalize'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: NormalizeCopy of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_NormalizeCopy00 -static int tolua_AllToLua_Vector3d_NormalizeCopy00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Vector3d",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NormalizeCopy'", NULL); -#endif - { - Vector3d tolua_ret = (Vector3d) self->NormalizeCopy(); - { -#ifdef __cplusplus - void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#else - void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#endif - } - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'NormalizeCopy'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: NormalizeCopy of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_NormalizeCopy01 -static int tolua_AllToLua_Vector3d_NormalizeCopy01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Vector3d",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3d",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); - Vector3d* a_V = ((Vector3d*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NormalizeCopy'", NULL); -#endif - { - self->NormalizeCopy(*a_V); - } - } - return 0; -tolua_lerror: - return tolua_AllToLua_Vector3d_NormalizeCopy00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Length of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Length00 -static int tolua_AllToLua_Vector3d_Length00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Length'", NULL); -#endif - { - double tolua_ret = (double) self->Length(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Length'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SqrLength of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_SqrLength00 -static int tolua_AllToLua_Vector3d_SqrLength00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SqrLength'", NULL); -#endif - { - double tolua_ret = (double) self->SqrLength(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SqrLength'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Dot of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Dot00 -static int tolua_AllToLua_Vector3d_Dot00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); - const Vector3d* a_V = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Dot'", NULL); -#endif - { - double tolua_ret = (double) self->Dot(*a_V); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Dot'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Cross of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Cross00 -static int tolua_AllToLua_Vector3d_Cross00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); - const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Cross'", NULL); -#endif - { - Vector3d tolua_ret = (Vector3d) self->Cross(*v); - { -#ifdef __cplusplus - void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#else - void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#endif - } - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Cross'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Equals of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Equals00 -static int tolua_AllToLua_Vector3d_Equals00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); - const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Equals'", NULL); -#endif - { - bool tolua_ret = (bool) self->Equals(*v); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Equals'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: operator+ of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__add00 -static int tolua_AllToLua_Vector3d__add00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); - const Vector3d* v2 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator+'", NULL); -#endif - { - Vector3d tolua_ret = (Vector3d) self->operator+(*v2); - { -#ifdef __cplusplus - void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#else - void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#endif - } - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function '.add'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: operator+ of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__add01 -static int tolua_AllToLua_Vector3d__add01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); - const Vector3d* v2 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator+'", NULL); -#endif - { - Vector3d tolua_ret = (Vector3d) self->operator+(v2); - { -#ifdef __cplusplus - void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#else - void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#endif - } - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3d__add00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: operator- of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__sub00 -static int tolua_AllToLua_Vector3d__sub00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); - const Vector3d* v2 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator-'", NULL); -#endif - { - Vector3d tolua_ret = (Vector3d) self->operator-(*v2); - { -#ifdef __cplusplus - void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#else - void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#endif - } - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function '.sub'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: operator- of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__sub01 -static int tolua_AllToLua_Vector3d__sub01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); - const Vector3d* v2 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator-'", NULL); -#endif - { - Vector3d tolua_ret = (Vector3d) self->operator-(v2); - { -#ifdef __cplusplus - void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#else - void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#endif - } - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3d__sub00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: operator* of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__mul00 -static int tolua_AllToLua_Vector3d__mul00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); - const double f = ((const double) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator*'", NULL); -#endif - { - Vector3d tolua_ret = (Vector3d) self->operator*(f); - { -#ifdef __cplusplus - void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#else - void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#endif - } - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function '.mul'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: operator* of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__mul01 -static int tolua_AllToLua_Vector3d__mul01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); - const Vector3d* v2 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator*'", NULL); -#endif - { - Vector3d tolua_ret = (Vector3d) self->operator*(*v2); - { -#ifdef __cplusplus - void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#else - void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); - tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); -#endif - } - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3d__mul00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: x of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_get_Vector3d_x -static int tolua_get_Vector3d_x(lua_State* tolua_S) -{ - Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->x); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: x of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_set_Vector3d_x -static int tolua_set_Vector3d_x(lua_State* tolua_S) -{ - Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->x = ((double) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: y of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_get_Vector3d_y -static int tolua_get_Vector3d_y(lua_State* tolua_S) -{ - Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->y); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: y of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_set_Vector3d_y -static int tolua_set_Vector3d_y(lua_State* tolua_S) -{ - Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->y = ((double) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: z of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_get_Vector3d_z -static int tolua_get_Vector3d_z(lua_State* tolua_S) -{ - Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->z); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: z of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_set_Vector3d_z -static int tolua_set_Vector3d_z(lua_State* tolua_S) -{ - Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->z = ((double) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class Vector3i */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new00 -static int tolua_AllToLua_Vector3i_new00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); - { - Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)(*v)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class Vector3i */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new00_local -static int tolua_AllToLua_Vector3i_new00_local(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); - { - Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)(*v)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class Vector3i */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new01 -static int tolua_AllToLua_Vector3i_new01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else - { - { - Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)()); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i"); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3i_new00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class Vector3i */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new01_local -static int tolua_AllToLua_Vector3i_new01_local(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else - { - { - Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)()); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3i_new00_local(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class Vector3i */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new02 -static int tolua_AllToLua_Vector3i_new02(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else - { - int a_x = ((int) tolua_tonumber(tolua_S,2,0)); - int a_y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_z = ((int) tolua_tonumber(tolua_S,4,0)); - { - Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)(a_x,a_y,a_z)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i"); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3i_new01(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class Vector3i */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new02_local -static int tolua_AllToLua_Vector3i_new02_local(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else - { - int a_x = ((int) tolua_tonumber(tolua_S,2,0)); - int a_y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_z = ((int) tolua_tonumber(tolua_S,4,0)); - { - Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)(a_x,a_y,a_z)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3i_new01_local(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Set of class Vector3i */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_Set00 -static int tolua_AllToLua_Vector3i_Set00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Vector3i",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); - int a_x = ((int) tolua_tonumber(tolua_S,2,0)); - int a_y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_z = ((int) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Set'", NULL); -#endif - { - self->Set(a_x,a_y,a_z); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Set'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Length of class Vector3i */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_Length00 -static int tolua_AllToLua_Vector3i_Length00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3i",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3i* self = (const Vector3i*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Length'", NULL); -#endif - { - float tolua_ret = (float) self->Length(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Length'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SqrLength of class Vector3i */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_SqrLength00 -static int tolua_AllToLua_Vector3i_SqrLength00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3i",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3i* self = (const Vector3i*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SqrLength'", NULL); -#endif - { - int tolua_ret = (int) self->SqrLength(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SqrLength'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Equals of class Vector3i */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_Equals00 -static int tolua_AllToLua_Vector3i_Equals00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3i",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const Vector3i* self = (const Vector3i*) tolua_tousertype(tolua_S,1,0); - const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Equals'", NULL); -#endif - { - bool tolua_ret = (bool) self->Equals(*v); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Equals'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Equals of class Vector3i */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_Equals01 -static int tolua_AllToLua_Vector3i_Equals01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const Vector3i",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const Vector3i* self = (const Vector3i*) tolua_tousertype(tolua_S,1,0); - const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Equals'", NULL); -#endif - { - bool tolua_ret = (bool) self->Equals(v); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_Vector3i_Equals00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: x of class Vector3i */ -#ifndef TOLUA_DISABLE_tolua_get_Vector3i_x -static int tolua_get_Vector3i_x(lua_State* tolua_S) -{ - Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->x); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: x of class Vector3i */ -#ifndef TOLUA_DISABLE_tolua_set_Vector3i_x -static int tolua_set_Vector3i_x(lua_State* tolua_S) -{ - Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->x = ((int) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: y of class Vector3i */ -#ifndef TOLUA_DISABLE_tolua_get_Vector3i_y -static int tolua_get_Vector3i_y(lua_State* tolua_S) -{ - Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->y); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: y of class Vector3i */ -#ifndef TOLUA_DISABLE_tolua_set_Vector3i_y -static int tolua_set_Vector3i_y(lua_State* tolua_S) -{ - Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->y = ((int) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: z of class Vector3i */ -#ifndef TOLUA_DISABLE_tolua_get_Vector3i_z -static int tolua_get_Vector3i_z(lua_State* tolua_S) -{ - Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->z); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: z of class Vector3i */ -#ifndef TOLUA_DISABLE_tolua_set_Vector3i_z -static int tolua_set_Vector3i_z(lua_State* tolua_S) -{ - Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->z = ((int) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class cCuboid */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new00 -static int tolua_AllToLua_cCuboid_new00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - { - cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)()); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class cCuboid */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new00_local -static int tolua_AllToLua_cCuboid_new00_local(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - { - cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)()); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class cCuboid */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new01 -static int tolua_AllToLua_cCuboid_new01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cCuboid",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const cCuboid* a_Cuboid = ((const cCuboid*) tolua_tousertype(tolua_S,2,0)); - { - cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)(*a_Cuboid)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid"); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_cCuboid_new00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class cCuboid */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new01_local -static int tolua_AllToLua_cCuboid_new01_local(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cCuboid",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const cCuboid* a_Cuboid = ((const cCuboid*) tolua_tousertype(tolua_S,2,0)); - { - cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)(*a_Cuboid)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_cCuboid_new00_local(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class cCuboid */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new02 -static int tolua_AllToLua_cCuboid_new02(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || - (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3i",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else - { - const Vector3i* a_p1 = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); - const Vector3i* a_p2 = ((const Vector3i*) tolua_tousertype(tolua_S,3,0)); - { - cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)(*a_p1,*a_p2)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid"); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_cCuboid_new01(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class cCuboid */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new02_local -static int tolua_AllToLua_cCuboid_new02_local(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || - (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3i",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else - { - const Vector3i* a_p1 = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); - const Vector3i* a_p2 = ((const Vector3i*) tolua_tousertype(tolua_S,3,0)); - { - cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)(*a_p1,*a_p2)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_cCuboid_new01_local(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: p1 of class cCuboid */ -#ifndef TOLUA_DISABLE_tolua_get_cCuboid_p1 -static int tolua_get_cCuboid_p1(lua_State* tolua_S) -{ - cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'p1'",NULL); -#endif - tolua_pushusertype(tolua_S,(void*)&self->p1,"Vector3i"); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: p1 of class cCuboid */ -#ifndef TOLUA_DISABLE_tolua_set_cCuboid_p1 -static int tolua_set_cCuboid_p1(lua_State* tolua_S) -{ - cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'p1'",NULL); - if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3i",0,&tolua_err))) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->p1 = *((Vector3i*) tolua_tousertype(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: p2 of class cCuboid */ -#ifndef TOLUA_DISABLE_tolua_get_cCuboid_p2 -static int tolua_get_cCuboid_p2(lua_State* tolua_S) -{ - cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'p2'",NULL); -#endif - tolua_pushusertype(tolua_S,(void*)&self->p2,"Vector3i"); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: p2 of class cCuboid */ -#ifndef TOLUA_DISABLE_tolua_set_cCuboid_p2 -static int tolua_set_cCuboid_p2(lua_State* tolua_S) -{ - cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'p2'",NULL); - if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3i",0,&tolua_err))) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->p2 = *((Vector3i*) tolua_tousertype(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Sort of class cCuboid */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_Sort00 -static int tolua_AllToLua_cCuboid_Sort00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cCuboid",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Sort'", NULL); -#endif - { - self->Sort(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Sort'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: IsInside of class cCuboid */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_IsInside00 -static int tolua_AllToLua_cCuboid_IsInside00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cCuboid",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cCuboid* self = (const cCuboid*) tolua_tousertype(tolua_S,1,0); - const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsInside'", NULL); -#endif - { - bool tolua_ret = (bool) self->IsInside(*v); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'IsInside'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: IsInside of class cCuboid */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_IsInside01 -static int tolua_AllToLua_cCuboid_IsInside01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cCuboid",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - const cCuboid* self = (const cCuboid*) tolua_tousertype(tolua_S,1,0); - const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsInside'", NULL); -#endif - { - bool tolua_ret = (bool) self->IsInside(*v); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -tolua_lerror: - return tolua_AllToLua_cCuboid_IsInside00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class cMCLogger */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cMCLogger_new00 -static int tolua_AllToLua_cMCLogger_new00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cMCLogger",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - char* a_File = ((char*) tolua_tostring(tolua_S,2,0)); - { - cMCLogger* tolua_ret = (cMCLogger*) Mtolua_new((cMCLogger)(a_File)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cMCLogger"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class cMCLogger */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cMCLogger_new00_local -static int tolua_AllToLua_cMCLogger_new00_local(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cMCLogger",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - char* a_File = ((char*) tolua_tostring(tolua_S,2,0)); - { - cMCLogger* tolua_ret = (cMCLogger*) Mtolua_new((cMCLogger)(a_File)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cMCLogger"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: delete of class cMCLogger */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cMCLogger_delete00 -static int tolua_AllToLua_cMCLogger_delete00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cMCLogger",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cMCLogger* self = (cMCLogger*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); -#endif - Mtolua_delete(self); - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: LogSimple of class cMCLogger */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cMCLogger_LogSimple00 -static int tolua_AllToLua_cMCLogger_LogSimple00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cMCLogger",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,1,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cMCLogger* self = (cMCLogger*) tolua_tousertype(tolua_S,1,0); - const char* a_Text = ((const char*) tolua_tostring(tolua_S,2,0)); - int a_LogType = ((int) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'LogSimple'", NULL); -#endif - { - self->LogSimple(a_Text,a_LogType); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'LogSimple'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class cTracer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_new00 -static int tolua_AllToLua_cTracer_new00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cTracer",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); - { - cTracer* tolua_ret = (cTracer*) Mtolua_new((cTracer)(a_World)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cTracer"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class cTracer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_new00_local -static int tolua_AllToLua_cTracer_new00_local(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cTracer",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); - { - cTracer* tolua_ret = (cTracer*) Mtolua_new((cTracer)(a_World)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cTracer"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: delete of class cTracer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_delete00 -static int tolua_AllToLua_cTracer_delete00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cTracer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); -#endif - Mtolua_delete(self); - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Trace of class cTracer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_Trace00 -static int tolua_AllToLua_cTracer_Trace00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cTracer",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || - (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3f",0,&tolua_err)) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); - const Vector3f* a_Start = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); - const Vector3f* a_Direction = ((const Vector3f*) tolua_tousertype(tolua_S,3,0)); - int a_Distance = ((int) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Trace'", NULL); -#endif - { - int tolua_ret = (int) self->Trace(*a_Start,*a_Direction,a_Distance); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Trace'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetValues of class cTracer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_SetValues00 -static int tolua_AllToLua_cTracer_SetValues00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cTracer",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || - (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3f",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); - const Vector3f* a_Start = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); - const Vector3f* a_Direction = ((const Vector3f*) tolua_tousertype(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValues'", NULL); -#endif - { - self->SetValues(*a_Start,*a_Direction); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetValues'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: BlockHitPosition of class cTracer */ -#ifndef TOLUA_DISABLE_tolua_get_cTracer_BlockHitPosition -static int tolua_get_cTracer_BlockHitPosition(lua_State* tolua_S) -{ - cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'BlockHitPosition'",NULL); -#endif - tolua_pushusertype(tolua_S,(void*)&self->BlockHitPosition,"Vector3f"); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: BlockHitPosition of class cTracer */ -#ifndef TOLUA_DISABLE_tolua_set_cTracer_BlockHitPosition -static int tolua_set_cTracer_BlockHitPosition(lua_State* tolua_S) -{ - cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'BlockHitPosition'",NULL); - if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3f",0,&tolua_err))) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->BlockHitPosition = *((Vector3f*) tolua_tousertype(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: HitNormal of class cTracer */ -#ifndef TOLUA_DISABLE_tolua_get_cTracer_HitNormal -static int tolua_get_cTracer_HitNormal(lua_State* tolua_S) -{ - cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'HitNormal'",NULL); -#endif - tolua_pushusertype(tolua_S,(void*)&self->HitNormal,"Vector3f"); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: HitNormal of class cTracer */ -#ifndef TOLUA_DISABLE_tolua_set_cTracer_HitNormal -static int tolua_set_cTracer_HitNormal(lua_State* tolua_S) -{ - cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'HitNormal'",NULL); - if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3f",0,&tolua_err))) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->HitNormal = *((Vector3f*) tolua_tousertype(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: RealHit of class cTracer */ -#ifndef TOLUA_DISABLE_tolua_get_cTracer_RealHit -static int tolua_get_cTracer_RealHit(lua_State* tolua_S) -{ - cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'RealHit'",NULL); -#endif - tolua_pushusertype(tolua_S,(void*)&self->RealHit,"Vector3f"); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: RealHit of class cTracer */ -#ifndef TOLUA_DISABLE_tolua_set_cTracer_RealHit -static int tolua_set_cTracer_RealHit(lua_State* tolua_S) -{ - cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'RealHit'",NULL); - if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3f",0,&tolua_err))) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->RealHit = *((Vector3f*) tolua_tousertype(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetName of class cGroup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_SetName00 -static int tolua_AllToLua_cGroup_SetName00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0); - std::string a_Name = ((std::string) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetName'", NULL); -#endif - { - self->SetName(a_Name); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetName'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetName of class cGroup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_GetName00 -static int tolua_AllToLua_cGroup_GetName00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cGroup",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cGroup* self = (const cGroup*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL); -#endif - { - const std::string tolua_ret = (const std::string) self->GetName(); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetName'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetColor of class cGroup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_SetColor00 -static int tolua_AllToLua_cGroup_SetColor00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0); - std::string a_Color = ((std::string) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetColor'", NULL); -#endif - { - self->SetColor(a_Color); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetColor'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: AddCommand of class cGroup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_AddCommand00 -static int tolua_AllToLua_cGroup_AddCommand00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0); - std::string a_Command = ((std::string) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddCommand'", NULL); -#endif - { - self->AddCommand(a_Command); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'AddCommand'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: AddPermission of class cGroup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_AddPermission00 -static int tolua_AllToLua_cGroup_AddPermission00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0); - std::string a_Permission = ((std::string) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddPermission'", NULL); -#endif - { - self->AddPermission(a_Permission); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'AddPermission'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: InheritFrom of class cGroup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_InheritFrom00 -static int tolua_AllToLua_cGroup_InheritFrom00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cGroup",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0); - cGroup* a_Group = ((cGroup*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'InheritFrom'", NULL); -#endif - { - self->InheritFrom(a_Group); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'InheritFrom'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: HasCommand of class cGroup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_HasCommand00 -static int tolua_AllToLua_cGroup_HasCommand00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0); - std::string a_Command = ((std::string) tolua_tocppstring(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HasCommand'", NULL); -#endif - { - bool tolua_ret = (bool) self->HasCommand(a_Command); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'HasCommand'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetColor of class cGroup */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_GetColor00 -static int tolua_AllToLua_cGroup_GetColor00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cGroup",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cGroup* self = (const cGroup*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetColor'", NULL); -#endif - { - const AString tolua_ret = (const AString) self->GetColor(); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetColor'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_ProtocolVersion of class cPacket_Login */ -#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_m_ProtocolVersion -static int tolua_get_cPacket_Login_m_ProtocolVersion(lua_State* tolua_S) -{ - cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ProtocolVersion'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_ProtocolVersion); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_ProtocolVersion of class cPacket_Login */ -#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_m_ProtocolVersion -static int tolua_set_cPacket_Login_m_ProtocolVersion(lua_State* tolua_S) -{ - cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ProtocolVersion'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_ProtocolVersion = ((int) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_Username of class cPacket_Login */ -#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_m_Username -static int tolua_get_cPacket_Login_m_Username(lua_State* tolua_S) -{ - cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Username'",NULL); -#endif - tolua_pushcppstring(tolua_S,(const char*)self->m_Username); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_Username of class cPacket_Login */ -#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_m_Username -static int tolua_set_cPacket_Login_m_Username(lua_State* tolua_S) -{ - cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Username'",NULL); - if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_Username = ((AString) tolua_tocppstring(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_LevelType of class cPacket_Login */ -#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_m_LevelType -static int tolua_get_cPacket_Login_m_LevelType(lua_State* tolua_S) -{ - cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_LevelType'",NULL); -#endif - tolua_pushcppstring(tolua_S,(const char*)self->m_LevelType); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_LevelType of class cPacket_Login */ -#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_m_LevelType -static int tolua_set_cPacket_Login_m_LevelType(lua_State* tolua_S) -{ - cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_LevelType'",NULL); - if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_LevelType = ((AString) tolua_tocppstring(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_ServerMode of class cPacket_Login */ -#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_m_ServerMode -static int tolua_get_cPacket_Login_m_ServerMode(lua_State* tolua_S) -{ - cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ServerMode'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_ServerMode); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_ServerMode of class cPacket_Login */ -#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_m_ServerMode -static int tolua_set_cPacket_Login_m_ServerMode(lua_State* tolua_S) -{ - cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ServerMode'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_ServerMode = ((int) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_Difficulty of class cPacket_Login */ -#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_m_Difficulty -static int tolua_get_cPacket_Login_m_Difficulty(lua_State* tolua_S) -{ - cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Difficulty'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_Difficulty); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_Difficulty of class cPacket_Login */ -#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_m_Difficulty -static int tolua_set_cPacket_Login_m_Difficulty(lua_State* tolua_S) -{ - cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Difficulty'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_Difficulty = ((char) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_WorldHeight of class cPacket_Login */ -#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_unsigned_m_WorldHeight -static int tolua_get_cPacket_Login_unsigned_m_WorldHeight(lua_State* tolua_S) -{ - cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_WorldHeight'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_WorldHeight); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_WorldHeight of class cPacket_Login */ -#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_unsigned_m_WorldHeight -static int tolua_set_cPacket_Login_unsigned_m_WorldHeight(lua_State* tolua_S) -{ - cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_WorldHeight'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_WorldHeight = ((unsigned char) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_MaxPlayers of class cPacket_Login */ -#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_unsigned_m_MaxPlayers -static int tolua_get_cPacket_Login_unsigned_m_MaxPlayers(lua_State* tolua_S) -{ - cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_MaxPlayers'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_MaxPlayers); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_MaxPlayers of class cPacket_Login */ -#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_unsigned_m_MaxPlayers -static int tolua_set_cPacket_Login_unsigned_m_MaxPlayers(lua_State* tolua_S) -{ - cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_MaxPlayers'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_MaxPlayers = ((unsigned char) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class cPacket_BlockDig */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPacket_BlockDig_new00 -static int tolua_AllToLua_cPacket_BlockDig_new00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cPacket_BlockDig",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - { - cPacket_BlockDig* tolua_ret = (cPacket_BlockDig*) Mtolua_new((cPacket_BlockDig)()); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPacket_BlockDig"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class cPacket_BlockDig */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPacket_BlockDig_new00_local -static int tolua_AllToLua_cPacket_BlockDig_new00_local(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cPacket_BlockDig",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - { - cPacket_BlockDig* tolua_ret = (cPacket_BlockDig*) Mtolua_new((cPacket_BlockDig)()); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPacket_BlockDig"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Clone of class cPacket_BlockDig */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPacket_BlockDig_Clone00 -static int tolua_AllToLua_cPacket_BlockDig_Clone00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cPacket_BlockDig",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cPacket_BlockDig* self = (const cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clone'", NULL); -#endif - { - cPacket* tolua_ret = (cPacket*) self->Clone(); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPacket"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Clone'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_Status of class cPacket_BlockDig */ -#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockDig_m_Status -static int tolua_get_cPacket_BlockDig_m_Status(lua_State* tolua_S) -{ - cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Status'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_Status); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_Status of class cPacket_BlockDig */ -#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockDig_m_Status -static int tolua_set_cPacket_BlockDig_m_Status(lua_State* tolua_S) -{ - cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Status'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_Status = ((char) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_PosX of class cPacket_BlockDig */ -#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockDig_m_PosX -static int tolua_get_cPacket_BlockDig_m_PosX(lua_State* tolua_S) -{ - cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosX'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_PosX); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_PosX of class cPacket_BlockDig */ -#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockDig_m_PosX -static int tolua_set_cPacket_BlockDig_m_PosX(lua_State* tolua_S) -{ - cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosX'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_PosX = ((int) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_PosY of class cPacket_BlockDig */ -#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockDig_m_PosY -static int tolua_get_cPacket_BlockDig_m_PosY(lua_State* tolua_S) -{ - cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosY'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_PosY); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_PosY of class cPacket_BlockDig */ -#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockDig_m_PosY -static int tolua_set_cPacket_BlockDig_m_PosY(lua_State* tolua_S) -{ - cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosY'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_PosY = ((char) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_PosZ of class cPacket_BlockDig */ -#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockDig_m_PosZ -static int tolua_get_cPacket_BlockDig_m_PosZ(lua_State* tolua_S) -{ - cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosZ'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_PosZ); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_PosZ of class cPacket_BlockDig */ -#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockDig_m_PosZ -static int tolua_set_cPacket_BlockDig_m_PosZ(lua_State* tolua_S) -{ - cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosZ'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_PosZ = ((int) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_Direction of class cPacket_BlockDig */ -#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockDig_m_Direction -static int tolua_get_cPacket_BlockDig_m_Direction(lua_State* tolua_S) -{ - cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Direction'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_Direction); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_Direction of class cPacket_BlockDig */ -#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockDig_m_Direction -static int tolua_set_cPacket_BlockDig_m_Direction(lua_State* tolua_S) -{ - cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Direction'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_Direction = ((char) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - - class Lua__cPacket_BlockDig : public cPacket_BlockDig, public ToluaBase { -public: - cPacket* Clone( void )const { - if (push_method("Clone", tolua_AllToLua_cPacket_BlockDig_Clone00)) { - ToluaBase::dbcall(lua_state, 1, 1); - cPacket* tolua_ret = ( cPacket* )tolua_tousertype(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( cPacket* ) cPacket_BlockDig:: Clone(); - }; - }; - - cPacket* cPacket_BlockDig__Clone( void ) { - return ( cPacket* )cPacket_BlockDig::Clone(); - }; - Lua__cPacket_BlockDig( void ): cPacket_BlockDig(){}; -}; - -/* method: tolua__set_instance of class Lua__cPacket_BlockDig */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPacket_BlockDig_tolua__set_instance00 -static int tolua_AllToLua_Lua__cPacket_BlockDig_tolua__set_instance00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPacket_BlockDig",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPacket_BlockDig* self = (Lua__cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); - lua_State* L = tolua_S; - lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); -#endif - { - self->tolua__set_instance(L,lo); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: cPacket_BlockDig__Clone of class Lua__cPacket_BlockDig */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPacket_BlockDig_cPacket_BlockDig__Clone00 -static int tolua_AllToLua_Lua__cPacket_BlockDig_cPacket_BlockDig__Clone00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPacket_BlockDig",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPacket_BlockDig* self = (Lua__cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPacket_BlockDig__Clone'", NULL); -#endif - { - cPacket* tolua_ret = (cPacket*) self->cPacket_BlockDig__Clone(); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPacket"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPacket_BlockDig__Clone'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class Lua__cPacket_BlockDig */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPacket_BlockDig_new00 -static int tolua_AllToLua_Lua__cPacket_BlockDig_new00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Lua__cPacket_BlockDig",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - { - Lua__cPacket_BlockDig* tolua_ret = (Lua__cPacket_BlockDig*) Mtolua_new((Lua__cPacket_BlockDig)()); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPacket_BlockDig"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class Lua__cPacket_BlockDig */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPacket_BlockDig_new00_local -static int tolua_AllToLua_Lua__cPacket_BlockDig_new00_local(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"Lua__cPacket_BlockDig",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - { - Lua__cPacket_BlockDig* tolua_ret = (Lua__cPacket_BlockDig*) Mtolua_new((Lua__cPacket_BlockDig)()); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPacket_BlockDig"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - - -/* function to release collected object via destructor */ -#ifdef __cplusplus - -static int tolua_collect_Lua__cPacket_BlockDig (lua_State* tolua_S) -{ - Lua__cPacket_BlockDig* self = (Lua__cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); - delete self; - return 0; -} -#endif - -/* get function: m_PosX of class cPacket_BlockPlace */ -#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_PosX -static int tolua_get_cPacket_BlockPlace_m_PosX(lua_State* tolua_S) -{ - cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosX'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_PosX); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_PosX of class cPacket_BlockPlace */ -#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_PosX -static int tolua_set_cPacket_BlockPlace_m_PosX(lua_State* tolua_S) -{ - cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosX'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_PosX = ((int) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_PosY of class cPacket_BlockPlace */ -#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_unsigned_m_PosY -static int tolua_get_cPacket_BlockPlace_unsigned_m_PosY(lua_State* tolua_S) -{ - cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosY'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_PosY); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_PosY of class cPacket_BlockPlace */ -#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_unsigned_m_PosY -static int tolua_set_cPacket_BlockPlace_unsigned_m_PosY(lua_State* tolua_S) -{ - cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosY'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_PosY = ((unsigned char) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_PosZ of class cPacket_BlockPlace */ -#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_PosZ -static int tolua_get_cPacket_BlockPlace_m_PosZ(lua_State* tolua_S) -{ - cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosZ'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_PosZ); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_PosZ of class cPacket_BlockPlace */ -#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_PosZ -static int tolua_set_cPacket_BlockPlace_m_PosZ(lua_State* tolua_S) -{ - cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosZ'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_PosZ = ((int) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_Direction of class cPacket_BlockPlace */ -#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_Direction -static int tolua_get_cPacket_BlockPlace_m_Direction(lua_State* tolua_S) -{ - cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Direction'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_Direction); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_Direction of class cPacket_BlockPlace */ -#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_Direction -static int tolua_set_cPacket_BlockPlace_m_Direction(lua_State* tolua_S) -{ - cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Direction'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_Direction = ((char) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_ItemType of class cPacket_BlockPlace */ -#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_ItemType -static int tolua_get_cPacket_BlockPlace_m_ItemType(lua_State* tolua_S) -{ - cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemType'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_ItemType); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_ItemType of class cPacket_BlockPlace */ -#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_ItemType -static int tolua_set_cPacket_BlockPlace_m_ItemType(lua_State* tolua_S) -{ - cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemType'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_ItemType = ((short) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_Count of class cPacket_BlockPlace */ -#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_Count -static int tolua_get_cPacket_BlockPlace_m_Count(lua_State* tolua_S) -{ - cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Count'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_Count); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_Count of class cPacket_BlockPlace */ -#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_Count -static int tolua_set_cPacket_BlockPlace_m_Count(lua_State* tolua_S) -{ - cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Count'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_Count = ((char) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: m_Uses of class cPacket_BlockPlace */ -#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_Uses -static int tolua_get_cPacket_BlockPlace_m_Uses(lua_State* tolua_S) -{ - cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Uses'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_Uses); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_Uses of class cPacket_BlockPlace */ -#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_Uses -static int tolua_set_cPacket_BlockPlace_m_Uses(lua_State* tolua_S) -{ - cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Uses'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_Uses = ((short) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* method: FillBlocks of class cLuaChunk */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_FillBlocks00 -static int tolua_AllToLua_cLuaChunk_FillBlocks00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); - char a_BlockID = ((char) tolua_tonumber(tolua_S,2,0)); - unsigned char a_BlockMeta = ((unsigned char) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'FillBlocks'", NULL); -#endif - { - self->FillBlocks(a_BlockID,a_BlockMeta); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'FillBlocks'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetBlock of class cLuaChunk */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetBlock00 -static int tolua_AllToLua_cLuaChunk_SetBlock00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnumber(tolua_S,5,0,&tolua_err) || - !tolua_isnumber(tolua_S,6,0,&tolua_err) || - !tolua_isnoobj(tolua_S,7,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); - char a_BlockID = ((char) tolua_tonumber(tolua_S,5,0)); - unsigned char a_BlockMeta = ((unsigned char) tolua_tonumber(tolua_S,6,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBlock'", NULL); -#endif - { - self->SetBlock(a_X,a_Y,a_Z,a_BlockID,a_BlockMeta); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetBlock'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetBlock of class cLuaChunk */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_GetBlock00 -static int tolua_AllToLua_cLuaChunk_GetBlock00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlock'", NULL); -#endif - { - char tolua_ret = (char) self->GetBlock(a_X,a_Y,a_Z); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetBlock'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetBlockMeta of class cLuaChunk */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_GetBlockMeta00 -static int tolua_AllToLua_cLuaChunk_GetBlockMeta00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockMeta'", NULL); -#endif - { - char tolua_ret = (char) self->GetBlockMeta(a_X,a_Y,a_Z); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetBlockMeta'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetBiome of class cLuaChunk */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetBiome00 -static int tolua_AllToLua_cLuaChunk_SetBiome00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,3,0)); - int a_BiomeID = ((int) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBiome'", NULL); -#endif - { - self->SetBiome(a_X,a_Z,a_BiomeID); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetBiome'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetBiome of class cLuaChunk */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_GetBiome00 -static int tolua_AllToLua_cLuaChunk_GetBiome00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBiome'", NULL); -#endif - { - int tolua_ret = (int) self->GetBiome(a_X,a_Z); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetBiome'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetHeight of class cLuaChunk */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetHeight00 -static int tolua_AllToLua_cLuaChunk_SetHeight00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,3,0)); - int a_Height = ((int) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetHeight'", NULL); -#endif - { - self->SetHeight(a_X,a_Z,a_Height); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetHeight'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetHeight of class cLuaChunk */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_GetHeight00 -static int tolua_AllToLua_cLuaChunk_GetHeight00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); - int a_X = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Z = ((int) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHeight'", NULL); -#endif - { - int tolua_ret = (int) self->GetHeight(a_X,a_Z); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetHeight'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetUseDefaultBiomes of class cLuaChunk */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetUseDefaultBiomes00 -static int tolua_AllToLua_cLuaChunk_SetUseDefaultBiomes00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || - !tolua_isboolean(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); - bool a_bUseDefaultBiomes = ((bool) tolua_toboolean(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetUseDefaultBiomes'", NULL); -#endif - { - self->SetUseDefaultBiomes(a_bUseDefaultBiomes); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetUseDefaultBiomes'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: IsUsingDefaultBiomes of class cLuaChunk */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_IsUsingDefaultBiomes00 -static int tolua_AllToLua_cLuaChunk_IsUsingDefaultBiomes00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsUsingDefaultBiomes'", NULL); -#endif - { - bool tolua_ret = (bool) self->IsUsingDefaultBiomes(); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'IsUsingDefaultBiomes'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetUseDefaultComposition of class cLuaChunk */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetUseDefaultComposition00 -static int tolua_AllToLua_cLuaChunk_SetUseDefaultComposition00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || - !tolua_isboolean(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); - bool a_bUseDefaultComposition = ((bool) tolua_toboolean(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetUseDefaultComposition'", NULL); -#endif - { - self->SetUseDefaultComposition(a_bUseDefaultComposition); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetUseDefaultComposition'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: IsUsingDefaultComposition of class cLuaChunk */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_IsUsingDefaultComposition00 -static int tolua_AllToLua_cLuaChunk_IsUsingDefaultComposition00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsUsingDefaultComposition'", NULL); -#endif - { - bool tolua_ret = (bool) self->IsUsingDefaultComposition(); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'IsUsingDefaultComposition'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetUseDefaultStructures of class cLuaChunk */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetUseDefaultStructures00 -static int tolua_AllToLua_cLuaChunk_SetUseDefaultStructures00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || - !tolua_isboolean(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); - bool a_bUseDefaultStructures = ((bool) tolua_toboolean(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetUseDefaultStructures'", NULL); -#endif - { - self->SetUseDefaultStructures(a_bUseDefaultStructures); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetUseDefaultStructures'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: IsUsingDefaultStructures of class cLuaChunk */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_IsUsingDefaultStructures00 -static int tolua_AllToLua_cLuaChunk_IsUsingDefaultStructures00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsUsingDefaultStructures'", NULL); -#endif - { - bool tolua_ret = (bool) self->IsUsingDefaultStructures(); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'IsUsingDefaultStructures'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetUseDefaultFinish of class cLuaChunk */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetUseDefaultFinish00 -static int tolua_AllToLua_cLuaChunk_SetUseDefaultFinish00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || - !tolua_isboolean(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); - bool a_bUseDefaultFinish = ((bool) tolua_toboolean(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetUseDefaultFinish'", NULL); -#endif - { - self->SetUseDefaultFinish(a_bUseDefaultFinish); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetUseDefaultFinish'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: IsUsingDefaultFinish of class cLuaChunk */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_IsUsingDefaultFinish00 -static int tolua_AllToLua_cLuaChunk_IsUsingDefaultFinish00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsUsingDefaultFinish'", NULL); -#endif - { - bool tolua_ret = (bool) self->IsUsingDefaultFinish(); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'IsUsingDefaultFinish'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new of class cCraftingGrid */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_new00 -static int tolua_AllToLua_cCraftingGrid_new00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cCraftingGrid",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - int a_Width = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Height = ((int) tolua_tonumber(tolua_S,3,0)); - { - cCraftingGrid* tolua_ret = (cCraftingGrid*) Mtolua_new((cCraftingGrid)(a_Width,a_Height)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCraftingGrid"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: new_local of class cCraftingGrid */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_new00_local -static int tolua_AllToLua_cCraftingGrid_new00_local(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertable(tolua_S,1,"cCraftingGrid",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - int a_Width = ((int) tolua_tonumber(tolua_S,2,0)); - int a_Height = ((int) tolua_tonumber(tolua_S,3,0)); - { - cCraftingGrid* tolua_ret = (cCraftingGrid*) Mtolua_new((cCraftingGrid)(a_Width,a_Height)); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCraftingGrid"); - tolua_register_gc(tolua_S,lua_gettop(tolua_S)); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetWidth of class cCraftingGrid */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_GetWidth00 -static int tolua_AllToLua_cCraftingGrid_GetWidth00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cCraftingGrid",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cCraftingGrid* self = (const cCraftingGrid*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWidth'", NULL); -#endif - { - int tolua_ret = (int) self->GetWidth(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetWidth'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetHeight of class cCraftingGrid */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_GetHeight00 -static int tolua_AllToLua_cCraftingGrid_GetHeight00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cCraftingGrid",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cCraftingGrid* self = (const cCraftingGrid*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHeight'", NULL); -#endif - { - int tolua_ret = (int) self->GetHeight(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetHeight'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetItem of class cCraftingGrid */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_GetItem00 -static int tolua_AllToLua_cCraftingGrid_GetItem00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cCraftingGrid",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cCraftingGrid* self = (const cCraftingGrid*) tolua_tousertype(tolua_S,1,0); - int x = ((int) tolua_tonumber(tolua_S,2,0)); - int y = ((int) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetItem'", NULL); -#endif - { - cItem& tolua_ret = (cItem&) self->GetItem(x,y); - tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cItem"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetItem'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetItem of class cCraftingGrid */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_SetItem00 -static int tolua_AllToLua_cCraftingGrid_SetItem00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cCraftingGrid",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnumber(tolua_S,5,0,&tolua_err) || - !tolua_isnumber(tolua_S,6,0,&tolua_err) || - !tolua_isnoobj(tolua_S,7,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0); - int x = ((int) tolua_tonumber(tolua_S,2,0)); - int y = ((int) tolua_tonumber(tolua_S,3,0)); - ENUM_ITEM_ID a_ItemType = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,4,0)); - int a_ItemCount = ((int) tolua_tonumber(tolua_S,5,0)); - short a_ItemHealth = ((short) tolua_tonumber(tolua_S,6,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetItem'", NULL); -#endif - { - self->SetItem(x,y,a_ItemType,a_ItemCount,a_ItemHealth); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetItem'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetItem of class cCraftingGrid */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_SetItem01 -static int tolua_AllToLua_cCraftingGrid_SetItem01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cCraftingGrid",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - (tolua_isvaluenil(tolua_S,4,&tolua_err) || !tolua_isusertype(tolua_S,4,"const cItem",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else - { - cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0); - int x = ((int) tolua_tonumber(tolua_S,2,0)); - int y = ((int) tolua_tonumber(tolua_S,3,0)); - const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetItem'", NULL); -#endif - { - self->SetItem(x,y,*a_Item); - } - } - return 0; -tolua_lerror: - return tolua_AllToLua_cCraftingGrid_SetItem00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Clear of class cCraftingGrid */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_Clear00 -static int tolua_AllToLua_cCraftingGrid_Clear00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cCraftingGrid",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL); -#endif - { - self->Clear(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: ConsumeGrid of class cCraftingGrid */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_ConsumeGrid00 -static int tolua_AllToLua_cCraftingGrid_ConsumeGrid00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cCraftingGrid",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cCraftingGrid",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0); - const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ConsumeGrid'", NULL); -#endif - { - self->ConsumeGrid(*a_Grid); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'ConsumeGrid'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Dump of class cCraftingGrid */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_Dump00 -static int tolua_AllToLua_cCraftingGrid_Dump00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cCraftingGrid",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Dump'", NULL); -#endif - { - self->Dump(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Dump'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Clear of class cCraftingRecipe */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_Clear00 -static int tolua_AllToLua_cCraftingRecipe_Clear00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL); -#endif - { - self->Clear(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetIngredientsWidth of class cCraftingRecipe */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_GetIngredientsWidth00 -static int tolua_AllToLua_cCraftingRecipe_GetIngredientsWidth00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cCraftingRecipe",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cCraftingRecipe* self = (const cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetIngredientsWidth'", NULL); -#endif - { - int tolua_ret = (int) self->GetIngredientsWidth(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetIngredientsWidth'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetIngredientsHeight of class cCraftingRecipe */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_GetIngredientsHeight00 -static int tolua_AllToLua_cCraftingRecipe_GetIngredientsHeight00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cCraftingRecipe",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cCraftingRecipe* self = (const cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetIngredientsHeight'", NULL); -#endif - { - int tolua_ret = (int) self->GetIngredientsHeight(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetIngredientsHeight'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetIngredient of class cCraftingRecipe */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_GetIngredient00 -static int tolua_AllToLua_cCraftingRecipe_GetIngredient00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cCraftingRecipe",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cCraftingRecipe* self = (const cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); - int x = ((int) tolua_tonumber(tolua_S,2,0)); - int y = ((int) tolua_tonumber(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetIngredient'", NULL); -#endif - { - cItem& tolua_ret = (cItem&) self->GetIngredient(x,y); - tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cItem"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetIngredient'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetResult of class cCraftingRecipe */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_GetResult00 -static int tolua_AllToLua_cCraftingRecipe_GetResult00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cCraftingRecipe",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cCraftingRecipe* self = (const cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetResult'", NULL); -#endif - { - const cItem& tolua_ret = (const cItem&) self->GetResult(); - tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const cItem"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetResult'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetResult of class cCraftingRecipe */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_SetResult00 -static int tolua_AllToLua_cCraftingRecipe_SetResult00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); - ENUM_ITEM_ID a_ItemType = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,0)); - int a_ItemCount = ((int) tolua_tonumber(tolua_S,3,0)); - short a_ItemHealth = ((short) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetResult'", NULL); -#endif - { - self->SetResult(a_ItemType,a_ItemCount,a_ItemHealth); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetResult'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetResult of class cCraftingRecipe */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_SetResult01 -static int tolua_AllToLua_cCraftingRecipe_SetResult01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cItem",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else - { - cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); - const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetResult'", NULL); -#endif - { - self->SetResult(*a_Item); - } - } - return 0; -tolua_lerror: - return tolua_AllToLua_cCraftingRecipe_SetResult00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetIngredient of class cCraftingRecipe */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_SetIngredient00 -static int tolua_AllToLua_cCraftingRecipe_SetIngredient00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnumber(tolua_S,5,0,&tolua_err) || - !tolua_isnumber(tolua_S,6,0,&tolua_err) || - !tolua_isnoobj(tolua_S,7,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); - int x = ((int) tolua_tonumber(tolua_S,2,0)); - int y = ((int) tolua_tonumber(tolua_S,3,0)); - ENUM_ITEM_ID a_ItemType = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,4,0)); - int a_ItemCount = ((int) tolua_tonumber(tolua_S,5,0)); - short a_ItemHealth = ((short) tolua_tonumber(tolua_S,6,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetIngredient'", NULL); -#endif - { - self->SetIngredient(x,y,a_ItemType,a_ItemCount,a_ItemHealth); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetIngredient'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetIngredient of class cCraftingRecipe */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_SetIngredient01 -static int tolua_AllToLua_cCraftingRecipe_SetIngredient01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - (tolua_isvaluenil(tolua_S,4,&tolua_err) || !tolua_isusertype(tolua_S,4,"const cItem",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else - { - cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); - int x = ((int) tolua_tonumber(tolua_S,2,0)); - int y = ((int) tolua_tonumber(tolua_S,3,0)); - const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetIngredient'", NULL); -#endif - { - self->SetIngredient(x,y,*a_Item); - } - } - return 0; -tolua_lerror: - return tolua_AllToLua_cCraftingRecipe_SetIngredient00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: ConsumeIngredients of class cCraftingRecipe */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_ConsumeIngredients00 -static int tolua_AllToLua_cCraftingRecipe_ConsumeIngredients00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cCraftingGrid",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); - cCraftingGrid* a_CraftingGrid = ((cCraftingGrid*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ConsumeIngredients'", NULL); -#endif - { - self->ConsumeIngredients(*a_CraftingGrid); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'ConsumeIngredients'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Dump of class cCraftingRecipe */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_Dump00 -static int tolua_AllToLua_cCraftingRecipe_Dump00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Dump'", NULL); -#endif - { - self->Dump(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Dump'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Get of class cLuaItems */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Get00 -static int tolua_AllToLua_cLuaItems_Get00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); - int a_Idx = ((int) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Get'", NULL); -#endif - { - cItem& tolua_ret = (cItem&) self->Get(a_Idx); - tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cItem"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Get'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Set of class cLuaItems */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Set00 -static int tolua_AllToLua_cLuaItems_Set00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const cItem",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); - int a_Idx = ((int) tolua_tonumber(tolua_S,2,0)); - const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,3,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Set'", NULL); -#endif - { - self->Set(a_Idx,*a_Item); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Set'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Add of class cLuaItems */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Add00 -static int tolua_AllToLua_cLuaItems_Add00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cItem",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); - const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Add'", NULL); -#endif - { - self->Add(*a_Item); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Add'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Delete of class cLuaItems */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Delete00 -static int tolua_AllToLua_cLuaItems_Delete00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); - int a_Idx = ((int) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Delete'", NULL); -#endif - { - self->Delete(a_Idx); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Delete'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Clear of class cLuaItems */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Clear00 -static int tolua_AllToLua_cLuaItems_Clear00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL); -#endif - { - self->Clear(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Size of class cLuaItems */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Size00 -static int tolua_AllToLua_cLuaItems_Size00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Size'", NULL); -#endif - { - int tolua_ret = (int) self->Size(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Size'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Add of class cLuaItems */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Add01 -static int tolua_AllToLua_cLuaItems_Add01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else - { - cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); - ENUM_ITEM_ID a_ItemType = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,0)); - char a_ItemCount = ((char) tolua_tonumber(tolua_S,3,0)); - short a_ItemHealth = ((short) tolua_tonumber(tolua_S,4,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Add'", NULL); -#endif - { - self->Add(a_ItemType,a_ItemCount,a_ItemHealth); - } - } - return 0; -tolua_lerror: - return tolua_AllToLua_cLuaItems_Add00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* method: Set of class cLuaItems */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Set01 -static int tolua_AllToLua_cLuaItems_Set01(lua_State* tolua_S) -{ - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnumber(tolua_S,3,0,&tolua_err) || - !tolua_isnumber(tolua_S,4,0,&tolua_err) || - !tolua_isnumber(tolua_S,5,0,&tolua_err) || - !tolua_isnoobj(tolua_S,6,&tolua_err) - ) - goto tolua_lerror; - else - { - cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); - int a_Idx = ((int) tolua_tonumber(tolua_S,2,0)); - ENUM_ITEM_ID a_ItemType = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,3,0)); - char a_ItemCount = ((char) tolua_tonumber(tolua_S,4,0)); - short a_ItemHealth = ((short) tolua_tonumber(tolua_S,5,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Set'", NULL); -#endif - { - self->Set(a_Idx,a_ItemType,a_ItemCount,a_ItemHealth); - } - } - return 0; -tolua_lerror: - return tolua_AllToLua_cLuaItems_Set00(tolua_S); -} -#endif //#ifndef TOLUA_DISABLE - -/* Open function */ -TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) -{ - tolua_open(tolua_S); - tolua_reg_types(tolua_S); - tolua_module(tolua_S,NULL,1); - tolua_beginmodule(tolua_S,NULL); - tolua_cclass(tolua_S,"cTorch","cTorch","",NULL); - tolua_beginmodule(tolua_S,"cTorch"); - tolua_function(tolua_S,"DirectionToMetaData",tolua_AllToLua_cTorch_DirectionToMetaData00); - tolua_function(tolua_S,"MetaDataToDirection",tolua_AllToLua_cTorch_MetaDataToDirection00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cStairs","cStairs","",NULL); - tolua_beginmodule(tolua_S,"cStairs"); - tolua_function(tolua_S,"RotationToMetaData",tolua_AllToLua_cStairs_RotationToMetaData00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cStep","cStep","",NULL); - tolua_beginmodule(tolua_S,"cStep"); - tolua_function(tolua_S,"DirectionToMetaData",tolua_AllToLua_cStep_DirectionToMetaData00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cLadder","cLadder","",NULL); - tolua_beginmodule(tolua_S,"cLadder"); - tolua_function(tolua_S,"DirectionToMetaData",tolua_AllToLua_cLadder_DirectionToMetaData00); - tolua_function(tolua_S,"MetaDataToDirection",tolua_AllToLua_cLadder_MetaDataToDirection00); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"cIniFile","cIniFile","",tolua_collect_cIniFile); - #else - tolua_cclass(tolua_S,"cIniFile","cIniFile","",NULL); - #endif - tolua_beginmodule(tolua_S,"cIniFile"); - tolua_constant(tolua_S,"noID",cIniFile::noID); - tolua_function(tolua_S,"new",tolua_AllToLua_cIniFile_new00); - tolua_function(tolua_S,"new_local",tolua_AllToLua_cIniFile_new00_local); - tolua_function(tolua_S,".call",tolua_AllToLua_cIniFile_new00_local); - tolua_function(tolua_S,"CaseSensitive",tolua_AllToLua_cIniFile_CaseSensitive00); - tolua_function(tolua_S,"CaseInsensitive",tolua_AllToLua_cIniFile_CaseInsensitive00); - tolua_function(tolua_S,"Path",tolua_AllToLua_cIniFile_Path00); - tolua_function(tolua_S,"Path",tolua_AllToLua_cIniFile_Path01); - tolua_function(tolua_S,"SetPath",tolua_AllToLua_cIniFile_SetPath00); - tolua_function(tolua_S,"ReadFile",tolua_AllToLua_cIniFile_ReadFile00); - tolua_function(tolua_S,"WriteFile",tolua_AllToLua_cIniFile_WriteFile00); - tolua_function(tolua_S,"Erase",tolua_AllToLua_cIniFile_Erase00); - tolua_function(tolua_S,"Clear",tolua_AllToLua_cIniFile_Clear00); - tolua_function(tolua_S,"Reset",tolua_AllToLua_cIniFile_Reset00); - tolua_function(tolua_S,"FindKey",tolua_AllToLua_cIniFile_FindKey00); - tolua_function(tolua_S,"FindValue",tolua_AllToLua_cIniFile_FindValue00); - tolua_function(tolua_S,"NumKeys",tolua_AllToLua_cIniFile_NumKeys00); - tolua_function(tolua_S,"GetNumKeys",tolua_AllToLua_cIniFile_GetNumKeys00); - tolua_function(tolua_S,"AddKeyName",tolua_AllToLua_cIniFile_AddKeyName00); - tolua_function(tolua_S,"KeyName",tolua_AllToLua_cIniFile_KeyName00); - tolua_function(tolua_S,"GetKeyName",tolua_AllToLua_cIniFile_GetKeyName00); - tolua_function(tolua_S,"NumValues",tolua_AllToLua_cIniFile_NumValues00); - tolua_function(tolua_S,"GetNumValues",tolua_AllToLua_cIniFile_GetNumValues00); - tolua_function(tolua_S,"NumValues",tolua_AllToLua_cIniFile_NumValues01); - tolua_function(tolua_S,"GetNumValues",tolua_AllToLua_cIniFile_GetNumValues01); - tolua_function(tolua_S,"ValueName",tolua_AllToLua_cIniFile_ValueName00); - tolua_function(tolua_S,"GetValueName",tolua_AllToLua_cIniFile_GetValueName00); - tolua_function(tolua_S,"ValueName",tolua_AllToLua_cIniFile_ValueName01); - tolua_function(tolua_S,"GetValueName",tolua_AllToLua_cIniFile_GetValueName01); - tolua_function(tolua_S,"GetValue",tolua_AllToLua_cIniFile_GetValue00); - tolua_function(tolua_S,"GetValue",tolua_AllToLua_cIniFile_GetValue01); - tolua_function(tolua_S,"GetValue",tolua_AllToLua_cIniFile_GetValue02); - tolua_function(tolua_S,"GetValue",tolua_AllToLua_cIniFile_GetValue03); - tolua_function(tolua_S,"GetValueF",tolua_AllToLua_cIniFile_GetValueF00); - tolua_function(tolua_S,"GetValueI",tolua_AllToLua_cIniFile_GetValueI00); - tolua_function(tolua_S,"GetValueB",tolua_AllToLua_cIniFile_GetValueB00); - tolua_function(tolua_S,"GetValueSet",tolua_AllToLua_cIniFile_GetValueSet00); - tolua_function(tolua_S,"GetValueSet",tolua_AllToLua_cIniFile_GetValueSet01); - tolua_function(tolua_S,"GetValueSetF",tolua_AllToLua_cIniFile_GetValueSetF00); - tolua_function(tolua_S,"GetValueSetI",tolua_AllToLua_cIniFile_GetValueSetI00); - tolua_function(tolua_S,"GetValueSetB",tolua_AllToLua_cIniFile_GetValueSetB00); - tolua_function(tolua_S,"SetValue",tolua_AllToLua_cIniFile_SetValue00); - tolua_function(tolua_S,"SetValue",tolua_AllToLua_cIniFile_SetValue01); - tolua_function(tolua_S,"SetValueI",tolua_AllToLua_cIniFile_SetValueI00); - tolua_function(tolua_S,"SetValueB",tolua_AllToLua_cIniFile_SetValueB00); - tolua_function(tolua_S,"SetValueF",tolua_AllToLua_cIniFile_SetValueF00); - tolua_function(tolua_S,"DeleteValueByID",tolua_AllToLua_cIniFile_DeleteValueByID00); - tolua_function(tolua_S,"DeleteValue",tolua_AllToLua_cIniFile_DeleteValue00); - tolua_function(tolua_S,"DeleteKey",tolua_AllToLua_cIniFile_DeleteKey00); - tolua_function(tolua_S,"NumHeaderComments",tolua_AllToLua_cIniFile_NumHeaderComments00); - tolua_function(tolua_S,"HeaderComment",tolua_AllToLua_cIniFile_HeaderComment00); - tolua_function(tolua_S,"HeaderComment",tolua_AllToLua_cIniFile_HeaderComment01); - tolua_function(tolua_S,"DeleteHeaderComment",tolua_AllToLua_cIniFile_DeleteHeaderComment00); - tolua_function(tolua_S,"DeleteHeaderComments",tolua_AllToLua_cIniFile_DeleteHeaderComments00); - tolua_function(tolua_S,"NumKeyComments",tolua_AllToLua_cIniFile_NumKeyComments00); - tolua_function(tolua_S,"NumKeyComments",tolua_AllToLua_cIniFile_NumKeyComments01); - tolua_function(tolua_S,"KeyComment",tolua_AllToLua_cIniFile_KeyComment00); - tolua_function(tolua_S,"KeyComment",tolua_AllToLua_cIniFile_KeyComment01); - tolua_function(tolua_S,"KeyComment",tolua_AllToLua_cIniFile_KeyComment02); - tolua_function(tolua_S,"KeyComment",tolua_AllToLua_cIniFile_KeyComment03); - tolua_function(tolua_S,"DeleteKeyComment",tolua_AllToLua_cIniFile_DeleteKeyComment00); - tolua_function(tolua_S,"DeleteKeyComment",tolua_AllToLua_cIniFile_DeleteKeyComment01); - tolua_function(tolua_S,"DeleteKeyComments",tolua_AllToLua_cIniFile_DeleteKeyComments00); - tolua_function(tolua_S,"DeleteKeyComments",tolua_AllToLua_cIniFile_DeleteKeyComments01); - tolua_endmodule(tolua_S); - tolua_constant(tolua_S,"E_BLOCK_AIR",E_BLOCK_AIR); - tolua_constant(tolua_S,"E_BLOCK_STONE",E_BLOCK_STONE); - tolua_constant(tolua_S,"E_BLOCK_GRASS",E_BLOCK_GRASS); - tolua_constant(tolua_S,"E_BLOCK_DIRT",E_BLOCK_DIRT); - tolua_constant(tolua_S,"E_BLOCK_COBBLESTONE",E_BLOCK_COBBLESTONE); - tolua_constant(tolua_S,"E_BLOCK_PLANKS",E_BLOCK_PLANKS); - tolua_constant(tolua_S,"E_BLOCK_WOOD",E_BLOCK_WOOD); - tolua_constant(tolua_S,"E_BLOCK_SAPLING",E_BLOCK_SAPLING); - tolua_constant(tolua_S,"E_BLOCK_BEDROCK",E_BLOCK_BEDROCK); - tolua_constant(tolua_S,"E_BLOCK_WATER",E_BLOCK_WATER); - tolua_constant(tolua_S,"E_BLOCK_STATIONARY_WATER",E_BLOCK_STATIONARY_WATER); - tolua_constant(tolua_S,"E_BLOCK_LAVA",E_BLOCK_LAVA); - tolua_constant(tolua_S,"E_BLOCK_STATIONARY_LAVA",E_BLOCK_STATIONARY_LAVA); - tolua_constant(tolua_S,"E_BLOCK_SAND",E_BLOCK_SAND); - tolua_constant(tolua_S,"E_BLOCK_GRAVEL",E_BLOCK_GRAVEL); - tolua_constant(tolua_S,"E_BLOCK_GOLD_ORE",E_BLOCK_GOLD_ORE); - tolua_constant(tolua_S,"E_BLOCK_IRON_ORE",E_BLOCK_IRON_ORE); - tolua_constant(tolua_S,"E_BLOCK_COAL_ORE",E_BLOCK_COAL_ORE); - tolua_constant(tolua_S,"E_BLOCK_LOG",E_BLOCK_LOG); - tolua_constant(tolua_S,"E_BLOCK_LEAVES",E_BLOCK_LEAVES); - tolua_constant(tolua_S,"E_BLOCK_SPONGE",E_BLOCK_SPONGE); - tolua_constant(tolua_S,"E_BLOCK_GLASS",E_BLOCK_GLASS); - tolua_constant(tolua_S,"E_BLOCK_LAPIS_ORE",E_BLOCK_LAPIS_ORE); - tolua_constant(tolua_S,"E_BLOCK_LAPIS_BLOCK",E_BLOCK_LAPIS_BLOCK); - tolua_constant(tolua_S,"E_BLOCK_DISPENSER",E_BLOCK_DISPENSER); - tolua_constant(tolua_S,"E_BLOCK_SANDSTONE",E_BLOCK_SANDSTONE); - tolua_constant(tolua_S,"E_BLOCK_NOTE_BLOCK",E_BLOCK_NOTE_BLOCK); - tolua_constant(tolua_S,"E_BLOCK_BED",E_BLOCK_BED); - tolua_constant(tolua_S,"E_BLOCK_POWERED_RAIL",E_BLOCK_POWERED_RAIL); - tolua_constant(tolua_S,"E_BLOCK_DETECTOR_RAIL",E_BLOCK_DETECTOR_RAIL); - tolua_constant(tolua_S,"E_BLOCK_STICKY_PISTON",E_BLOCK_STICKY_PISTON); - tolua_constant(tolua_S,"E_BLOCK_COBWEB",E_BLOCK_COBWEB); - tolua_constant(tolua_S,"E_BLOCK_TALL_GRASS",E_BLOCK_TALL_GRASS); - tolua_constant(tolua_S,"E_BLOCK_DEAD_BUSH",E_BLOCK_DEAD_BUSH); - tolua_constant(tolua_S,"E_BLOCK_PISTON",E_BLOCK_PISTON); - tolua_constant(tolua_S,"E_BLOCK_PISTON_EXTENSION",E_BLOCK_PISTON_EXTENSION); - tolua_constant(tolua_S,"E_BLOCK_WHITE_CLOTH",E_BLOCK_WHITE_CLOTH); - tolua_constant(tolua_S,"E_BLOCK_WOOL",E_BLOCK_WOOL); - tolua_constant(tolua_S,"E_BLOCK_PISTON_MOVED_BLOCK",E_BLOCK_PISTON_MOVED_BLOCK); - tolua_constant(tolua_S,"E_BLOCK_YELLOW_FLOWER",E_BLOCK_YELLOW_FLOWER); - tolua_constant(tolua_S,"E_BLOCK_RED_ROSE",E_BLOCK_RED_ROSE); - tolua_constant(tolua_S,"E_BLOCK_BROWN_MUSHROOM",E_BLOCK_BROWN_MUSHROOM); - tolua_constant(tolua_S,"E_BLOCK_RED_MUSHROOM",E_BLOCK_RED_MUSHROOM); - tolua_constant(tolua_S,"E_BLOCK_GOLD_BLOCK",E_BLOCK_GOLD_BLOCK); - tolua_constant(tolua_S,"E_BLOCK_IRON_BLOCK",E_BLOCK_IRON_BLOCK); - tolua_constant(tolua_S,"E_BLOCK_DOUBLE_STONE_SLAB",E_BLOCK_DOUBLE_STONE_SLAB); - tolua_constant(tolua_S,"E_BLOCK_DOUBLE_STEP",E_BLOCK_DOUBLE_STEP); - tolua_constant(tolua_S,"E_BLOCK_STONE_SLAB",E_BLOCK_STONE_SLAB); - tolua_constant(tolua_S,"E_BLOCK_STEP",E_BLOCK_STEP); - tolua_constant(tolua_S,"E_BLOCK_BRICK",E_BLOCK_BRICK); - tolua_constant(tolua_S,"E_BLOCK_TNT",E_BLOCK_TNT); - tolua_constant(tolua_S,"E_BLOCK_BOOKCASE",E_BLOCK_BOOKCASE); - tolua_constant(tolua_S,"E_BLOCK_MOSSY_COBBLESTONE",E_BLOCK_MOSSY_COBBLESTONE); - tolua_constant(tolua_S,"E_BLOCK_OBSIDIAN",E_BLOCK_OBSIDIAN); - tolua_constant(tolua_S,"E_BLOCK_TORCH",E_BLOCK_TORCH); - tolua_constant(tolua_S,"E_BLOCK_FIRE",E_BLOCK_FIRE); - tolua_constant(tolua_S,"E_BLOCK_MOB_SPAWNER",E_BLOCK_MOB_SPAWNER); - tolua_constant(tolua_S,"E_BLOCK_WOODEN_STAIRS",E_BLOCK_WOODEN_STAIRS); - tolua_constant(tolua_S,"E_BLOCK_CHEST",E_BLOCK_CHEST); - tolua_constant(tolua_S,"E_BLOCK_REDSTONE_WIRE",E_BLOCK_REDSTONE_WIRE); - tolua_constant(tolua_S,"E_BLOCK_DIAMOND_ORE",E_BLOCK_DIAMOND_ORE); - tolua_constant(tolua_S,"E_BLOCK_DIAMOND_BLOCK",E_BLOCK_DIAMOND_BLOCK); - tolua_constant(tolua_S,"E_BLOCK_CRAFTING_TABLE",E_BLOCK_CRAFTING_TABLE); - tolua_constant(tolua_S,"E_BLOCK_WORKBENCH",E_BLOCK_WORKBENCH); - tolua_constant(tolua_S,"E_BLOCK_CROPS",E_BLOCK_CROPS); - tolua_constant(tolua_S,"E_BLOCK_SOIL",E_BLOCK_SOIL); - tolua_constant(tolua_S,"E_BLOCK_FARMLAND",E_BLOCK_FARMLAND); - tolua_constant(tolua_S,"E_BLOCK_FURNACE",E_BLOCK_FURNACE); - tolua_constant(tolua_S,"E_BLOCK_LIT_FURNACE",E_BLOCK_LIT_FURNACE); - tolua_constant(tolua_S,"E_BLOCK_BURNING_FURNACE",E_BLOCK_BURNING_FURNACE); - tolua_constant(tolua_S,"E_BLOCK_SIGN_POST",E_BLOCK_SIGN_POST); - tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOOR",E_BLOCK_WOODEN_DOOR); - tolua_constant(tolua_S,"E_BLOCK_LADDER",E_BLOCK_LADDER); - tolua_constant(tolua_S,"E_BLOCK_RAIL",E_BLOCK_RAIL); - tolua_constant(tolua_S,"E_BLOCK_MINECART_TRACKS",E_BLOCK_MINECART_TRACKS); - tolua_constant(tolua_S,"E_BLOCK_COBBLESTONE_STAIRS",E_BLOCK_COBBLESTONE_STAIRS); - tolua_constant(tolua_S,"E_BLOCK_WALLSIGN",E_BLOCK_WALLSIGN); - tolua_constant(tolua_S,"E_BLOCK_LEVER",E_BLOCK_LEVER); - tolua_constant(tolua_S,"E_BLOCK_STONE_PRESSURE_PLATE",E_BLOCK_STONE_PRESSURE_PLATE); - tolua_constant(tolua_S,"E_BLOCK_IRON_DOOR",E_BLOCK_IRON_DOOR); - tolua_constant(tolua_S,"E_BLOCK_WOODEN_PRESSURE_PLATE",E_BLOCK_WOODEN_PRESSURE_PLATE); - tolua_constant(tolua_S,"E_BLOCK_REDSTONE_ORE",E_BLOCK_REDSTONE_ORE); - tolua_constant(tolua_S,"E_BLOCK_REDSTONE_ORE_GLOWING",E_BLOCK_REDSTONE_ORE_GLOWING); - tolua_constant(tolua_S,"E_BLOCK_REDSTONE_TORCH_OFF",E_BLOCK_REDSTONE_TORCH_OFF); - tolua_constant(tolua_S,"E_BLOCK_REDSTONE_TORCH_ON",E_BLOCK_REDSTONE_TORCH_ON); - tolua_constant(tolua_S,"E_BLOCK_STONE_BUTTON",E_BLOCK_STONE_BUTTON); - tolua_constant(tolua_S,"E_BLOCK_SNOW",E_BLOCK_SNOW); - tolua_constant(tolua_S,"E_BLOCK_ICE",E_BLOCK_ICE); - tolua_constant(tolua_S,"E_BLOCK_SNOW_BLOCK",E_BLOCK_SNOW_BLOCK); - tolua_constant(tolua_S,"E_BLOCK_CACTUS",E_BLOCK_CACTUS); - tolua_constant(tolua_S,"E_BLOCK_CLAY",E_BLOCK_CLAY); - tolua_constant(tolua_S,"E_BLOCK_SUGARCANE",E_BLOCK_SUGARCANE); - tolua_constant(tolua_S,"E_BLOCK_REEDS",E_BLOCK_REEDS); - tolua_constant(tolua_S,"E_BLOCK_JUKEBOX",E_BLOCK_JUKEBOX); - tolua_constant(tolua_S,"E_BLOCK_FENCE",E_BLOCK_FENCE); - tolua_constant(tolua_S,"E_BLOCK_PUMPKIN",E_BLOCK_PUMPKIN); - tolua_constant(tolua_S,"E_BLOCK_BLOODSTONE",E_BLOCK_BLOODSTONE); - tolua_constant(tolua_S,"E_BLOCK_NETHERRACK",E_BLOCK_NETHERRACK); - tolua_constant(tolua_S,"E_BLOCK_SOULSAND",E_BLOCK_SOULSAND); - tolua_constant(tolua_S,"E_BLOCK_GLOWSTONE",E_BLOCK_GLOWSTONE); - tolua_constant(tolua_S,"E_BLOCK_PORT",E_BLOCK_PORT); - tolua_constant(tolua_S,"E_BLOCK_NETHER_PORTAL",E_BLOCK_NETHER_PORTAL); - tolua_constant(tolua_S,"E_BLOCK_JACK_O_LANTERN",E_BLOCK_JACK_O_LANTERN); - tolua_constant(tolua_S,"E_BLOCK_CAKE",E_BLOCK_CAKE); - tolua_constant(tolua_S,"E_BLOCK_REDSTONE_REPEATER_OFF",E_BLOCK_REDSTONE_REPEATER_OFF); - tolua_constant(tolua_S,"E_BLOCK_REDSTONE_REPEATER_ON",E_BLOCK_REDSTONE_REPEATER_ON); - tolua_constant(tolua_S,"E_BLOCK_LOCKED_CHEST",E_BLOCK_LOCKED_CHEST); - tolua_constant(tolua_S,"E_BLOCK_TRAPDOOR",E_BLOCK_TRAPDOOR); - tolua_constant(tolua_S,"E_BLOCK_SILVERFISH_EGG",E_BLOCK_SILVERFISH_EGG); - tolua_constant(tolua_S,"E_BLOCK_STONE_BRICKS",E_BLOCK_STONE_BRICKS); - tolua_constant(tolua_S,"E_BLOCK_HUGE_BROWN_MUSHROOM",E_BLOCK_HUGE_BROWN_MUSHROOM); - tolua_constant(tolua_S,"E_BLOCK_HUGE_RED_MUSHROOM",E_BLOCK_HUGE_RED_MUSHROOM); - tolua_constant(tolua_S,"E_BLOCK_IRON_BAR",E_BLOCK_IRON_BAR); - tolua_constant(tolua_S,"E_BLOCK_GLASS_PLANE",E_BLOCK_GLASS_PLANE); - tolua_constant(tolua_S,"E_BLOCK_MELON",E_BLOCK_MELON); - tolua_constant(tolua_S,"E_BLOCK_PUMPKIN_STEM",E_BLOCK_PUMPKIN_STEM); - tolua_constant(tolua_S,"E_BLOCK_MELON_STEM",E_BLOCK_MELON_STEM); - tolua_constant(tolua_S,"E_BLOCK_VINES",E_BLOCK_VINES); - tolua_constant(tolua_S,"E_BLOCK_FENCE_GATE",E_BLOCK_FENCE_GATE); - tolua_constant(tolua_S,"E_BLOCK_BRICK_STAIRS",E_BLOCK_BRICK_STAIRS); - tolua_constant(tolua_S,"E_BLOCK_STONE_BRICK_STAIRS",E_BLOCK_STONE_BRICK_STAIRS); - tolua_constant(tolua_S,"E_BLOCK_MYCELIUM",E_BLOCK_MYCELIUM); - tolua_constant(tolua_S,"E_BLOCK_LILY_PAD",E_BLOCK_LILY_PAD); - tolua_constant(tolua_S,"E_BLOCK_NETHER_BRICK",E_BLOCK_NETHER_BRICK); - tolua_constant(tolua_S,"E_BLOCK_NETHER_BRICK_FENCE",E_BLOCK_NETHER_BRICK_FENCE); - tolua_constant(tolua_S,"E_BLOCK_NETHER_BRICK_STAIRS",E_BLOCK_NETHER_BRICK_STAIRS); - tolua_constant(tolua_S,"E_BLOCK_NETHER_WART",E_BLOCK_NETHER_WART); - tolua_constant(tolua_S,"E_BLOCK_ENCHANTMENT_TABLE",E_BLOCK_ENCHANTMENT_TABLE); - tolua_constant(tolua_S,"E_BLOCK_BREWING_STAND",E_BLOCK_BREWING_STAND); - tolua_constant(tolua_S,"E_BLOCK_CAULDRON",E_BLOCK_CAULDRON); - tolua_constant(tolua_S,"E_BLOCK_END_PORTAL",E_BLOCK_END_PORTAL); - tolua_constant(tolua_S,"E_BLOCK_END_PORTAL_FRAME",E_BLOCK_END_PORTAL_FRAME); - tolua_constant(tolua_S,"E_BLOCK_END_STONE",E_BLOCK_END_STONE); - tolua_constant(tolua_S,"E_BLOCK_DRAGON_EGG",E_BLOCK_DRAGON_EGG); - tolua_constant(tolua_S,"E_BLOCK_REDSTONE_LAMP_OFF",E_BLOCK_REDSTONE_LAMP_OFF); - tolua_constant(tolua_S,"E_BLOCK_REDSTONE_LAMP_ON",E_BLOCK_REDSTONE_LAMP_ON); - tolua_constant(tolua_S,"E_BLOCK_DOUBLE_WOODEN_SLAB",E_BLOCK_DOUBLE_WOODEN_SLAB); - tolua_constant(tolua_S,"E_BLOCK_WOODEN_SLAB",E_BLOCK_WOODEN_SLAB); - tolua_constant(tolua_S,"E_BLOCK_COCA_PLANT",E_BLOCK_COCA_PLANT); - tolua_constant(tolua_S,"E_BLOCK_SANDSTONE_STAIRS",E_BLOCK_SANDSTONE_STAIRS); - tolua_constant(tolua_S,"E_BLOCK_EMERALD_ORE",E_BLOCK_EMERALD_ORE); - tolua_constant(tolua_S,"E_BLOCK_ENDER_CHEST",E_BLOCK_ENDER_CHEST); - tolua_constant(tolua_S,"E_BLOCK_TRIPWIRE_HOOK",E_BLOCK_TRIPWIRE_HOOK); - tolua_constant(tolua_S,"E_BLOCK_TRIPWIRE",E_BLOCK_TRIPWIRE); - tolua_constant(tolua_S,"E_BLOCK_EMERALD_BLOCK",E_BLOCK_EMERALD_BLOCK); - tolua_constant(tolua_S,"E_BLOCK_",E_BLOCK_); - tolua_constant(tolua_S,"E_ITEM_EMPTY",E_ITEM_EMPTY); - tolua_constant(tolua_S,"E_ITEM_STONE",E_ITEM_STONE); - tolua_constant(tolua_S,"E_ITEM_GRASS",E_ITEM_GRASS); - tolua_constant(tolua_S,"E_ITEM_DIRT",E_ITEM_DIRT); - tolua_constant(tolua_S,"E_ITEM_COBBLESTONE",E_ITEM_COBBLESTONE); - tolua_constant(tolua_S,"E_ITEM_PLANKS",E_ITEM_PLANKS); - tolua_constant(tolua_S,"E_ITEM_WOOD",E_ITEM_WOOD); - tolua_constant(tolua_S,"E_ITEM_SAPLING",E_ITEM_SAPLING); - tolua_constant(tolua_S,"E_ITEM_BEDROCK",E_ITEM_BEDROCK); - tolua_constant(tolua_S,"E_ITEM_WATER",E_ITEM_WATER); - tolua_constant(tolua_S,"E_ITEM_STATIONARY_WATER",E_ITEM_STATIONARY_WATER); - tolua_constant(tolua_S,"E_ITEM_LAVA",E_ITEM_LAVA); - tolua_constant(tolua_S,"E_ITEM_STATIONARY_LAVA",E_ITEM_STATIONARY_LAVA); - tolua_constant(tolua_S,"E_ITEM_SAND",E_ITEM_SAND); - tolua_constant(tolua_S,"E_ITEM_GRAVEL",E_ITEM_GRAVEL); - tolua_constant(tolua_S,"E_ITEM_GOLD_ORE",E_ITEM_GOLD_ORE); - tolua_constant(tolua_S,"E_ITEM_IRON_ORE",E_ITEM_IRON_ORE); - tolua_constant(tolua_S,"E_ITEM_COAL_ORE",E_ITEM_COAL_ORE); - tolua_constant(tolua_S,"E_ITEM_LOG",E_ITEM_LOG); - tolua_constant(tolua_S,"E_ITEM_LEAVES",E_ITEM_LEAVES); - tolua_constant(tolua_S,"E_ITEM_SPONGE",E_ITEM_SPONGE); - tolua_constant(tolua_S,"E_ITEM_GLASS",E_ITEM_GLASS); - tolua_constant(tolua_S,"E_ITEM_LAPIS_ORE",E_ITEM_LAPIS_ORE); - tolua_constant(tolua_S,"E_ITEM_LAPIS_BLOCK",E_ITEM_LAPIS_BLOCK); - tolua_constant(tolua_S,"E_ITEM_DISPENSER",E_ITEM_DISPENSER); - tolua_constant(tolua_S,"E_ITEM_SANDSTONE",E_ITEM_SANDSTONE); - tolua_constant(tolua_S,"E_ITEM_NOTE_ITEM",E_ITEM_NOTE_ITEM); - tolua_constant(tolua_S,"E_ITEM_POWERED_RAIL",E_ITEM_POWERED_RAIL); - tolua_constant(tolua_S,"E_ITEM_DETECTOR_RAIL",E_ITEM_DETECTOR_RAIL); - tolua_constant(tolua_S,"E_ITEM_STICKY_PISTON",E_ITEM_STICKY_PISTON); - tolua_constant(tolua_S,"E_ITEM_COBWEB",E_ITEM_COBWEB); - tolua_constant(tolua_S,"E_ITEM_TALL_GRASS",E_ITEM_TALL_GRASS); - tolua_constant(tolua_S,"E_ITEM_DEAD_BRUSH",E_ITEM_DEAD_BRUSH); - tolua_constant(tolua_S,"E_ITEM_PISTON",E_ITEM_PISTON); - tolua_constant(tolua_S,"E_ITEM_PISTON_EXTENSION",E_ITEM_PISTON_EXTENSION); - tolua_constant(tolua_S,"E_ITEM_WHITE_CLOTH",E_ITEM_WHITE_CLOTH); - tolua_constant(tolua_S,"E_ITEM_PISTON_MOVED_BLOCK",E_ITEM_PISTON_MOVED_BLOCK); - tolua_constant(tolua_S,"E_ITEM_YELLOW_FLOWER",E_ITEM_YELLOW_FLOWER); - tolua_constant(tolua_S,"E_ITEM_RED_ROSE",E_ITEM_RED_ROSE); - tolua_constant(tolua_S,"E_ITEM_BROWN_MUSHROOM",E_ITEM_BROWN_MUSHROOM); - tolua_constant(tolua_S,"E_ITEM_RED_MUSHROOM",E_ITEM_RED_MUSHROOM); - tolua_constant(tolua_S,"E_ITEM_GOLD_BLOCK",E_ITEM_GOLD_BLOCK); - tolua_constant(tolua_S,"E_ITEM_IRON_BLOCK",E_ITEM_IRON_BLOCK); - tolua_constant(tolua_S,"E_ITEM_DOUBLE_STONE_SLAB",E_ITEM_DOUBLE_STONE_SLAB); - tolua_constant(tolua_S,"E_ITEM_DOUBLE_STEP",E_ITEM_DOUBLE_STEP); - tolua_constant(tolua_S,"E_ITEM_STONE_SLAB",E_ITEM_STONE_SLAB); - tolua_constant(tolua_S,"E_ITEM_STEP",E_ITEM_STEP); - tolua_constant(tolua_S,"E_ITEM_BRICK",E_ITEM_BRICK); - tolua_constant(tolua_S,"E_ITEM_TNT",E_ITEM_TNT); - tolua_constant(tolua_S,"E_ITEM_BOOKCASE",E_ITEM_BOOKCASE); - tolua_constant(tolua_S,"E_ITEM_MOSSY_COBBLESTONE",E_ITEM_MOSSY_COBBLESTONE); - tolua_constant(tolua_S,"E_ITEM_OBSIDIAN",E_ITEM_OBSIDIAN); - tolua_constant(tolua_S,"E_ITEM_TORCH",E_ITEM_TORCH); - tolua_constant(tolua_S,"E_ITEM_FIRE",E_ITEM_FIRE); - tolua_constant(tolua_S,"E_ITEM_MOB_SPAWNER",E_ITEM_MOB_SPAWNER); - tolua_constant(tolua_S,"E_ITEM_WOODEN_STAIRS",E_ITEM_WOODEN_STAIRS); - tolua_constant(tolua_S,"E_ITEM_CHEST",E_ITEM_CHEST); - tolua_constant(tolua_S,"E_ITEM_REDSTONE_WIRE",E_ITEM_REDSTONE_WIRE); - tolua_constant(tolua_S,"E_ITEM_DIAMOND_ORE",E_ITEM_DIAMOND_ORE); - tolua_constant(tolua_S,"E_ITEM_DIAMOND_BLOCK",E_ITEM_DIAMOND_BLOCK); - tolua_constant(tolua_S,"E_ITEM_WORKBENCH",E_ITEM_WORKBENCH); - tolua_constant(tolua_S,"E_ITEM_CROPS",E_ITEM_CROPS); - tolua_constant(tolua_S,"E_ITEM_SOIL",E_ITEM_SOIL); - tolua_constant(tolua_S,"E_ITEM_FURNACE",E_ITEM_FURNACE); - tolua_constant(tolua_S,"E_ITEM_BURNING_FURNACE",E_ITEM_BURNING_FURNACE); - tolua_constant(tolua_S,"E_ITEM_SIGN_POST",E_ITEM_SIGN_POST); - tolua_constant(tolua_S,"E_ITEM_LADDER",E_ITEM_LADDER); - tolua_constant(tolua_S,"E_ITEM_MINECART_TRACKS",E_ITEM_MINECART_TRACKS); - tolua_constant(tolua_S,"E_ITEM_COBBLESTONE_STAIRS",E_ITEM_COBBLESTONE_STAIRS); - tolua_constant(tolua_S,"E_ITEM_WALLSIGN",E_ITEM_WALLSIGN); - tolua_constant(tolua_S,"E_ITEM_LEVER",E_ITEM_LEVER); - tolua_constant(tolua_S,"E_ITEM_STONE_PRESSURE_PLATE",E_ITEM_STONE_PRESSURE_PLATE); - tolua_constant(tolua_S,"E_ITEM_WOODEN_PRESSURE_PLATE",E_ITEM_WOODEN_PRESSURE_PLATE); - tolua_constant(tolua_S,"E_ITEM_REDSTONE_ORE",E_ITEM_REDSTONE_ORE); - tolua_constant(tolua_S,"E_ITEM_REDSTONE_ORE_GLOWING",E_ITEM_REDSTONE_ORE_GLOWING); - tolua_constant(tolua_S,"E_ITEM_REDSTONE_TORCH_ON",E_ITEM_REDSTONE_TORCH_ON); - tolua_constant(tolua_S,"E_ITEM_REDSTONE_TORCH_OFF",E_ITEM_REDSTONE_TORCH_OFF); - tolua_constant(tolua_S,"E_ITEM_STONE_BUTTON",E_ITEM_STONE_BUTTON); - tolua_constant(tolua_S,"E_ITEM_SNOW",E_ITEM_SNOW); - tolua_constant(tolua_S,"E_ITEM_ICE",E_ITEM_ICE); - tolua_constant(tolua_S,"E_ITEM_SNOW_BLOCK",E_ITEM_SNOW_BLOCK); - tolua_constant(tolua_S,"E_ITEM_CACTUS",E_ITEM_CACTUS); - tolua_constant(tolua_S,"E_ITEM_REEDS",E_ITEM_REEDS); - tolua_constant(tolua_S,"E_ITEM_JUKEBOX",E_ITEM_JUKEBOX); - tolua_constant(tolua_S,"E_ITEM_FENCE",E_ITEM_FENCE); - tolua_constant(tolua_S,"E_ITEM_PUMPKIN",E_ITEM_PUMPKIN); - tolua_constant(tolua_S,"E_ITEM_BLOODSTONE",E_ITEM_BLOODSTONE); - tolua_constant(tolua_S,"E_ITEM_SOULSAND",E_ITEM_SOULSAND); - tolua_constant(tolua_S,"E_ITEM_GLOWSTONE",E_ITEM_GLOWSTONE); - tolua_constant(tolua_S,"E_ITEM_PORT",E_ITEM_PORT); - tolua_constant(tolua_S,"E_ITEM_JACK_O_LANTERN",E_ITEM_JACK_O_LANTERN); - tolua_constant(tolua_S,"E_ITEM_REDSTONE_REPEATER_OFF",E_ITEM_REDSTONE_REPEATER_OFF); - tolua_constant(tolua_S,"E_ITEM_REDSTONE_REPEATER_ON",E_ITEM_REDSTONE_REPEATER_ON); - tolua_constant(tolua_S,"E_ITEM_LOCKED_CHEST",E_ITEM_LOCKED_CHEST); - tolua_constant(tolua_S,"E_ITEM_TRAPDOOR",E_ITEM_TRAPDOOR); - tolua_constant(tolua_S,"E_ITEM_SILVERFISH_EGG",E_ITEM_SILVERFISH_EGG); - tolua_constant(tolua_S,"E_ITEM_STONE_BRICKS",E_ITEM_STONE_BRICKS); - tolua_constant(tolua_S,"E_ITEM_HUGE_BROWN_MUSHROOM",E_ITEM_HUGE_BROWN_MUSHROOM); - tolua_constant(tolua_S,"E_ITEM_HUGE_RED_MUSHROOM",E_ITEM_HUGE_RED_MUSHROOM); - tolua_constant(tolua_S,"E_ITEM_IRON_BAR",E_ITEM_IRON_BAR); - tolua_constant(tolua_S,"E_ITEM_GLASS_PLANE",E_ITEM_GLASS_PLANE); - tolua_constant(tolua_S,"E_ITEM_MELON",E_ITEM_MELON); - tolua_constant(tolua_S,"E_ITEM_PUMPKIN_STEM",E_ITEM_PUMPKIN_STEM); - tolua_constant(tolua_S,"E_ITEM_MELON_STEM",E_ITEM_MELON_STEM); - tolua_constant(tolua_S,"E_ITEM_VINES",E_ITEM_VINES); - tolua_constant(tolua_S,"E_ITEM_FENCE_GATE",E_ITEM_FENCE_GATE); - tolua_constant(tolua_S,"E_ITEM_BRICK_STAIRS",E_ITEM_BRICK_STAIRS); - tolua_constant(tolua_S,"E_ITEM_STONE_BRICK_STAIRS",E_ITEM_STONE_BRICK_STAIRS); - tolua_constant(tolua_S,"E_ITEM_MYCELIUM",E_ITEM_MYCELIUM); - tolua_constant(tolua_S,"E_ITEM_LILY_PAD",E_ITEM_LILY_PAD); - tolua_constant(tolua_S,"E_ITEM_NETHER_BRICK",E_ITEM_NETHER_BRICK); - tolua_constant(tolua_S,"E_ITEM_NETHER_BRICK_FENCE",E_ITEM_NETHER_BRICK_FENCE); - tolua_constant(tolua_S,"E_ITEM_NETHER_BRICK_STAIRS",E_ITEM_NETHER_BRICK_STAIRS); - tolua_constant(tolua_S,"E_ITEM_ENCHANTMENT_TABLE",E_ITEM_ENCHANTMENT_TABLE); - tolua_constant(tolua_S,"E_ITEM_END_PORTAL",E_ITEM_END_PORTAL); - tolua_constant(tolua_S,"E_ITEM_END_PORTAL_FRAME",E_ITEM_END_PORTAL_FRAME); - tolua_constant(tolua_S,"E_ITEM_END_STONE",E_ITEM_END_STONE); - tolua_constant(tolua_S,"E_ITEM_DOUBLE_WOODEN_SLAB",E_ITEM_DOUBLE_WOODEN_SLAB); - tolua_constant(tolua_S,"E_ITEM_WOODEN_SLAB",E_ITEM_WOODEN_SLAB); - tolua_constant(tolua_S,"E_ITEM_COCA_PLANT",E_ITEM_COCA_PLANT); - tolua_constant(tolua_S,"E_ITEM_SANDSTONE_STAIRS",E_ITEM_SANDSTONE_STAIRS); - tolua_constant(tolua_S,"E_ITEM_EMERALD_ORE",E_ITEM_EMERALD_ORE); - tolua_constant(tolua_S,"E_ITEM_ENDER_CHEST",E_ITEM_ENDER_CHEST); - tolua_constant(tolua_S,"E_ITEM_TRIPWIRE_HOOK",E_ITEM_TRIPWIRE_HOOK); - tolua_constant(tolua_S,"E_ITEM_TRIPWIRE",E_ITEM_TRIPWIRE); - tolua_constant(tolua_S,"E_ITEM_EMERALD_BLOCK",E_ITEM_EMERALD_BLOCK); - tolua_constant(tolua_S,"E_ITEM_IRON_SHOVEL",E_ITEM_IRON_SHOVEL); - tolua_constant(tolua_S,"E_ITEM_IRON_PICKAXE",E_ITEM_IRON_PICKAXE); - tolua_constant(tolua_S,"E_ITEM_IRON_AXE",E_ITEM_IRON_AXE); - tolua_constant(tolua_S,"E_ITEM_FLINT_AND_STEEL",E_ITEM_FLINT_AND_STEEL); - tolua_constant(tolua_S,"E_ITEM_RED_APPLE",E_ITEM_RED_APPLE); - tolua_constant(tolua_S,"E_ITEM_APPLE",E_ITEM_APPLE); - tolua_constant(tolua_S,"E_ITEM_BOW",E_ITEM_BOW); - tolua_constant(tolua_S,"E_ITEM_ARROW",E_ITEM_ARROW); - tolua_constant(tolua_S,"E_ITEM_COAL",E_ITEM_COAL); - tolua_constant(tolua_S,"E_ITEM_DIAMOND",E_ITEM_DIAMOND); - tolua_constant(tolua_S,"E_ITEM_IRON",E_ITEM_IRON); - tolua_constant(tolua_S,"E_ITEM_GOLD",E_ITEM_GOLD); - tolua_constant(tolua_S,"E_ITEM_IRON_SWORD",E_ITEM_IRON_SWORD); - tolua_constant(tolua_S,"E_ITEM_WOODEN_SWORD",E_ITEM_WOODEN_SWORD); - tolua_constant(tolua_S,"E_ITEM_WOODEN_SHOVEL",E_ITEM_WOODEN_SHOVEL); - tolua_constant(tolua_S,"E_ITEM_WOODEN_PICKAXE",E_ITEM_WOODEN_PICKAXE); - tolua_constant(tolua_S,"E_ITEM_WOODEN_AXE",E_ITEM_WOODEN_AXE); - tolua_constant(tolua_S,"E_ITEM_STONE_SWORD",E_ITEM_STONE_SWORD); - tolua_constant(tolua_S,"E_ITEM_STONE_SHOVEL",E_ITEM_STONE_SHOVEL); - tolua_constant(tolua_S,"E_ITEM_STONE_PICKAXE",E_ITEM_STONE_PICKAXE); - tolua_constant(tolua_S,"E_ITEM_STONE_AXE",E_ITEM_STONE_AXE); - tolua_constant(tolua_S,"E_ITEM_DIAMOND_SWORD",E_ITEM_DIAMOND_SWORD); - tolua_constant(tolua_S,"E_ITEM_DIAMOND_SHOVEL",E_ITEM_DIAMOND_SHOVEL); - tolua_constant(tolua_S,"E_ITEM_DIAMOND_PICKAXE",E_ITEM_DIAMOND_PICKAXE); - tolua_constant(tolua_S,"E_ITEM_DIAMOND_AXE",E_ITEM_DIAMOND_AXE); - tolua_constant(tolua_S,"E_ITEM_STICK",E_ITEM_STICK); - tolua_constant(tolua_S,"E_ITEM_BOWL",E_ITEM_BOWL); - tolua_constant(tolua_S,"E_ITEM_MUSHROOM_SOUP",E_ITEM_MUSHROOM_SOUP); - tolua_constant(tolua_S,"E_ITEM_GOLD_SWORD",E_ITEM_GOLD_SWORD); - tolua_constant(tolua_S,"E_ITEM_GOLD_SHOVEL",E_ITEM_GOLD_SHOVEL); - tolua_constant(tolua_S,"E_ITEM_GOLD_PICKAXE",E_ITEM_GOLD_PICKAXE); - tolua_constant(tolua_S,"E_ITEM_GOLD_AXE",E_ITEM_GOLD_AXE); - tolua_constant(tolua_S,"E_ITEM_STRING",E_ITEM_STRING); - tolua_constant(tolua_S,"E_ITEM_FEATHER",E_ITEM_FEATHER); - tolua_constant(tolua_S,"E_ITEM_GUNPOWDER",E_ITEM_GUNPOWDER); - tolua_constant(tolua_S,"E_ITEM_WOODEN_HOE",E_ITEM_WOODEN_HOE); - tolua_constant(tolua_S,"E_ITEM_STONE_HOE",E_ITEM_STONE_HOE); - tolua_constant(tolua_S,"E_ITEM_IRON_HOE",E_ITEM_IRON_HOE); - tolua_constant(tolua_S,"E_ITEM_DIAMOND_HOE",E_ITEM_DIAMOND_HOE); - tolua_constant(tolua_S,"E_ITEM_GOLD_HOE",E_ITEM_GOLD_HOE); - tolua_constant(tolua_S,"E_ITEM_SEEDS",E_ITEM_SEEDS); - tolua_constant(tolua_S,"E_ITEM_WHEAT",E_ITEM_WHEAT); - tolua_constant(tolua_S,"E_ITEM_BREAD",E_ITEM_BREAD); - tolua_constant(tolua_S,"E_ITEM_LEATHER_CAP",E_ITEM_LEATHER_CAP); - tolua_constant(tolua_S,"E_ITEM_LEATHER_TUNIC",E_ITEM_LEATHER_TUNIC); - tolua_constant(tolua_S,"E_ITEM_LEATHER_PANTS",E_ITEM_LEATHER_PANTS); - tolua_constant(tolua_S,"E_ITEM_LEATHER_BOOTS",E_ITEM_LEATHER_BOOTS); - tolua_constant(tolua_S,"E_ITEM_CHAIN_HELMET",E_ITEM_CHAIN_HELMET); - tolua_constant(tolua_S,"E_ITEM_CHAIN_CHESTPLATE",E_ITEM_CHAIN_CHESTPLATE); - tolua_constant(tolua_S,"E_ITEM_CHAIN_LEGGINGS",E_ITEM_CHAIN_LEGGINGS); - tolua_constant(tolua_S,"E_ITEM_CHAIN_BOOTS",E_ITEM_CHAIN_BOOTS); - tolua_constant(tolua_S,"E_ITEM_IRON_HELMET",E_ITEM_IRON_HELMET); - tolua_constant(tolua_S,"E_ITEM_IRON_CHESTPLATE",E_ITEM_IRON_CHESTPLATE); - tolua_constant(tolua_S,"E_ITEM_IRON_LEGGINGS",E_ITEM_IRON_LEGGINGS); - tolua_constant(tolua_S,"E_ITEM_IRON_BOOTS",E_ITEM_IRON_BOOTS); - tolua_constant(tolua_S,"E_ITEM_DIAMOND_HELMET",E_ITEM_DIAMOND_HELMET); - tolua_constant(tolua_S,"E_ITEM_DIAMOND_CHESTPLATE",E_ITEM_DIAMOND_CHESTPLATE); - tolua_constant(tolua_S,"E_ITEM_DIAMOND_LEGGINGS",E_ITEM_DIAMOND_LEGGINGS); - tolua_constant(tolua_S,"E_ITEM_DIAMOND_BOOTS",E_ITEM_DIAMOND_BOOTS); - tolua_constant(tolua_S,"E_ITEM_GOLD_HELMET",E_ITEM_GOLD_HELMET); - tolua_constant(tolua_S,"E_ITEM_GOLD_CHESTPLATE",E_ITEM_GOLD_CHESTPLATE); - tolua_constant(tolua_S,"E_ITEM_GOLD_LEGGINGS",E_ITEM_GOLD_LEGGINGS); - tolua_constant(tolua_S,"E_ITEM_GOLD_BOOTS",E_ITEM_GOLD_BOOTS); - tolua_constant(tolua_S,"E_ITEM_FLINT",E_ITEM_FLINT); - tolua_constant(tolua_S,"E_ITEM_RAW_MEAT",E_ITEM_RAW_MEAT); - tolua_constant(tolua_S,"E_ITEM_COOKED_MEAT",E_ITEM_COOKED_MEAT); - tolua_constant(tolua_S,"E_ITEM_PAINTINGS",E_ITEM_PAINTINGS); - tolua_constant(tolua_S,"E_ITEM_GOLDEN_APPLE",E_ITEM_GOLDEN_APPLE); - tolua_constant(tolua_S,"E_ITEM_SIGN",E_ITEM_SIGN); - tolua_constant(tolua_S,"E_ITEM_WOODEN_DOOR",E_ITEM_WOODEN_DOOR); - tolua_constant(tolua_S,"E_ITEM_BUCKET",E_ITEM_BUCKET); - tolua_constant(tolua_S,"E_ITEM_WATER_BUCKET",E_ITEM_WATER_BUCKET); - tolua_constant(tolua_S,"E_ITEM_LAVA_BUCKET",E_ITEM_LAVA_BUCKET); - tolua_constant(tolua_S,"E_ITEM_MINECART",E_ITEM_MINECART); - tolua_constant(tolua_S,"E_ITEM_SADDLE",E_ITEM_SADDLE); - tolua_constant(tolua_S,"E_ITEM_IRON_DOOR",E_ITEM_IRON_DOOR); - tolua_constant(tolua_S,"E_ITEM_REDSTONE_DUST",E_ITEM_REDSTONE_DUST); - tolua_constant(tolua_S,"E_ITEM_SNOWBALL",E_ITEM_SNOWBALL); - tolua_constant(tolua_S,"E_ITEM_BOAT",E_ITEM_BOAT); - tolua_constant(tolua_S,"E_ITEM_LEATHER",E_ITEM_LEATHER); - tolua_constant(tolua_S,"E_ITEM_MILK",E_ITEM_MILK); - tolua_constant(tolua_S,"E_ITEM_CLAY_BRICK",E_ITEM_CLAY_BRICK); - tolua_constant(tolua_S,"E_ITEM_CLAY",E_ITEM_CLAY); - tolua_constant(tolua_S,"E_ITEM_SUGARCANE",E_ITEM_SUGARCANE); - tolua_constant(tolua_S,"E_ITEM_SUGAR_CANE",E_ITEM_SUGAR_CANE); - tolua_constant(tolua_S,"E_ITEM_PAPER",E_ITEM_PAPER); - tolua_constant(tolua_S,"E_ITEM_BOOK",E_ITEM_BOOK); - tolua_constant(tolua_S,"E_ITEM_SLIMEBALL",E_ITEM_SLIMEBALL); - tolua_constant(tolua_S,"E_ITEM_CHEST_MINECART",E_ITEM_CHEST_MINECART); - tolua_constant(tolua_S,"E_ITEM_FURNACE_MINECART",E_ITEM_FURNACE_MINECART); - tolua_constant(tolua_S,"E_ITEM_EGG",E_ITEM_EGG); - tolua_constant(tolua_S,"E_ITEM_COMPASS",E_ITEM_COMPASS); - tolua_constant(tolua_S,"E_ITEM_FISHING_ROD",E_ITEM_FISHING_ROD); - tolua_constant(tolua_S,"E_ITEM_CLOCK",E_ITEM_CLOCK); - tolua_constant(tolua_S,"E_ITEM_GLOWSTONE_DUST",E_ITEM_GLOWSTONE_DUST); - tolua_constant(tolua_S,"E_ITEM_RAW_FISH",E_ITEM_RAW_FISH); - tolua_constant(tolua_S,"E_ITEM_COOKED_FISH",E_ITEM_COOKED_FISH); - tolua_constant(tolua_S,"E_ITEM_DYE",E_ITEM_DYE); - tolua_constant(tolua_S,"E_ITEM_BONE",E_ITEM_BONE); - tolua_constant(tolua_S,"E_ITEM_SUGAR",E_ITEM_SUGAR); - tolua_constant(tolua_S,"E_ITEM_CAKE",E_ITEM_CAKE); - tolua_constant(tolua_S,"E_ITEM_BED",E_ITEM_BED); - tolua_constant(tolua_S,"E_ITEM_REDSTONE_REPEATER",E_ITEM_REDSTONE_REPEATER); - tolua_constant(tolua_S,"E_ITEM_COOKIE",E_ITEM_COOKIE); - tolua_constant(tolua_S,"E_ITEM_MAP",E_ITEM_MAP); - tolua_constant(tolua_S,"E_ITEM_SHEARS",E_ITEM_SHEARS); - tolua_constant(tolua_S,"E_ITEM_MELON_SLICE",E_ITEM_MELON_SLICE); - tolua_constant(tolua_S,"E_ITEM_PUMPKIN_SEEDS",E_ITEM_PUMPKIN_SEEDS); - tolua_constant(tolua_S,"E_ITEM_MELON_SEEDS",E_ITEM_MELON_SEEDS); - tolua_constant(tolua_S,"E_ITEM_RAW_BEEF",E_ITEM_RAW_BEEF); - tolua_constant(tolua_S,"E_ITEM_STEAK",E_ITEM_STEAK); - tolua_constant(tolua_S,"E_ITEM_RAW_CHICKEN",E_ITEM_RAW_CHICKEN); - tolua_constant(tolua_S,"E_ITEM_COOKED_CHICKEN",E_ITEM_COOKED_CHICKEN); - tolua_constant(tolua_S,"E_ITEM_ROTTEN_FLESH",E_ITEM_ROTTEN_FLESH); - tolua_constant(tolua_S,"E_ITEM_ENDER_PEARL",E_ITEM_ENDER_PEARL); - tolua_constant(tolua_S,"E_ITEM_BLAZE_ROD",E_ITEM_BLAZE_ROD); - tolua_constant(tolua_S,"E_ITEM_GHAST_TEAR",E_ITEM_GHAST_TEAR); - tolua_constant(tolua_S,"E_ITEM_GOLD_NUGGET",E_ITEM_GOLD_NUGGET); - tolua_constant(tolua_S,"E_ITEM_NETHER_WART",E_ITEM_NETHER_WART); - tolua_constant(tolua_S,"E_ITEM_POTIONS",E_ITEM_POTIONS); - tolua_constant(tolua_S,"E_ITEM_GLASS_BOTTLE",E_ITEM_GLASS_BOTTLE); - tolua_constant(tolua_S,"E_ITEM_SPIDER_EYE",E_ITEM_SPIDER_EYE); - tolua_constant(tolua_S,"E_ITEM_FERMENTED_SPIDER_EYE",E_ITEM_FERMENTED_SPIDER_EYE); - tolua_constant(tolua_S,"E_ITEM_BLAZE_POWDER",E_ITEM_BLAZE_POWDER); - tolua_constant(tolua_S,"E_ITEM_MAGMA_CREAM",E_ITEM_MAGMA_CREAM); - tolua_constant(tolua_S,"E_ITEM_BREWING_STAND",E_ITEM_BREWING_STAND); - tolua_constant(tolua_S,"E_ITEM_CAULDRON",E_ITEM_CAULDRON); - tolua_constant(tolua_S,"E_ITEM_EYE_OF_ENDER",E_ITEM_EYE_OF_ENDER); - tolua_constant(tolua_S,"E_ITEM_GLISTERING_MELON",E_ITEM_GLISTERING_MELON); - tolua_constant(tolua_S,"E_ITEM_SPAWN_EGG",E_ITEM_SPAWN_EGG); - tolua_constant(tolua_S,"E_ITEM_BOTTLE_O_ENCHANTING",E_ITEM_BOTTLE_O_ENCHANTING); - tolua_constant(tolua_S,"E_ITEM_FIRE_CHARGE",E_ITEM_FIRE_CHARGE); - tolua_constant(tolua_S,"E_ITEM_BOOK_AND_QUILL",E_ITEM_BOOK_AND_QUILL); - tolua_constant(tolua_S,"E_ITEM_WRITTEN_BOOK",E_ITEM_WRITTEN_BOOK); - tolua_constant(tolua_S,"E_ITEM_EMERALD",E_ITEM_EMERALD); - tolua_constant(tolua_S,"E_ITEM_13_DISC",E_ITEM_13_DISC); - tolua_constant(tolua_S,"E_ITEM_CAT_DISC",E_ITEM_CAT_DISC); - tolua_constant(tolua_S,"E_ITEM_BLOCKS_DISC",E_ITEM_BLOCKS_DISC); - tolua_constant(tolua_S,"E_ITEM_CHIRP_DISC",E_ITEM_CHIRP_DISC); - tolua_constant(tolua_S,"E_ITEM_FAR_DISC",E_ITEM_FAR_DISC); - tolua_constant(tolua_S,"E_ITEM_MALL_DISC",E_ITEM_MALL_DISC); - tolua_constant(tolua_S,"E_ITEM_MELLOHI_DISC",E_ITEM_MELLOHI_DISC); - tolua_constant(tolua_S,"E_ITEM_STAL_DISC",E_ITEM_STAL_DISC); - tolua_constant(tolua_S,"E_ITEM_STRAD_DISC",E_ITEM_STRAD_DISC); - tolua_constant(tolua_S,"E_ITEM_WARD_DISC",E_ITEM_WARD_DISC); - tolua_constant(tolua_S,"E_ITEM_11_DISC",E_ITEM_11_DISC); - tolua_constant(tolua_S,"E_META_PLANKS_APPLE",E_META_PLANKS_APPLE); - tolua_constant(tolua_S,"E_META_PLANKS_CONIFER",E_META_PLANKS_CONIFER); - tolua_constant(tolua_S,"E_META_PLANKS_BIRCH",E_META_PLANKS_BIRCH); - tolua_constant(tolua_S,"E_META_PLANKS_JUNGLE",E_META_PLANKS_JUNGLE); - tolua_constant(tolua_S,"E_META_LOG_APPLE",E_META_LOG_APPLE); - tolua_constant(tolua_S,"E_META_LOG_CONIFER",E_META_LOG_CONIFER); - tolua_constant(tolua_S,"E_META_LOG_BIRCH",E_META_LOG_BIRCH); - tolua_constant(tolua_S,"E_META_LOG_JUNGLE",E_META_LOG_JUNGLE); - tolua_constant(tolua_S,"E_META_LEAVES_APPLE",E_META_LEAVES_APPLE); - tolua_constant(tolua_S,"E_META_LEAVES_CONIFER",E_META_LEAVES_CONIFER); - tolua_constant(tolua_S,"E_META_LEAVES_BIRCH",E_META_LEAVES_BIRCH); - tolua_constant(tolua_S,"E_META_LEAVES_JUNGLE",E_META_LEAVES_JUNGLE); - tolua_constant(tolua_S,"E_META_SAPLING_APPLE",E_META_SAPLING_APPLE); - tolua_constant(tolua_S,"E_META_SAPLING_CONIFER",E_META_SAPLING_CONIFER); - tolua_constant(tolua_S,"E_META_SAPLING_BIRCH",E_META_SAPLING_BIRCH); - tolua_constant(tolua_S,"E_META_SAPLING_JUNGLE",E_META_SAPLING_JUNGLE); - tolua_constant(tolua_S,"E_META_TALL_GRASS_DEAD_SHRUB",E_META_TALL_GRASS_DEAD_SHRUB); - tolua_constant(tolua_S,"E_META_TALL_GRASS_GRASS",E_META_TALL_GRASS_GRASS); - tolua_constant(tolua_S,"E_META_TALL_GRASS_FERN",E_META_TALL_GRASS_FERN); - tolua_constant(tolua_S,"E_META_SANDSTONE_NORMAL",E_META_SANDSTONE_NORMAL); - tolua_constant(tolua_S,"E_META_SANDSTONE_ORNAMENT",E_META_SANDSTONE_ORNAMENT); - tolua_constant(tolua_S,"E_META_SANDSTONE_SMOOTH",E_META_SANDSTONE_SMOOTH); - tolua_constant(tolua_S,"E_META_WOOL_WHITE",E_META_WOOL_WHITE); - tolua_constant(tolua_S,"E_META_WOOL_ORANGE",E_META_WOOL_ORANGE); - tolua_constant(tolua_S,"E_META_WOOL_MAGENTA",E_META_WOOL_MAGENTA); - tolua_constant(tolua_S,"E_META_WOOL_LIGHTBLUE",E_META_WOOL_LIGHTBLUE); - tolua_constant(tolua_S,"E_META_WOOL_YELLOW",E_META_WOOL_YELLOW); - tolua_constant(tolua_S,"E_META_WOOL_LIGHTGREEN",E_META_WOOL_LIGHTGREEN); - tolua_constant(tolua_S,"E_META_WOOL_PINK",E_META_WOOL_PINK); - tolua_constant(tolua_S,"E_META_WOOL_GRAY",E_META_WOOL_GRAY); - tolua_constant(tolua_S,"E_META_WOOL_LIGHTGRAY",E_META_WOOL_LIGHTGRAY); - tolua_constant(tolua_S,"E_META_WOOL_CYAN",E_META_WOOL_CYAN); - tolua_constant(tolua_S,"E_META_WOOL_PURPLE",E_META_WOOL_PURPLE); - tolua_constant(tolua_S,"E_META_WOOL_BLUE",E_META_WOOL_BLUE); - tolua_constant(tolua_S,"E_META_WOOL_BROWN",E_META_WOOL_BROWN); - tolua_constant(tolua_S,"E_META_WOOL_GREEN",E_META_WOOL_GREEN); - tolua_constant(tolua_S,"E_META_WOOL_RED",E_META_WOOL_RED); - tolua_constant(tolua_S,"E_META_WOOL_BLACK",E_META_WOOL_BLACK); - tolua_constant(tolua_S,"E_META_DOUBLE_STEP_STONE",E_META_DOUBLE_STEP_STONE); - tolua_constant(tolua_S,"E_META_DOUBLE_STEP_SANDSTONE",E_META_DOUBLE_STEP_SANDSTONE); - tolua_constant(tolua_S,"E_META_DOUBLE_STEP_WOODEN",E_META_DOUBLE_STEP_WOODEN); - tolua_constant(tolua_S,"E_META_DOUBLE_STEP_COBBLESTONE",E_META_DOUBLE_STEP_COBBLESTONE); - tolua_constant(tolua_S,"E_META_DOUBLE_STEP_BRICK",E_META_DOUBLE_STEP_BRICK); - tolua_constant(tolua_S,"E_META_DOUBLE_STEP_STONE_BRICK",E_META_DOUBLE_STEP_STONE_BRICK); - tolua_constant(tolua_S,"E_META_DOUBLE_STEP_STONE_SECRET",E_META_DOUBLE_STEP_STONE_SECRET); - tolua_constant(tolua_S,"E_META_STEP_STONE",E_META_STEP_STONE); - tolua_constant(tolua_S,"E_META_STEP_SANDSTONE",E_META_STEP_SANDSTONE); - tolua_constant(tolua_S,"E_META_STEP_PLANKS",E_META_STEP_PLANKS); - tolua_constant(tolua_S,"E_META_STEP_COBBLESTONE",E_META_STEP_COBBLESTONE); - tolua_constant(tolua_S,"E_META_STEP_BRICK",E_META_STEP_BRICK); - tolua_constant(tolua_S,"E_META_STEP_STONE_BRICK",E_META_STEP_STONE_BRICK); - tolua_constant(tolua_S,"E_META_STEP_STONE_SECRET",E_META_STEP_STONE_SECRET); - tolua_constant(tolua_S,"E_META_SILVERFISH_EGG_STONE",E_META_SILVERFISH_EGG_STONE); - tolua_constant(tolua_S,"E_META_SILVERFISH_EGG_COBBLESTONE",E_META_SILVERFISH_EGG_COBBLESTONE); - tolua_constant(tolua_S,"E_META_SILVERFISH_EGG_STONE_BRICK",E_META_SILVERFISH_EGG_STONE_BRICK); - tolua_constant(tolua_S,"E_META_STONE_BRICK_NORMAL",E_META_STONE_BRICK_NORMAL); - tolua_constant(tolua_S,"E_META_STONE_BRICK_MOSSY",E_META_STONE_BRICK_MOSSY); - tolua_constant(tolua_S,"E_META_STONE_BRICK_CRACKED",E_META_STONE_BRICK_CRACKED); - tolua_constant(tolua_S,"E_META_STONE_BRICK_ORNAMENT",E_META_STONE_BRICK_ORNAMENT); - tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_APPLE",E_BLOCK_WOODEN_DOUBLE_STEP_APPLE); - tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_CONIFER",E_BLOCK_WOODEN_DOUBLE_STEP_CONIFER); - tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_BIRCH",E_BLOCK_WOODEN_DOUBLE_STEP_BIRCH); - tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_JUNGLE",E_BLOCK_WOODEN_DOUBLE_STEP_JUNGLE); - tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_APPLE",E_BLOCK_WOODEN_STEP_APPLE); - tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_CONIFER",E_BLOCK_WOODEN_STEP_CONIFER); - tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_BIRCH",E_BLOCK_WOODEN_STEP_BIRCH); - tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_JUNGLE",E_BLOCK_WOODEN_STEP_JUNGLE); - tolua_constant(tolua_S,"E_META_COAL_NORMAL",E_META_COAL_NORMAL); - tolua_constant(tolua_S,"E_META_COAL_CHARCOAL",E_META_COAL_CHARCOAL); - tolua_constant(tolua_S,"E_META_GOLDEN_APPLE_NORMAL",E_META_GOLDEN_APPLE_NORMAL); - tolua_constant(tolua_S,"E_META_GOLDEN_APPLE_ENCHANTED",E_META_GOLDEN_APPLE_ENCHANTED); - tolua_constant(tolua_S,"E_META_DYE_BLACK",E_META_DYE_BLACK); - tolua_constant(tolua_S,"E_META_DYE_RED",E_META_DYE_RED); - tolua_constant(tolua_S,"E_META_DYE_GREEN",E_META_DYE_GREEN); - tolua_constant(tolua_S,"E_META_DYE_BROWN",E_META_DYE_BROWN); - tolua_constant(tolua_S,"E_META_DYE_BLUE",E_META_DYE_BLUE); - tolua_constant(tolua_S,"E_META_DYE_PURPLE",E_META_DYE_PURPLE); - tolua_constant(tolua_S,"E_META_DYE_CYAN",E_META_DYE_CYAN); - tolua_constant(tolua_S,"E_META_DYE_LIGHTGRAY",E_META_DYE_LIGHTGRAY); - tolua_constant(tolua_S,"E_META_DYE_GRAY",E_META_DYE_GRAY); - tolua_constant(tolua_S,"E_META_DYE_PINK",E_META_DYE_PINK); - tolua_constant(tolua_S,"E_META_DYE_LIGHTGREEN",E_META_DYE_LIGHTGREEN); - tolua_constant(tolua_S,"E_META_DYE_YELLOW",E_META_DYE_YELLOW); - tolua_constant(tolua_S,"E_META_DYE_LIGHTBLUE",E_META_DYE_LIGHTBLUE); - tolua_constant(tolua_S,"E_META_DYE_MAGENTA",E_META_DYE_MAGENTA); - tolua_constant(tolua_S,"E_META_DYE_ORANGE",E_META_DYE_ORANGE); - tolua_constant(tolua_S,"E_META_DYE_WHITE",E_META_DYE_WHITE); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_CREEPER",E_META_SPAWN_EGG_CREEPER); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_SKELETON",E_META_SPAWN_EGG_SKELETON); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_SPIDER",E_META_SPAWN_EGG_SPIDER); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_ZOMBIE",E_META_SPAWN_EGG_ZOMBIE); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_SLIME",E_META_SPAWN_EGG_SLIME); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_GHAST",E_META_SPAWN_EGG_GHAST); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_ZOMBIE_PIGMAN",E_META_SPAWN_EGG_ZOMBIE_PIGMAN); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_ENDERMAN",E_META_SPAWN_EGG_ENDERMAN); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_CAVE_SPIDER",E_META_SPAWN_EGG_CAVE_SPIDER); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_SILVERFISH",E_META_SPAWN_EGG_SILVERFISH); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_BLAZE",E_META_SPAWN_EGG_BLAZE); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_MAGMA_CUBE",E_META_SPAWN_EGG_MAGMA_CUBE); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_GIANT",E_META_SPAWN_EGG_GIANT); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_ENDER_DRAGON",E_META_SPAWN_EGG_ENDER_DRAGON); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_PIG",E_META_SPAWN_EGG_PIG); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_SHEEP",E_META_SPAWN_EGG_SHEEP); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_COW",E_META_SPAWN_EGG_COW); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_CHICKEN",E_META_SPAWN_EGG_CHICKEN); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_SQUID",E_META_SPAWN_EGG_SQUID); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_WOLF",E_META_SPAWN_EGG_WOLF); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_MOOSHROOM",E_META_SPAWN_EGG_MOOSHROOM); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_OCELOT",E_META_SPAWN_EGG_OCELOT); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_VILLAGER",E_META_SPAWN_EGG_VILLAGER); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_SNOW_GOLEM",E_META_SPAWN_EGG_SNOW_GOLEM); - tolua_constant(tolua_S,"E_META_SPAWN_EGG_IRON_GOLEM",E_META_SPAWN_EGG_IRON_GOLEM); - tolua_function(tolua_S,"BlockStringToType",tolua_AllToLua_BlockStringToType00); - tolua_function(tolua_S,"StringToItem",tolua_AllToLua_StringToItem00); - tolua_constant(tolua_S,"E_KEEP_ALIVE",E_KEEP_ALIVE); - tolua_constant(tolua_S,"E_LOGIN",E_LOGIN); - tolua_constant(tolua_S,"E_HANDSHAKE",E_HANDSHAKE); - tolua_constant(tolua_S,"E_CHAT",E_CHAT); - tolua_constant(tolua_S,"E_UPDATE_TIME",E_UPDATE_TIME); - tolua_constant(tolua_S,"E_ENTITY_EQUIPMENT",E_ENTITY_EQUIPMENT); - tolua_constant(tolua_S,"E_USE_ENTITY",E_USE_ENTITY); - tolua_constant(tolua_S,"E_UPDATE_HEALTH",E_UPDATE_HEALTH); - tolua_constant(tolua_S,"E_RESPAWN",E_RESPAWN); - tolua_constant(tolua_S,"E_FLYING",E_FLYING); - tolua_constant(tolua_S,"E_PLAYERPOS",E_PLAYERPOS); - tolua_constant(tolua_S,"E_PLAYERLOOK",E_PLAYERLOOK); - tolua_constant(tolua_S,"E_PLAYERMOVELOOK",E_PLAYERMOVELOOK); - tolua_constant(tolua_S,"E_BLOCK_DIG",E_BLOCK_DIG); - tolua_constant(tolua_S,"E_BLOCK_PLACE",E_BLOCK_PLACE); - tolua_constant(tolua_S,"E_ITEM_SWITCH",E_ITEM_SWITCH); - tolua_constant(tolua_S,"E_ADD_TO_INV",E_ADD_TO_INV); - tolua_constant(tolua_S,"E_ANIMATION",E_ANIMATION); - tolua_constant(tolua_S,"E_PACKET_13",E_PACKET_13); - tolua_constant(tolua_S,"E_NAMED_ENTITY_SPAWN",E_NAMED_ENTITY_SPAWN); - tolua_constant(tolua_S,"E_PICKUP_SPAWN",E_PICKUP_SPAWN); - tolua_constant(tolua_S,"E_COLLECT_ITEM",E_COLLECT_ITEM); - tolua_constant(tolua_S,"E_ADD_VEHICLE",E_ADD_VEHICLE); - tolua_constant(tolua_S,"E_SPAWN_MOB",E_SPAWN_MOB); - tolua_constant(tolua_S,"E_DESTROY_ENT",E_DESTROY_ENT); - tolua_constant(tolua_S,"E_ENTITY",E_ENTITY); - tolua_constant(tolua_S,"E_REL_ENT_MOVE",E_REL_ENT_MOVE); - tolua_constant(tolua_S,"E_ENT_LOOK",E_ENT_LOOK); - tolua_constant(tolua_S,"E_REL_ENT_MOVE_LOOK",E_REL_ENT_MOVE_LOOK); - tolua_constant(tolua_S,"E_ENT_TELEPORT",E_ENT_TELEPORT); - tolua_constant(tolua_S,"E_ENT_HEAD_LOOK",E_ENT_HEAD_LOOK); - tolua_constant(tolua_S,"E_ENT_STATUS",E_ENT_STATUS); - tolua_constant(tolua_S,"E_METADATA",E_METADATA); - tolua_constant(tolua_S,"E_PRE_CHUNK",E_PRE_CHUNK); - tolua_constant(tolua_S,"E_MAP_CHUNK",E_MAP_CHUNK); - tolua_constant(tolua_S,"E_MULTI_BLOCK",E_MULTI_BLOCK); - tolua_constant(tolua_S,"E_BLOCK_CHANGE",E_BLOCK_CHANGE); - tolua_constant(tolua_S,"E_BLOCK_ACTION",E_BLOCK_ACTION); - tolua_constant(tolua_S,"E_EXPLOSION",E_EXPLOSION); - tolua_constant(tolua_S,"E_SOUND_EFFECT",E_SOUND_EFFECT); - tolua_constant(tolua_S,"E_NEW_INVALID_STATE",E_NEW_INVALID_STATE); - tolua_constant(tolua_S,"E_THUNDERBOLT",E_THUNDERBOLT); - tolua_constant(tolua_S,"E_WINDOW_OPEN",E_WINDOW_OPEN); - tolua_constant(tolua_S,"E_WINDOW_CLOSE",E_WINDOW_CLOSE); - tolua_constant(tolua_S,"E_WINDOW_CLICK",E_WINDOW_CLICK); - tolua_constant(tolua_S,"E_INVENTORY_SLOT",E_INVENTORY_SLOT); - tolua_constant(tolua_S,"E_INVENTORY_WHOLE",E_INVENTORY_WHOLE); - tolua_constant(tolua_S,"E_INVENTORY_PROGRESS",E_INVENTORY_PROGRESS); - tolua_constant(tolua_S,"E_CREATIVE_INVENTORY_ACTION",E_CREATIVE_INVENTORY_ACTION); - tolua_constant(tolua_S,"E_UPDATE_SIGN",E_UPDATE_SIGN); - tolua_constant(tolua_S,"E_PLAYER_LIST_ITEM",E_PLAYER_LIST_ITEM); - tolua_constant(tolua_S,"E_PLAYER_ABILITIES",E_PLAYER_ABILITIES); - tolua_constant(tolua_S,"E_PING",E_PING); - tolua_constant(tolua_S,"E_DISCONNECT",E_DISCONNECT); - tolua_array(tolua_S,"g_BlockLightValue",tolua_get_AllToLua_g_BlockLightValue,tolua_set_AllToLua_g_BlockLightValue); - tolua_array(tolua_S,"g_BlockSpreadLightFalloff",tolua_get_AllToLua_g_BlockSpreadLightFalloff,tolua_set_AllToLua_g_BlockSpreadLightFalloff); - tolua_array(tolua_S,"g_BlockTransparent",tolua_get_AllToLua_g_BlockTransparent,tolua_set_AllToLua_g_BlockTransparent); - tolua_array(tolua_S,"g_BlockOneHitDig",tolua_get_AllToLua_g_BlockOneHitDig,tolua_set_AllToLua_g_BlockOneHitDig); - tolua_function(tolua_S,"IsValidBlock",tolua_AllToLua_IsValidBlock00); - tolua_function(tolua_S,"IsValidItem",tolua_AllToLua_IsValidItem00); - tolua_function(tolua_S,"AddDirection",tolua_AllToLua_AddDirection00); - tolua_module(tolua_S,"ItemCategory",0); - tolua_beginmodule(tolua_S,"ItemCategory"); - tolua_function(tolua_S,"IsPickaxe",tolua_AllToLua_ItemCategory_IsPickaxe00); - tolua_function(tolua_S,"IsAxe",tolua_AllToLua_ItemCategory_IsAxe00); - tolua_function(tolua_S,"IsSword",tolua_AllToLua_ItemCategory_IsSword00); - tolua_function(tolua_S,"IsHoe",tolua_AllToLua_ItemCategory_IsHoe00); - tolua_function(tolua_S,"IsShovel",tolua_AllToLua_ItemCategory_IsShovel00); - tolua_function(tolua_S,"IsTool",tolua_AllToLua_ItemCategory_IsTool00); - tolua_endmodule(tolua_S); - tolua_constant(tolua_S,"eGameMode_Survival",eGameMode_Survival); - tolua_constant(tolua_S,"eGameMode_Creative",eGameMode_Creative); - tolua_constant(tolua_S,"eWeather_Sunny",eWeather_Sunny); - tolua_constant(tolua_S,"eWeather_Rain",eWeather_Rain); - tolua_constant(tolua_S,"eWeather_ThunderStorm",eWeather_ThunderStorm); - tolua_function(tolua_S,"GetTime",tolua_AllToLua_GetTime00); - tolua_function(tolua_S,"GetChar",tolua_AllToLua_GetChar00); - tolua_cclass(tolua_S,"cStringMap","cStringMap","",NULL); - tolua_beginmodule(tolua_S,"cStringMap"); - tolua_function(tolua_S,"clear",tolua_AllToLua_cStringMap_clear00); - tolua_function(tolua_S,"size",tolua_AllToLua_cStringMap_size00); - tolua_function(tolua_S,"get",tolua_AllToLua_cStringMap_get00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cChatColor","cChatColor","",NULL); - tolua_beginmodule(tolua_S,"cChatColor"); - tolua_variable(tolua_S,"Color",tolua_get_cChatColor_Color,NULL); - tolua_variable(tolua_S,"Delimiter",tolua_get_cChatColor_Delimiter,NULL); - tolua_variable(tolua_S,"Black",tolua_get_cChatColor_Black,NULL); - tolua_variable(tolua_S,"Navy",tolua_get_cChatColor_Navy,NULL); - tolua_variable(tolua_S,"Green",tolua_get_cChatColor_Green,NULL); - tolua_variable(tolua_S,"Blue",tolua_get_cChatColor_Blue,NULL); - tolua_variable(tolua_S,"Red",tolua_get_cChatColor_Red,NULL); - tolua_variable(tolua_S,"Purple",tolua_get_cChatColor_Purple,NULL); - tolua_variable(tolua_S,"Gold",tolua_get_cChatColor_Gold,NULL); - tolua_variable(tolua_S,"LightGray",tolua_get_cChatColor_LightGray,NULL); - tolua_variable(tolua_S,"Gray",tolua_get_cChatColor_Gray,NULL); - tolua_variable(tolua_S,"DarkPurple",tolua_get_cChatColor_DarkPurple,NULL); - tolua_variable(tolua_S,"LightGreen",tolua_get_cChatColor_LightGreen,NULL); - tolua_variable(tolua_S,"LightBlue",tolua_get_cChatColor_LightBlue,NULL); - tolua_variable(tolua_S,"Rose",tolua_get_cChatColor_Rose,NULL); - tolua_variable(tolua_S,"LightPurple",tolua_get_cChatColor_LightPurple,NULL); - tolua_variable(tolua_S,"Yellow",tolua_get_cChatColor_Yellow,NULL); - tolua_variable(tolua_S,"White",tolua_get_cChatColor_White,NULL); - tolua_variable(tolua_S,"Random",tolua_get_cChatColor_Random,NULL); - tolua_variable(tolua_S,"Bold",tolua_get_cChatColor_Bold,NULL); - tolua_variable(tolua_S,"Strikethrough",tolua_get_cChatColor_Strikethrough,NULL); - tolua_variable(tolua_S,"Underlined",tolua_get_cChatColor_Underlined,NULL); - tolua_variable(tolua_S,"Italic",tolua_get_cChatColor_Italic,NULL); - tolua_variable(tolua_S,"Plain",tolua_get_cChatColor_Plain,NULL); - tolua_function(tolua_S,"MakeColor",tolua_AllToLua_cChatColor_MakeColor00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cClientHandle","cClientHandle","",NULL); - tolua_beginmodule(tolua_S,"cClientHandle"); - tolua_function(tolua_S,"GetPlayer",tolua_AllToLua_cClientHandle_GetPlayer00); - tolua_function(tolua_S,"Kick",tolua_AllToLua_cClientHandle_Kick00); - tolua_function(tolua_S,"GetUsername",tolua_AllToLua_cClientHandle_GetUsername00); - tolua_function(tolua_S,"GetPing",tolua_AllToLua_cClientHandle_GetPing00); - tolua_function(tolua_S,"SetViewDistance",tolua_AllToLua_cClientHandle_SetViewDistance00); - tolua_function(tolua_S,"GetViewDistance",tolua_AllToLua_cClientHandle_GetViewDistance00); - tolua_function(tolua_S,"GetUniqueID",tolua_AllToLua_cClientHandle_GetUniqueID00); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"cEntity","cEntity","",tolua_collect_cEntity); - #else - tolua_cclass(tolua_S,"cEntity","cEntity","",NULL); - #endif - tolua_beginmodule(tolua_S,"cEntity"); - tolua_function(tolua_S,"delete",tolua_AllToLua_cEntity_delete00); - tolua_function(tolua_S,"Initialize",tolua_AllToLua_cEntity_Initialize00); - tolua_constant(tolua_S,"eEntityType_Entity",cEntity::eEntityType_Entity); - tolua_constant(tolua_S,"eEntityType_Player",cEntity::eEntityType_Player); - tolua_constant(tolua_S,"eEntityType_Pickup",cEntity::eEntityType_Pickup); - tolua_function(tolua_S,"GetEntityType",tolua_AllToLua_cEntity_GetEntityType00); - tolua_function(tolua_S,"IsA",tolua_AllToLua_cEntity_IsA00); - tolua_function(tolua_S,"GetClass",tolua_AllToLua_cEntity_GetClass00); - tolua_function(tolua_S,"GetWorld",tolua_AllToLua_cEntity_GetWorld00); - tolua_function(tolua_S,"GetPosition",tolua_AllToLua_cEntity_GetPosition00); - tolua_function(tolua_S,"GetPosX",tolua_AllToLua_cEntity_GetPosX00); - tolua_function(tolua_S,"GetPosY",tolua_AllToLua_cEntity_GetPosY00); - tolua_function(tolua_S,"GetPosZ",tolua_AllToLua_cEntity_GetPosZ00); - tolua_function(tolua_S,"GetRot",tolua_AllToLua_cEntity_GetRot00); - tolua_function(tolua_S,"GetRotation",tolua_AllToLua_cEntity_GetRotation00); - tolua_function(tolua_S,"GetPitch",tolua_AllToLua_cEntity_GetPitch00); - tolua_function(tolua_S,"GetRoll",tolua_AllToLua_cEntity_GetRoll00); - tolua_function(tolua_S,"GetLookVector",tolua_AllToLua_cEntity_GetLookVector00); - tolua_function(tolua_S,"GetChunkX",tolua_AllToLua_cEntity_GetChunkX00); - tolua_function(tolua_S,"GetChunkY",tolua_AllToLua_cEntity_GetChunkY00); - tolua_function(tolua_S,"GetChunkZ",tolua_AllToLua_cEntity_GetChunkZ00); - tolua_function(tolua_S,"SetPosX",tolua_AllToLua_cEntity_SetPosX00); - tolua_function(tolua_S,"SetPosY",tolua_AllToLua_cEntity_SetPosY00); - tolua_function(tolua_S,"SetPosZ",tolua_AllToLua_cEntity_SetPosZ00); - tolua_function(tolua_S,"SetPosition",tolua_AllToLua_cEntity_SetPosition00); - tolua_function(tolua_S,"SetPosition",tolua_AllToLua_cEntity_SetPosition01); - tolua_function(tolua_S,"SetRot",tolua_AllToLua_cEntity_SetRot00); - tolua_function(tolua_S,"SetRotation",tolua_AllToLua_cEntity_SetRotation00); - tolua_function(tolua_S,"SetPitch",tolua_AllToLua_cEntity_SetPitch00); - tolua_function(tolua_S,"SetRoll",tolua_AllToLua_cEntity_SetRoll00); - tolua_function(tolua_S,"GetUniqueID",tolua_AllToLua_cEntity_GetUniqueID00); - tolua_function(tolua_S,"IsDestroyed",tolua_AllToLua_cEntity_IsDestroyed00); - tolua_function(tolua_S,"Destroy",tolua_AllToLua_cEntity_Destroy00); - tolua_function(tolua_S,"Tick",tolua_AllToLua_cEntity_Tick00); - tolua_function(tolua_S,"SpawnOn",tolua_AllToLua_cEntity_SpawnOn00); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"Lua__cEntity","Lua__cEntity","cEntity",tolua_collect_Lua__cEntity); - #else - tolua_cclass(tolua_S,"Lua__cEntity","Lua__cEntity","cEntity",NULL); - #endif - tolua_beginmodule(tolua_S,"Lua__cEntity"); - tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cEntity_tolua__set_instance00); - tolua_function(tolua_S,"cEntity__Initialize",tolua_AllToLua_Lua__cEntity_cEntity__Initialize00); - tolua_function(tolua_S,"cEntity__GetEntityType",tolua_AllToLua_Lua__cEntity_cEntity__GetEntityType00); - tolua_function(tolua_S,"cEntity__IsA",tolua_AllToLua_Lua__cEntity_cEntity__IsA00); - tolua_function(tolua_S,"cEntity__GetClass",tolua_AllToLua_Lua__cEntity_cEntity__GetClass00); - tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cEntity_new00); - tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cEntity_new00_local); - tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cEntity_new00_local); - tolua_function(tolua_S,"delete",tolua_AllToLua_Lua__cEntity_delete00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"TakeDamageInfo","TakeDamageInfo","",NULL); - tolua_beginmodule(tolua_S,"TakeDamageInfo"); - tolua_variable(tolua_S,"Damage",tolua_get_TakeDamageInfo_Damage,tolua_set_TakeDamageInfo_Damage); - tolua_variable(tolua_S,"Instigator",tolua_get_TakeDamageInfo_Instigator_ptr,tolua_set_TakeDamageInfo_Instigator_ptr); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cPawn","cPawn","cEntity",NULL); - tolua_beginmodule(tolua_S,"cPawn"); - tolua_function(tolua_S,"TeleportToEntity",tolua_AllToLua_cPawn_TeleportToEntity00); - tolua_function(tolua_S,"TeleportTo",tolua_AllToLua_cPawn_TeleportTo00); - tolua_function(tolua_S,"Heal",tolua_AllToLua_cPawn_Heal00); - tolua_function(tolua_S,"TakeDamage",tolua_AllToLua_cPawn_TakeDamage00); - tolua_function(tolua_S,"KilledBy",tolua_AllToLua_cPawn_KilledBy00); - tolua_function(tolua_S,"GetHealth",tolua_AllToLua_cPawn_GetHealth00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"Lua__cPawn","Lua__cPawn","cPawn",NULL); - tolua_beginmodule(tolua_S,"Lua__cPawn"); - tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPawn_tolua__set_instance00); - tolua_function(tolua_S,"cPawn__TeleportToEntity",tolua_AllToLua_Lua__cPawn_cPawn__TeleportToEntity00); - tolua_function(tolua_S,"cPawn__TeleportTo",tolua_AllToLua_Lua__cPawn_cPawn__TeleportTo00); - tolua_function(tolua_S,"cPawn__TakeDamage",tolua_AllToLua_Lua__cPawn_cPawn__TakeDamage00); - tolua_function(tolua_S,"cPawn__KilledBy",tolua_AllToLua_Lua__cPawn_cPawn__KilledBy00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cPlayer","cPlayer","cPawn",NULL); - tolua_beginmodule(tolua_S,"cPlayer"); - tolua_function(tolua_S,"Initialize",tolua_AllToLua_cPlayer_Initialize00); - tolua_function(tolua_S,"GetEyeHeight",tolua_AllToLua_cPlayer_GetEyeHeight00); - tolua_function(tolua_S,"GetEyePosition",tolua_AllToLua_cPlayer_GetEyePosition00); - tolua_function(tolua_S,"GetFlying",tolua_AllToLua_cPlayer_GetFlying00); - tolua_function(tolua_S,"GetStance",tolua_AllToLua_cPlayer_GetStance00); - tolua_function(tolua_S,"GetInventory",tolua_AllToLua_cPlayer_GetInventory00); - tolua_function(tolua_S,"TeleportTo",tolua_AllToLua_cPlayer_TeleportTo00); - tolua_function(tolua_S,"GetGameMode",tolua_AllToLua_cPlayer_GetGameMode00); - tolua_function(tolua_S,"GetIP",tolua_AllToLua_cPlayer_GetIP00); - tolua_function(tolua_S,"GetLastBlockActionTime",tolua_AllToLua_cPlayer_GetLastBlockActionTime00); - tolua_function(tolua_S,"GetLastBlockActionCnt",tolua_AllToLua_cPlayer_GetLastBlockActionCnt00); - tolua_function(tolua_S,"SetLastBlockActionCnt",tolua_AllToLua_cPlayer_SetLastBlockActionCnt00); - tolua_function(tolua_S,"SetLastBlockActionTime",tolua_AllToLua_cPlayer_SetLastBlockActionTime00); - tolua_function(tolua_S,"SetGameMode",tolua_AllToLua_cPlayer_SetGameMode00); - tolua_function(tolua_S,"MoveTo",tolua_AllToLua_cPlayer_MoveTo00); - tolua_function(tolua_S,"GetClientHandle",tolua_AllToLua_cPlayer_GetClientHandle00); - tolua_function(tolua_S,"SendMessage",tolua_AllToLua_cPlayer_SendMessage00); - tolua_function(tolua_S,"GetName",tolua_AllToLua_cPlayer_GetName00); - tolua_function(tolua_S,"SetName",tolua_AllToLua_cPlayer_SetName00); - tolua_function(tolua_S,"AddToGroup",tolua_AllToLua_cPlayer_AddToGroup00); - tolua_function(tolua_S,"CanUseCommand",tolua_AllToLua_cPlayer_CanUseCommand00); - tolua_function(tolua_S,"HasPermission",tolua_AllToLua_cPlayer_HasPermission00); - tolua_function(tolua_S,"IsInGroup",tolua_AllToLua_cPlayer_IsInGroup00); - tolua_function(tolua_S,"GetColor",tolua_AllToLua_cPlayer_GetColor00); - tolua_function(tolua_S,"TossItem",tolua_AllToLua_cPlayer_TossItem00); - tolua_function(tolua_S,"Heal",tolua_AllToLua_cPlayer_Heal00); - tolua_function(tolua_S,"TakeDamage",tolua_AllToLua_cPlayer_TakeDamage00); - tolua_function(tolua_S,"KilledBy",tolua_AllToLua_cPlayer_KilledBy00); - tolua_function(tolua_S,"Respawn",tolua_AllToLua_cPlayer_Respawn00); - tolua_function(tolua_S,"SetVisible",tolua_AllToLua_cPlayer_SetVisible00); - tolua_function(tolua_S,"IsVisible",tolua_AllToLua_cPlayer_IsVisible00); - tolua_function(tolua_S,"MoveToWorld",tolua_AllToLua_cPlayer_MoveToWorld00); - tolua_function(tolua_S,"LoadPermissionsFromDisk",tolua_AllToLua_cPlayer_LoadPermissionsFromDisk00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"Lua__cPlayer","Lua__cPlayer","cPlayer",NULL); - tolua_beginmodule(tolua_S,"Lua__cPlayer"); - tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPlayer_tolua__set_instance00); - tolua_function(tolua_S,"cPlayer__Initialize",tolua_AllToLua_Lua__cPlayer_cPlayer__Initialize00); - tolua_function(tolua_S,"cPlayer__TeleportTo",tolua_AllToLua_Lua__cPlayer_cPlayer__TeleportTo00); - tolua_function(tolua_S,"cPlayer__MoveTo",tolua_AllToLua_Lua__cPlayer_cPlayer__MoveTo00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cPluginManager","cPluginManager","",NULL); - tolua_beginmodule(tolua_S,"cPluginManager"); - tolua_constant(tolua_S,"HOOK_TICK",cPluginManager::HOOK_TICK); - tolua_constant(tolua_S,"HOOK_CHAT",cPluginManager::HOOK_CHAT); - tolua_constant(tolua_S,"HOOK_COLLECT_ITEM",cPluginManager::HOOK_COLLECT_ITEM); - tolua_constant(tolua_S,"HOOK_BLOCK_DIG",cPluginManager::HOOK_BLOCK_DIG); - tolua_constant(tolua_S,"HOOK_BLOCK_PLACE",cPluginManager::HOOK_BLOCK_PLACE); - tolua_constant(tolua_S,"HOOK_DISCONNECT",cPluginManager::HOOK_DISCONNECT); - tolua_constant(tolua_S,"HOOK_HANDSHAKE",cPluginManager::HOOK_HANDSHAKE); - tolua_constant(tolua_S,"HOOK_LOGIN",cPluginManager::HOOK_LOGIN); - tolua_constant(tolua_S,"HOOK_PLAYER_SPAWN",cPluginManager::HOOK_PLAYER_SPAWN); - tolua_constant(tolua_S,"HOOK_PLAYER_JOIN",cPluginManager::HOOK_PLAYER_JOIN); - tolua_constant(tolua_S,"HOOK_PLAYER_MOVE",cPluginManager::HOOK_PLAYER_MOVE); - tolua_constant(tolua_S,"HOOK_TAKE_DAMAGE",cPluginManager::HOOK_TAKE_DAMAGE); - tolua_constant(tolua_S,"HOOK_KILLED",cPluginManager::HOOK_KILLED); - tolua_constant(tolua_S,"HOOK_CHUNK_GENERATED",cPluginManager::HOOK_CHUNK_GENERATED); - tolua_constant(tolua_S,"HOOK_CHUNK_GENERATING",cPluginManager::HOOK_CHUNK_GENERATING); - tolua_constant(tolua_S,"HOOK_BLOCK_TO_DROPS",cPluginManager::HOOK_BLOCK_TO_DROPS); - tolua_constant(tolua_S,"HOOK_PRE_CRAFTING",cPluginManager::HOOK_PRE_CRAFTING); - tolua_constant(tolua_S,"HOOK_CRAFTING_NO_RECIPE",cPluginManager::HOOK_CRAFTING_NO_RECIPE); - tolua_constant(tolua_S,"HOOK_POST_CRAFTING",cPluginManager::HOOK_POST_CRAFTING); - tolua_constant(tolua_S,"HOOK_BLOCK_TO_PICKUP",cPluginManager::HOOK_BLOCK_TO_PICKUP); - tolua_constant(tolua_S,"HOOK_WEATHER_CHANGE",cPluginManager::HOOK_WEATHER_CHANGE); - tolua_constant(tolua_S,"E_PLUGIN_TICK",cPluginManager::E_PLUGIN_TICK); - tolua_constant(tolua_S,"E_PLUGIN_CHAT",cPluginManager::E_PLUGIN_CHAT); - tolua_constant(tolua_S,"E_PLUGIN_COLLECT_ITEM",cPluginManager::E_PLUGIN_COLLECT_ITEM); - tolua_constant(tolua_S,"E_PLUGIN_BLOCK_DIG",cPluginManager::E_PLUGIN_BLOCK_DIG); - tolua_constant(tolua_S,"E_PLUGIN_BLOCK_PLACE",cPluginManager::E_PLUGIN_BLOCK_PLACE); - tolua_constant(tolua_S,"E_PLUGIN_DISCONNECT",cPluginManager::E_PLUGIN_DISCONNECT); - tolua_constant(tolua_S,"E_PLUGIN_HANDSHAKE",cPluginManager::E_PLUGIN_HANDSHAKE); - tolua_constant(tolua_S,"E_PLUGIN_LOGIN",cPluginManager::E_PLUGIN_LOGIN); - tolua_constant(tolua_S,"E_PLUGIN_PLAYER_SPAWN",cPluginManager::E_PLUGIN_PLAYER_SPAWN); - tolua_constant(tolua_S,"E_PLUGIN_PLAYER_JOIN",cPluginManager::E_PLUGIN_PLAYER_JOIN); - tolua_constant(tolua_S,"E_PLUGIN_PLAYER_MOVE",cPluginManager::E_PLUGIN_PLAYER_MOVE); - tolua_constant(tolua_S,"E_PLUGIN_TAKE_DAMAGE",cPluginManager::E_PLUGIN_TAKE_DAMAGE); - tolua_constant(tolua_S,"E_PLUGIN_KILLED",cPluginManager::E_PLUGIN_KILLED); - tolua_constant(tolua_S,"E_PLUGIN_CHUNK_GENERATED",cPluginManager::E_PLUGIN_CHUNK_GENERATED); - tolua_constant(tolua_S,"E_PLUGIN_CHUNK_GENERATING",cPluginManager::E_PLUGIN_CHUNK_GENERATING); - tolua_constant(tolua_S,"E_PLUGIN_BLOCK_TO_DROPS",cPluginManager::E_PLUGIN_BLOCK_TO_DROPS); - tolua_function(tolua_S,"GetPluginManager",tolua_AllToLua_cPluginManager_GetPluginManager00); - tolua_function(tolua_S,"GetPlugin",tolua_AllToLua_cPluginManager_GetPlugin00); - tolua_function(tolua_S,"ReloadPlugins",tolua_AllToLua_cPluginManager_ReloadPlugins00); - tolua_function(tolua_S,"AddPlugin",tolua_AllToLua_cPluginManager_AddPlugin00); - tolua_function(tolua_S,"AddHook",tolua_AllToLua_cPluginManager_AddHook00); - tolua_function(tolua_S,"GetNumPlugins",tolua_AllToLua_cPluginManager_GetNumPlugins00); - tolua_function(tolua_S,"RemovePlugin",tolua_AllToLua_cPluginManager_RemovePlugin00); - tolua_function(tolua_S,"RemoveLuaPlugin",tolua_AllToLua_cPluginManager_RemoveLuaPlugin00); - tolua_function(tolua_S,"GetLuaPlugin",tolua_AllToLua_cPluginManager_GetLuaPlugin00); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"cPlugin","cPlugin","",tolua_collect_cPlugin); - #else - tolua_cclass(tolua_S,"cPlugin","cPlugin","",NULL); - #endif - tolua_beginmodule(tolua_S,"cPlugin"); - tolua_function(tolua_S,"delete",tolua_AllToLua_cPlugin_delete00); - tolua_function(tolua_S,"OnDisable",tolua_AllToLua_cPlugin_OnDisable00); - tolua_function(tolua_S,"Initialize",tolua_AllToLua_cPlugin_Initialize00); - tolua_function(tolua_S,"Tick",tolua_AllToLua_cPlugin_Tick00); - tolua_function(tolua_S,"OnCollectItem",tolua_AllToLua_cPlugin_OnCollectItem00); - tolua_function(tolua_S,"OnDisconnect",tolua_AllToLua_cPlugin_OnDisconnect00); - tolua_function(tolua_S,"OnBlockPlace",tolua_AllToLua_cPlugin_OnBlockPlace00); - tolua_function(tolua_S,"OnBlockDig",tolua_AllToLua_cPlugin_OnBlockDig00); - tolua_function(tolua_S,"OnChat",tolua_AllToLua_cPlugin_OnChat00); - tolua_function(tolua_S,"OnLogin",tolua_AllToLua_cPlugin_OnLogin00); - tolua_function(tolua_S,"OnPlayerSpawn",tolua_AllToLua_cPlugin_OnPlayerSpawn00); - tolua_function(tolua_S,"OnPlayerJoin",tolua_AllToLua_cPlugin_OnPlayerJoin00); - tolua_function(tolua_S,"OnPlayerMove",tolua_AllToLua_cPlugin_OnPlayerMove00); - tolua_function(tolua_S,"OnTakeDamage",tolua_AllToLua_cPlugin_OnTakeDamage00); - tolua_function(tolua_S,"OnKilled",tolua_AllToLua_cPlugin_OnKilled00); - tolua_function(tolua_S,"OnChunkGenerated",tolua_AllToLua_cPlugin_OnChunkGenerated00); - tolua_function(tolua_S,"OnChunkGenerating",tolua_AllToLua_cPlugin_OnChunkGenerating00); - tolua_function(tolua_S,"OnPreCrafting",tolua_AllToLua_cPlugin_OnPreCrafting00); - tolua_function(tolua_S,"OnCraftingNoRecipe",tolua_AllToLua_cPlugin_OnCraftingNoRecipe00); - tolua_function(tolua_S,"OnPostCrafting",tolua_AllToLua_cPlugin_OnPostCrafting00); - tolua_function(tolua_S,"OnBlockToPickup",tolua_AllToLua_cPlugin_OnBlockToPickup00); - tolua_function(tolua_S,"GetName",tolua_AllToLua_cPlugin_GetName00); - tolua_function(tolua_S,"SetName",tolua_AllToLua_cPlugin_SetName00); - tolua_function(tolua_S,"GetVersion",tolua_AllToLua_cPlugin_GetVersion00); - tolua_function(tolua_S,"SetVersion",tolua_AllToLua_cPlugin_SetVersion00); - tolua_cclass(tolua_S,"CommandStruct","cPlugin::CommandStruct","",NULL); - tolua_beginmodule(tolua_S,"CommandStruct"); - tolua_variable(tolua_S,"Command",tolua_get_cPlugin__CommandStruct_Command,tolua_set_cPlugin__CommandStruct_Command); - tolua_variable(tolua_S,"Description",tolua_get_cPlugin__CommandStruct_Description,tolua_set_cPlugin__CommandStruct_Description); - tolua_variable(tolua_S,"Permission",tolua_get_cPlugin__CommandStruct_Permission,tolua_set_cPlugin__CommandStruct_Permission); - tolua_endmodule(tolua_S); - tolua_function(tolua_S,"AddCommand",tolua_AllToLua_cPlugin_AddCommand00); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"Lua__cPlugin","Lua__cPlugin","cPlugin",tolua_collect_Lua__cPlugin); - #else - tolua_cclass(tolua_S,"Lua__cPlugin","Lua__cPlugin","cPlugin",NULL); - #endif - tolua_beginmodule(tolua_S,"Lua__cPlugin"); - tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPlugin_tolua__set_instance00); - tolua_function(tolua_S,"cPlugin__OnDisable",tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisable00); - tolua_function(tolua_S,"cPlugin__Tick",tolua_AllToLua_Lua__cPlugin_cPlugin__Tick00); - tolua_function(tolua_S,"cPlugin__OnCollectItem",tolua_AllToLua_Lua__cPlugin_cPlugin__OnCollectItem00); - tolua_function(tolua_S,"cPlugin__OnDisconnect",tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisconnect00); - tolua_function(tolua_S,"cPlugin__OnBlockPlace",tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockPlace00); - tolua_function(tolua_S,"cPlugin__OnBlockDig",tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockDig00); - tolua_function(tolua_S,"cPlugin__OnChat",tolua_AllToLua_Lua__cPlugin_cPlugin__OnChat00); - tolua_function(tolua_S,"cPlugin__OnLogin",tolua_AllToLua_Lua__cPlugin_cPlugin__OnLogin00); - tolua_function(tolua_S,"cPlugin__OnPlayerSpawn",tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerSpawn00); - tolua_function(tolua_S,"cPlugin__OnPlayerJoin",tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerJoin00); - tolua_function(tolua_S,"cPlugin__OnPlayerMove",tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerMove00); - tolua_function(tolua_S,"cPlugin__OnTakeDamage",tolua_AllToLua_Lua__cPlugin_cPlugin__OnTakeDamage00); - tolua_function(tolua_S,"cPlugin__OnKilled",tolua_AllToLua_Lua__cPlugin_cPlugin__OnKilled00); - tolua_function(tolua_S,"cPlugin__OnChunkGenerated",tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerated00); - tolua_function(tolua_S,"cPlugin__OnChunkGenerating",tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerating00); - tolua_function(tolua_S,"cPlugin__OnPreCrafting",tolua_AllToLua_Lua__cPlugin_cPlugin__OnPreCrafting00); - tolua_function(tolua_S,"cPlugin__OnCraftingNoRecipe",tolua_AllToLua_Lua__cPlugin_cPlugin__OnCraftingNoRecipe00); - tolua_function(tolua_S,"cPlugin__OnPostCrafting",tolua_AllToLua_Lua__cPlugin_cPlugin__OnPostCrafting00); - tolua_function(tolua_S,"cPlugin__OnBlockToPickup",tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockToPickup00); - tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cPlugin_new00); - tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cPlugin_new00_local); - tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cPlugin_new00_local); - tolua_function(tolua_S,"delete",tolua_AllToLua_Lua__cPlugin_delete00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cPlugin_NewLua","cPlugin_NewLua","cPlugin",NULL); - tolua_beginmodule(tolua_S,"cPlugin_NewLua"); - tolua_function(tolua_S,"OnDisable",tolua_AllToLua_cPlugin_NewLua_OnDisable00); - tolua_function(tolua_S,"Initialize",tolua_AllToLua_cPlugin_NewLua_Initialize00); - tolua_function(tolua_S,"Tick",tolua_AllToLua_cPlugin_NewLua_Tick00); - tolua_function(tolua_S,"CreateWebPlugin",tolua_AllToLua_cPlugin_NewLua_CreateWebPlugin00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"Lua__cPlugin_NewLua","Lua__cPlugin_NewLua","cPlugin_NewLua",NULL); - tolua_beginmodule(tolua_S,"Lua__cPlugin_NewLua"); - tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPlugin_NewLua_tolua__set_instance00); - tolua_function(tolua_S,"cPlugin_NewLua__OnDisable",tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__OnDisable00); - tolua_function(tolua_S,"cPlugin_NewLua__Initialize",tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Initialize00); - tolua_function(tolua_S,"cPlugin_NewLua__Tick",tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Tick00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cPlugin_Lua","cPlugin_Lua","",NULL); - tolua_beginmodule(tolua_S,"cPlugin_Lua"); - tolua_function(tolua_S,"GetFileName",tolua_AllToLua_cPlugin_Lua_GetFileName00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cServer","cServer","",NULL); - tolua_beginmodule(tolua_S,"cServer"); - tolua_function(tolua_S,"GetServer",tolua_AllToLua_cServer_GetServer00); - tolua_function(tolua_S,"ServerCommand",tolua_AllToLua_cServer_ServerCommand00); - tolua_function(tolua_S,"SendMessage",tolua_AllToLua_cServer_SendMessage00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cWorld","cWorld","",NULL); - tolua_beginmodule(tolua_S,"cWorld"); - tolua_function(tolua_S,"GetTime",tolua_AllToLua_cWorld_GetTime00); - tolua_function(tolua_S,"GetGameMode",tolua_AllToLua_cWorld_GetGameMode00); - tolua_function(tolua_S,"SetWorldTime",tolua_AllToLua_cWorld_SetWorldTime00); - tolua_function(tolua_S,"GetHeight",tolua_AllToLua_cWorld_GetHeight00); - tolua_function(tolua_S,"UnloadUnusedChunks",tolua_AllToLua_cWorld_UnloadUnusedChunks00); - tolua_function(tolua_S,"GetMaxPlayers",tolua_AllToLua_cWorld_GetMaxPlayers00); - tolua_function(tolua_S,"SetMaxPlayers",tolua_AllToLua_cWorld_SetMaxPlayers00); - tolua_function(tolua_S,"GetNumPlayers",tolua_AllToLua_cWorld_GetNumPlayers00); - tolua_function(tolua_S,"GetPlayer",tolua_AllToLua_cWorld_GetPlayer00); - tolua_function(tolua_S,"UpdateSign",tolua_AllToLua_cWorld_UpdateSign00); - tolua_function(tolua_S,"RegenerateChunk",tolua_AllToLua_cWorld_RegenerateChunk00); - tolua_function(tolua_S,"GenerateChunk",tolua_AllToLua_cWorld_GenerateChunk00); - tolua_function(tolua_S,"SetBlock",tolua_AllToLua_cWorld_SetBlock00); - tolua_function(tolua_S,"FastSetBlock",tolua_AllToLua_cWorld_FastSetBlock00); - tolua_function(tolua_S,"GetBlock",tolua_AllToLua_cWorld_GetBlock00); - tolua_function(tolua_S,"GetBlock",tolua_AllToLua_cWorld_GetBlock01); - tolua_function(tolua_S,"GetBlockMeta",tolua_AllToLua_cWorld_GetBlockMeta00); - tolua_function(tolua_S,"GetBlockMeta",tolua_AllToLua_cWorld_GetBlockMeta01); - tolua_function(tolua_S,"SetBlockMeta",tolua_AllToLua_cWorld_SetBlockMeta00); - tolua_function(tolua_S,"SetBlockMeta",tolua_AllToLua_cWorld_SetBlockMeta01); - tolua_function(tolua_S,"GetBlockSkyLight",tolua_AllToLua_cWorld_GetBlockSkyLight00); - tolua_function(tolua_S,"GetBlockTypeMeta",tolua_AllToLua_cWorld_GetBlockTypeMeta00); - tolua_function(tolua_S,"DigBlock",tolua_AllToLua_cWorld_DigBlock00); - tolua_function(tolua_S,"SendBlockTo",tolua_AllToLua_cWorld_SendBlockTo00); - tolua_function(tolua_S,"GetSpawnX",tolua_AllToLua_cWorld_GetSpawnX00); - tolua_function(tolua_S,"GetSpawnY",tolua_AllToLua_cWorld_GetSpawnY00); - tolua_function(tolua_S,"GetSpawnZ",tolua_AllToLua_cWorld_GetSpawnZ00); - tolua_function(tolua_S,"GetBlockEntity",tolua_AllToLua_cWorld_GetBlockEntity00); - tolua_function(tolua_S,"GrowTree",tolua_AllToLua_cWorld_GrowTree00); - tolua_function(tolua_S,"GrowTreeFromSapling",tolua_AllToLua_cWorld_GrowTreeFromSapling00); - tolua_function(tolua_S,"GrowTreeByBiome",tolua_AllToLua_cWorld_GrowTreeByBiome00); - tolua_function(tolua_S,"GrowPlant",tolua_AllToLua_cWorld_GrowPlant00); - tolua_function(tolua_S,"GrowMelonPumpkin",tolua_AllToLua_cWorld_GrowMelonPumpkin00); - tolua_function(tolua_S,"GetBiomeAt",tolua_AllToLua_cWorld_GetBiomeAt00); - tolua_function(tolua_S,"GetName",tolua_AllToLua_cWorld_GetName00); - tolua_function(tolua_S,"SaveAllChunks",tolua_AllToLua_cWorld_SaveAllChunks00); - tolua_function(tolua_S,"GetNumChunks",tolua_AllToLua_cWorld_GetNumChunks00); - tolua_function(tolua_S,"GetGeneratorQueueLength",tolua_AllToLua_cWorld_GetGeneratorQueueLength00); - tolua_function(tolua_S,"GetLightingQueueLength",tolua_AllToLua_cWorld_GetLightingQueueLength00); - tolua_function(tolua_S,"GetStorageLoadQueueLength",tolua_AllToLua_cWorld_GetStorageLoadQueueLength00); - tolua_function(tolua_S,"GetStorageSaveQueueLength",tolua_AllToLua_cWorld_GetStorageSaveQueueLength00); - tolua_function(tolua_S,"CastThunderbolt",tolua_AllToLua_cWorld_CastThunderbolt00); - tolua_function(tolua_S,"SetWeather",tolua_AllToLua_cWorld_SetWeather00); - tolua_function(tolua_S,"ChangeWeather",tolua_AllToLua_cWorld_ChangeWeather00); - tolua_function(tolua_S,"GetWeather",tolua_AllToLua_cWorld_GetWeather00); - tolua_function(tolua_S,"SetNextBlockTick",tolua_AllToLua_cWorld_SetNextBlockTick00); - tolua_function(tolua_S,"GetMaxSugarcaneHeight",tolua_AllToLua_cWorld_GetMaxSugarcaneHeight00); - tolua_function(tolua_S,"GetMaxCactusHeight",tolua_AllToLua_cWorld_GetMaxCactusHeight00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cInventory","cInventory","",NULL); - tolua_beginmodule(tolua_S,"cInventory"); - tolua_function(tolua_S,"Clear",tolua_AllToLua_cInventory_Clear00); - tolua_function(tolua_S,"AddItem",tolua_AllToLua_cInventory_AddItem00); - tolua_function(tolua_S,"RemoveItem",tolua_AllToLua_cInventory_RemoveItem00); - tolua_function(tolua_S,"GetSlot",tolua_AllToLua_cInventory_GetSlot00); - tolua_function(tolua_S,"GetFromHotBar",tolua_AllToLua_cInventory_GetFromHotBar00); - tolua_function(tolua_S,"GetEquippedItem",tolua_AllToLua_cInventory_GetEquippedItem00); - tolua_function(tolua_S,"SetEquippedSlot",tolua_AllToLua_cInventory_SetEquippedSlot00); - tolua_function(tolua_S,"GetEquippedSlot",tolua_AllToLua_cInventory_GetEquippedSlot00); - tolua_function(tolua_S,"SendSlot",tolua_AllToLua_cInventory_SendSlot00); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"cItem","cItem","",tolua_collect_cItem); - #else - tolua_cclass(tolua_S,"cItem","cItem","",NULL); - #endif - tolua_beginmodule(tolua_S,"cItem"); - tolua_function(tolua_S,"new",tolua_AllToLua_cItem_new00); - tolua_function(tolua_S,"new_local",tolua_AllToLua_cItem_new00_local); - tolua_function(tolua_S,".call",tolua_AllToLua_cItem_new00_local); - tolua_function(tolua_S,"Empty",tolua_AllToLua_cItem_Empty00); - tolua_function(tolua_S,"Clear",tolua_AllToLua_cItem_Clear00); - tolua_function(tolua_S,"IsEmpty",tolua_AllToLua_cItem_IsEmpty00); - tolua_function(tolua_S,"Equals",tolua_AllToLua_cItem_Equals00); - tolua_function(tolua_S,"GetMaxDuration",tolua_AllToLua_cItem_GetMaxDuration00); - tolua_function(tolua_S,"DamageItem",tolua_AllToLua_cItem_DamageItem00); - tolua_function(tolua_S,"HasDuration",tolua_AllToLua_cItem_HasDuration00); - tolua_function(tolua_S,"GetJson",tolua_AllToLua_cItem_GetJson00); - tolua_function(tolua_S,"FromJson",tolua_AllToLua_cItem_FromJson00); - tolua_function(tolua_S,"IsEnchantable",tolua_AllToLua_cItem_IsEnchantable00); - tolua_variable(tolua_S,"m_ItemID",tolua_get_cItem_m_ItemID,tolua_set_cItem_m_ItemID); - tolua_variable(tolua_S,"m_ItemCount",tolua_get_cItem_m_ItemCount,tolua_set_cItem_m_ItemCount); - tolua_variable(tolua_S,"m_ItemHealth",tolua_get_cItem_m_ItemHealth,tolua_set_cItem_m_ItemHealth); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"HTTPFormData","HTTPFormData","",NULL); - tolua_beginmodule(tolua_S,"HTTPFormData"); - tolua_variable(tolua_S,"Name",tolua_get_HTTPFormData_Name,tolua_set_HTTPFormData_Name); - tolua_variable(tolua_S,"Value",tolua_get_HTTPFormData_Value,tolua_set_HTTPFormData_Value); - tolua_variable(tolua_S,"Type",tolua_get_HTTPFormData_Type,tolua_set_HTTPFormData_Type); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"HTTPRequest","HTTPRequest","",NULL); - tolua_beginmodule(tolua_S,"HTTPRequest"); - tolua_variable(tolua_S,"Method",tolua_get_HTTPRequest_Method,tolua_set_HTTPRequest_Method); - tolua_variable(tolua_S,"Path",tolua_get_HTTPRequest_Path,tolua_set_HTTPRequest_Path); - tolua_variable(tolua_S,"Username",tolua_get_HTTPRequest_Username,tolua_set_HTTPRequest_Username); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"cWebPlugin","cWebPlugin","",tolua_collect_cWebPlugin); - #else - tolua_cclass(tolua_S,"cWebPlugin","cWebPlugin","",NULL); - #endif - tolua_beginmodule(tolua_S,"cWebPlugin"); - tolua_function(tolua_S,"delete",tolua_AllToLua_cWebPlugin_delete00); - tolua_function(tolua_S,"SetName",tolua_AllToLua_cWebPlugin_SetName00); - tolua_function(tolua_S,"GetName",tolua_AllToLua_cWebPlugin_GetName00); - tolua_function(tolua_S,"HandleRequest",tolua_AllToLua_cWebPlugin_HandleRequest00); - tolua_function(tolua_S,"Initialize",tolua_AllToLua_cWebPlugin_Initialize00); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"Lua__cWebPlugin","Lua__cWebPlugin","cWebPlugin",tolua_collect_Lua__cWebPlugin); - #else - tolua_cclass(tolua_S,"Lua__cWebPlugin","Lua__cWebPlugin","cWebPlugin",NULL); - #endif - tolua_beginmodule(tolua_S,"Lua__cWebPlugin"); - tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cWebPlugin_tolua__set_instance00); - tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cWebPlugin_new00); - tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cWebPlugin_new00_local); - tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cWebPlugin_new00_local); - tolua_function(tolua_S,"delete",tolua_AllToLua_Lua__cWebPlugin_delete00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cWebPlugin_Lua","cWebPlugin_Lua","cWebPlugin",NULL); - tolua_beginmodule(tolua_S,"cWebPlugin_Lua"); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"cPickup","cPickup","cEntity",tolua_collect_cPickup); - #else - tolua_cclass(tolua_S,"cPickup","cPickup","cEntity",NULL); - #endif - tolua_beginmodule(tolua_S,"cPickup"); - tolua_function(tolua_S,"new",tolua_AllToLua_cPickup_new00); - tolua_function(tolua_S,"new_local",tolua_AllToLua_cPickup_new00_local); - tolua_function(tolua_S,".call",tolua_AllToLua_cPickup_new00_local); - tolua_function(tolua_S,"new",tolua_AllToLua_cPickup_new01); - tolua_function(tolua_S,"new_local",tolua_AllToLua_cPickup_new01_local); - tolua_function(tolua_S,".call",tolua_AllToLua_cPickup_new01_local); - tolua_function(tolua_S,"delete",tolua_AllToLua_cPickup_delete00); - tolua_function(tolua_S,"GetItem",tolua_AllToLua_cPickup_GetItem00); - tolua_function(tolua_S,"CollectedBy",tolua_AllToLua_cPickup_CollectedBy00); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"Lua__cPickup","Lua__cPickup","cPickup",tolua_collect_Lua__cPickup); - #else - tolua_cclass(tolua_S,"Lua__cPickup","Lua__cPickup","cPickup",NULL); - #endif - tolua_beginmodule(tolua_S,"Lua__cPickup"); - tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPickup_tolua__set_instance00); - tolua_function(tolua_S,"cPickup__CollectedBy",tolua_AllToLua_Lua__cPickup_cPickup__CollectedBy00); - tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cPickup_new00); - tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cPickup_new00_local); - tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cPickup_new00_local); - tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cPickup_new01); - tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cPickup_new01_local); - tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cPickup_new01_local); - tolua_function(tolua_S,"delete",tolua_AllToLua_Lua__cPickup_delete00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cRoot","cRoot","",NULL); - tolua_beginmodule(tolua_S,"cRoot"); - tolua_function(tolua_S,"Get",tolua_AllToLua_cRoot_Get00); - tolua_function(tolua_S,"GetServer",tolua_AllToLua_cRoot_GetServer00); - tolua_function(tolua_S,"GetDefaultWorld",tolua_AllToLua_cRoot_GetDefaultWorld00); - tolua_function(tolua_S,"GetWorld",tolua_AllToLua_cRoot_GetWorld00); - tolua_function(tolua_S,"GetGroupManager",tolua_AllToLua_cRoot_GetGroupManager00); - tolua_function(tolua_S,"GetCraftingRecipes",tolua_AllToLua_cRoot_GetCraftingRecipes00); - tolua_function(tolua_S,"GetFurnaceRecipe",tolua_AllToLua_cRoot_GetFurnaceRecipe00); - tolua_function(tolua_S,"GetWebAdmin",tolua_AllToLua_cRoot_GetWebAdmin00); - tolua_function(tolua_S,"GetPluginManager",tolua_AllToLua_cRoot_GetPluginManager00); - tolua_function(tolua_S,"ServerCommand",tolua_AllToLua_cRoot_ServerCommand00); - tolua_function(tolua_S,"GetTotalChunkCount",tolua_AllToLua_cRoot_GetTotalChunkCount00); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"cTCPLink","cTCPLink","",tolua_collect_cTCPLink); - #else - tolua_cclass(tolua_S,"cTCPLink","cTCPLink","",NULL); - #endif - tolua_beginmodule(tolua_S,"cTCPLink"); - tolua_function(tolua_S,"delete",tolua_AllToLua_cTCPLink_delete00); - tolua_function(tolua_S,"Connect",tolua_AllToLua_cTCPLink_Connect00); - tolua_function(tolua_S,"Send",tolua_AllToLua_cTCPLink_Send00); - tolua_function(tolua_S,"SendMessage",tolua_AllToLua_cTCPLink_SendMessage00); - tolua_function(tolua_S,"CloseSocket",tolua_AllToLua_cTCPLink_CloseSocket00); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"Lua__cTCPLink","Lua__cTCPLink","cTCPLink",tolua_collect_Lua__cTCPLink); - #else - tolua_cclass(tolua_S,"Lua__cTCPLink","Lua__cTCPLink","cTCPLink",NULL); - #endif - tolua_beginmodule(tolua_S,"Lua__cTCPLink"); - tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cTCPLink_tolua__set_instance00); - tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cTCPLink_new00); - tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cTCPLink_new00_local); - tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cTCPLink_new00_local); - tolua_function(tolua_S,"delete",tolua_AllToLua_Lua__cTCPLink_delete00); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"Vector3f","Vector3f","",tolua_collect_Vector3f); - #else - tolua_cclass(tolua_S,"Vector3f","Vector3f","",NULL); - #endif - tolua_beginmodule(tolua_S,"Vector3f"); - tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new00); - tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new00_local); - tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new00_local); - tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new01); - tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new01_local); - tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new01_local); - tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new02); - tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new02_local); - tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new02_local); - tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new03); - tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new03_local); - tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new03_local); - tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new04); - tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new04_local); - tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new04_local); - tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new05); - tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new05_local); - tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new05_local); - tolua_function(tolua_S,"Set",tolua_AllToLua_Vector3f_Set00); - tolua_function(tolua_S,"Normalize",tolua_AllToLua_Vector3f_Normalize00); - tolua_function(tolua_S,"NormalizeCopy",tolua_AllToLua_Vector3f_NormalizeCopy00); - tolua_function(tolua_S,"NormalizeCopy",tolua_AllToLua_Vector3f_NormalizeCopy01); - tolua_function(tolua_S,"Length",tolua_AllToLua_Vector3f_Length00); - tolua_function(tolua_S,"SqrLength",tolua_AllToLua_Vector3f_SqrLength00); - tolua_function(tolua_S,"Dot",tolua_AllToLua_Vector3f_Dot00); - tolua_function(tolua_S,"Cross",tolua_AllToLua_Vector3f_Cross00); - tolua_function(tolua_S,"Equals",tolua_AllToLua_Vector3f_Equals00); - tolua_function(tolua_S,".add",tolua_AllToLua_Vector3f__add00); - tolua_function(tolua_S,".add",tolua_AllToLua_Vector3f__add01); - tolua_function(tolua_S,".sub",tolua_AllToLua_Vector3f__sub00); - tolua_function(tolua_S,".sub",tolua_AllToLua_Vector3f__sub01); - tolua_function(tolua_S,".mul",tolua_AllToLua_Vector3f__mul00); - tolua_function(tolua_S,".mul",tolua_AllToLua_Vector3f__mul01); - tolua_variable(tolua_S,"x",tolua_get_Vector3f_x,tolua_set_Vector3f_x); - tolua_variable(tolua_S,"y",tolua_get_Vector3f_y,tolua_set_Vector3f_y); - tolua_variable(tolua_S,"z",tolua_get_Vector3f_z,tolua_set_Vector3f_z); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"Vector3d","Vector3d","",tolua_collect_Vector3d); - #else - tolua_cclass(tolua_S,"Vector3d","Vector3d","",NULL); - #endif - tolua_beginmodule(tolua_S,"Vector3d"); - tolua_function(tolua_S,"new",tolua_AllToLua_Vector3d_new00); - tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3d_new00_local); - tolua_function(tolua_S,".call",tolua_AllToLua_Vector3d_new00_local); - tolua_function(tolua_S,"new",tolua_AllToLua_Vector3d_new01); - tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3d_new01_local); - tolua_function(tolua_S,".call",tolua_AllToLua_Vector3d_new01_local); - tolua_function(tolua_S,"new",tolua_AllToLua_Vector3d_new02); - tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3d_new02_local); - tolua_function(tolua_S,".call",tolua_AllToLua_Vector3d_new02_local); - tolua_function(tolua_S,"new",tolua_AllToLua_Vector3d_new03); - tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3d_new03_local); - tolua_function(tolua_S,".call",tolua_AllToLua_Vector3d_new03_local); - tolua_function(tolua_S,"Set",tolua_AllToLua_Vector3d_Set00); - tolua_function(tolua_S,"Normalize",tolua_AllToLua_Vector3d_Normalize00); - tolua_function(tolua_S,"NormalizeCopy",tolua_AllToLua_Vector3d_NormalizeCopy00); - tolua_function(tolua_S,"NormalizeCopy",tolua_AllToLua_Vector3d_NormalizeCopy01); - tolua_function(tolua_S,"Length",tolua_AllToLua_Vector3d_Length00); - tolua_function(tolua_S,"SqrLength",tolua_AllToLua_Vector3d_SqrLength00); - tolua_function(tolua_S,"Dot",tolua_AllToLua_Vector3d_Dot00); - tolua_function(tolua_S,"Cross",tolua_AllToLua_Vector3d_Cross00); - tolua_function(tolua_S,"Equals",tolua_AllToLua_Vector3d_Equals00); - tolua_function(tolua_S,".add",tolua_AllToLua_Vector3d__add00); - tolua_function(tolua_S,".add",tolua_AllToLua_Vector3d__add01); - tolua_function(tolua_S,".sub",tolua_AllToLua_Vector3d__sub00); - tolua_function(tolua_S,".sub",tolua_AllToLua_Vector3d__sub01); - tolua_function(tolua_S,".mul",tolua_AllToLua_Vector3d__mul00); - tolua_function(tolua_S,".mul",tolua_AllToLua_Vector3d__mul01); - tolua_variable(tolua_S,"x",tolua_get_Vector3d_x,tolua_set_Vector3d_x); - tolua_variable(tolua_S,"y",tolua_get_Vector3d_y,tolua_set_Vector3d_y); - tolua_variable(tolua_S,"z",tolua_get_Vector3d_z,tolua_set_Vector3d_z); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"Vector3i","Vector3i","",tolua_collect_Vector3i); - #else - tolua_cclass(tolua_S,"Vector3i","Vector3i","",NULL); - #endif - tolua_beginmodule(tolua_S,"Vector3i"); - tolua_function(tolua_S,"new",tolua_AllToLua_Vector3i_new00); - tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3i_new00_local); - tolua_function(tolua_S,".call",tolua_AllToLua_Vector3i_new00_local); - tolua_function(tolua_S,"new",tolua_AllToLua_Vector3i_new01); - tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3i_new01_local); - tolua_function(tolua_S,".call",tolua_AllToLua_Vector3i_new01_local); - tolua_function(tolua_S,"new",tolua_AllToLua_Vector3i_new02); - tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3i_new02_local); - tolua_function(tolua_S,".call",tolua_AllToLua_Vector3i_new02_local); - tolua_function(tolua_S,"Set",tolua_AllToLua_Vector3i_Set00); - tolua_function(tolua_S,"Length",tolua_AllToLua_Vector3i_Length00); - tolua_function(tolua_S,"SqrLength",tolua_AllToLua_Vector3i_SqrLength00); - tolua_function(tolua_S,"Equals",tolua_AllToLua_Vector3i_Equals00); - tolua_function(tolua_S,"Equals",tolua_AllToLua_Vector3i_Equals01); - tolua_variable(tolua_S,"x",tolua_get_Vector3i_x,tolua_set_Vector3i_x); - tolua_variable(tolua_S,"y",tolua_get_Vector3i_y,tolua_set_Vector3i_y); - tolua_variable(tolua_S,"z",tolua_get_Vector3i_z,tolua_set_Vector3i_z); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"cCuboid","cCuboid","",tolua_collect_cCuboid); - #else - tolua_cclass(tolua_S,"cCuboid","cCuboid","",NULL); - #endif - tolua_beginmodule(tolua_S,"cCuboid"); - tolua_function(tolua_S,"new",tolua_AllToLua_cCuboid_new00); - tolua_function(tolua_S,"new_local",tolua_AllToLua_cCuboid_new00_local); - tolua_function(tolua_S,".call",tolua_AllToLua_cCuboid_new00_local); - tolua_function(tolua_S,"new",tolua_AllToLua_cCuboid_new01); - tolua_function(tolua_S,"new_local",tolua_AllToLua_cCuboid_new01_local); - tolua_function(tolua_S,".call",tolua_AllToLua_cCuboid_new01_local); - tolua_function(tolua_S,"new",tolua_AllToLua_cCuboid_new02); - tolua_function(tolua_S,"new_local",tolua_AllToLua_cCuboid_new02_local); - tolua_function(tolua_S,".call",tolua_AllToLua_cCuboid_new02_local); - tolua_variable(tolua_S,"p1",tolua_get_cCuboid_p1,tolua_set_cCuboid_p1); - tolua_variable(tolua_S,"p2",tolua_get_cCuboid_p2,tolua_set_cCuboid_p2); - tolua_function(tolua_S,"Sort",tolua_AllToLua_cCuboid_Sort00); - tolua_function(tolua_S,"IsInside",tolua_AllToLua_cCuboid_IsInside00); - tolua_function(tolua_S,"IsInside",tolua_AllToLua_cCuboid_IsInside01); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"cMCLogger","cMCLogger","",tolua_collect_cMCLogger); - #else - tolua_cclass(tolua_S,"cMCLogger","cMCLogger","",NULL); - #endif - tolua_beginmodule(tolua_S,"cMCLogger"); - tolua_function(tolua_S,"new",tolua_AllToLua_cMCLogger_new00); - tolua_function(tolua_S,"new_local",tolua_AllToLua_cMCLogger_new00_local); - tolua_function(tolua_S,".call",tolua_AllToLua_cMCLogger_new00_local); - tolua_function(tolua_S,"delete",tolua_AllToLua_cMCLogger_delete00); - tolua_function(tolua_S,"LogSimple",tolua_AllToLua_cMCLogger_LogSimple00); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"cTracer","cTracer","",tolua_collect_cTracer); - #else - tolua_cclass(tolua_S,"cTracer","cTracer","",NULL); - #endif - tolua_beginmodule(tolua_S,"cTracer"); - tolua_function(tolua_S,"new",tolua_AllToLua_cTracer_new00); - tolua_function(tolua_S,"new_local",tolua_AllToLua_cTracer_new00_local); - tolua_function(tolua_S,".call",tolua_AllToLua_cTracer_new00_local); - tolua_function(tolua_S,"delete",tolua_AllToLua_cTracer_delete00); - tolua_function(tolua_S,"Trace",tolua_AllToLua_cTracer_Trace00); - tolua_function(tolua_S,"SetValues",tolua_AllToLua_cTracer_SetValues00); - tolua_variable(tolua_S,"BlockHitPosition",tolua_get_cTracer_BlockHitPosition,tolua_set_cTracer_BlockHitPosition); - tolua_variable(tolua_S,"HitNormal",tolua_get_cTracer_HitNormal,tolua_set_cTracer_HitNormal); - tolua_variable(tolua_S,"RealHit",tolua_get_cTracer_RealHit,tolua_set_cTracer_RealHit); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cGroup","cGroup","",NULL); - tolua_beginmodule(tolua_S,"cGroup"); - tolua_function(tolua_S,"SetName",tolua_AllToLua_cGroup_SetName00); - tolua_function(tolua_S,"GetName",tolua_AllToLua_cGroup_GetName00); - tolua_function(tolua_S,"SetColor",tolua_AllToLua_cGroup_SetColor00); - tolua_function(tolua_S,"AddCommand",tolua_AllToLua_cGroup_AddCommand00); - tolua_function(tolua_S,"AddPermission",tolua_AllToLua_cGroup_AddPermission00); - tolua_function(tolua_S,"InheritFrom",tolua_AllToLua_cGroup_InheritFrom00); - tolua_function(tolua_S,"HasCommand",tolua_AllToLua_cGroup_HasCommand00); - tolua_function(tolua_S,"GetColor",tolua_AllToLua_cGroup_GetColor00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cPacket_Login","cPacket_Login","cPacket",NULL); - tolua_beginmodule(tolua_S,"cPacket_Login"); - tolua_variable(tolua_S,"m_ProtocolVersion",tolua_get_cPacket_Login_m_ProtocolVersion,tolua_set_cPacket_Login_m_ProtocolVersion); - tolua_variable(tolua_S,"m_Username",tolua_get_cPacket_Login_m_Username,tolua_set_cPacket_Login_m_Username); - tolua_variable(tolua_S,"m_LevelType",tolua_get_cPacket_Login_m_LevelType,tolua_set_cPacket_Login_m_LevelType); - tolua_variable(tolua_S,"m_ServerMode",tolua_get_cPacket_Login_m_ServerMode,tolua_set_cPacket_Login_m_ServerMode); - tolua_variable(tolua_S,"m_Difficulty",tolua_get_cPacket_Login_m_Difficulty,tolua_set_cPacket_Login_m_Difficulty); - tolua_variable(tolua_S,"m_WorldHeight",tolua_get_cPacket_Login_unsigned_m_WorldHeight,tolua_set_cPacket_Login_unsigned_m_WorldHeight); - tolua_variable(tolua_S,"m_MaxPlayers",tolua_get_cPacket_Login_unsigned_m_MaxPlayers,tolua_set_cPacket_Login_unsigned_m_MaxPlayers); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"cPacket_BlockDig","cPacket_BlockDig","cPacket",tolua_collect_cPacket_BlockDig); - #else - tolua_cclass(tolua_S,"cPacket_BlockDig","cPacket_BlockDig","cPacket",NULL); - #endif - tolua_beginmodule(tolua_S,"cPacket_BlockDig"); - tolua_function(tolua_S,"new",tolua_AllToLua_cPacket_BlockDig_new00); - tolua_function(tolua_S,"new_local",tolua_AllToLua_cPacket_BlockDig_new00_local); - tolua_function(tolua_S,".call",tolua_AllToLua_cPacket_BlockDig_new00_local); - tolua_function(tolua_S,"Clone",tolua_AllToLua_cPacket_BlockDig_Clone00); - tolua_variable(tolua_S,"m_Status",tolua_get_cPacket_BlockDig_m_Status,tolua_set_cPacket_BlockDig_m_Status); - tolua_variable(tolua_S,"m_PosX",tolua_get_cPacket_BlockDig_m_PosX,tolua_set_cPacket_BlockDig_m_PosX); - tolua_variable(tolua_S,"m_PosY",tolua_get_cPacket_BlockDig_m_PosY,tolua_set_cPacket_BlockDig_m_PosY); - tolua_variable(tolua_S,"m_PosZ",tolua_get_cPacket_BlockDig_m_PosZ,tolua_set_cPacket_BlockDig_m_PosZ); - tolua_variable(tolua_S,"m_Direction",tolua_get_cPacket_BlockDig_m_Direction,tolua_set_cPacket_BlockDig_m_Direction); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"Lua__cPacket_BlockDig","Lua__cPacket_BlockDig","cPacket_BlockDig",tolua_collect_Lua__cPacket_BlockDig); - #else - tolua_cclass(tolua_S,"Lua__cPacket_BlockDig","Lua__cPacket_BlockDig","cPacket_BlockDig",NULL); - #endif - tolua_beginmodule(tolua_S,"Lua__cPacket_BlockDig"); - tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPacket_BlockDig_tolua__set_instance00); - tolua_function(tolua_S,"cPacket_BlockDig__Clone",tolua_AllToLua_Lua__cPacket_BlockDig_cPacket_BlockDig__Clone00); - tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cPacket_BlockDig_new00); - tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cPacket_BlockDig_new00_local); - tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cPacket_BlockDig_new00_local); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cPacket_BlockPlace","cPacket_BlockPlace","cPacket",NULL); - tolua_beginmodule(tolua_S,"cPacket_BlockPlace"); - tolua_variable(tolua_S,"m_PosX",tolua_get_cPacket_BlockPlace_m_PosX,tolua_set_cPacket_BlockPlace_m_PosX); - tolua_variable(tolua_S,"m_PosY",tolua_get_cPacket_BlockPlace_unsigned_m_PosY,tolua_set_cPacket_BlockPlace_unsigned_m_PosY); - tolua_variable(tolua_S,"m_PosZ",tolua_get_cPacket_BlockPlace_m_PosZ,tolua_set_cPacket_BlockPlace_m_PosZ); - tolua_variable(tolua_S,"m_Direction",tolua_get_cPacket_BlockPlace_m_Direction,tolua_set_cPacket_BlockPlace_m_Direction); - tolua_variable(tolua_S,"m_ItemType",tolua_get_cPacket_BlockPlace_m_ItemType,tolua_set_cPacket_BlockPlace_m_ItemType); - tolua_variable(tolua_S,"m_Count",tolua_get_cPacket_BlockPlace_m_Count,tolua_set_cPacket_BlockPlace_m_Count); - tolua_variable(tolua_S,"m_Uses",tolua_get_cPacket_BlockPlace_m_Uses,tolua_set_cPacket_BlockPlace_m_Uses); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cLuaChunk","cLuaChunk","",NULL); - tolua_beginmodule(tolua_S,"cLuaChunk"); - tolua_function(tolua_S,"FillBlocks",tolua_AllToLua_cLuaChunk_FillBlocks00); - tolua_function(tolua_S,"SetBlock",tolua_AllToLua_cLuaChunk_SetBlock00); - tolua_function(tolua_S,"GetBlock",tolua_AllToLua_cLuaChunk_GetBlock00); - tolua_function(tolua_S,"GetBlockMeta",tolua_AllToLua_cLuaChunk_GetBlockMeta00); - tolua_function(tolua_S,"SetBiome",tolua_AllToLua_cLuaChunk_SetBiome00); - tolua_function(tolua_S,"GetBiome",tolua_AllToLua_cLuaChunk_GetBiome00); - tolua_function(tolua_S,"SetHeight",tolua_AllToLua_cLuaChunk_SetHeight00); - tolua_function(tolua_S,"GetHeight",tolua_AllToLua_cLuaChunk_GetHeight00); - tolua_function(tolua_S,"SetUseDefaultBiomes",tolua_AllToLua_cLuaChunk_SetUseDefaultBiomes00); - tolua_function(tolua_S,"IsUsingDefaultBiomes",tolua_AllToLua_cLuaChunk_IsUsingDefaultBiomes00); - tolua_function(tolua_S,"SetUseDefaultComposition",tolua_AllToLua_cLuaChunk_SetUseDefaultComposition00); - tolua_function(tolua_S,"IsUsingDefaultComposition",tolua_AllToLua_cLuaChunk_IsUsingDefaultComposition00); - tolua_function(tolua_S,"SetUseDefaultStructures",tolua_AllToLua_cLuaChunk_SetUseDefaultStructures00); - tolua_function(tolua_S,"IsUsingDefaultStructures",tolua_AllToLua_cLuaChunk_IsUsingDefaultStructures00); - tolua_function(tolua_S,"SetUseDefaultFinish",tolua_AllToLua_cLuaChunk_SetUseDefaultFinish00); - tolua_function(tolua_S,"IsUsingDefaultFinish",tolua_AllToLua_cLuaChunk_IsUsingDefaultFinish00); - tolua_endmodule(tolua_S); - #ifdef __cplusplus - tolua_cclass(tolua_S,"cCraftingGrid","cCraftingGrid","",tolua_collect_cCraftingGrid); - #else - tolua_cclass(tolua_S,"cCraftingGrid","cCraftingGrid","",NULL); - #endif - tolua_beginmodule(tolua_S,"cCraftingGrid"); - tolua_function(tolua_S,"new",tolua_AllToLua_cCraftingGrid_new00); - tolua_function(tolua_S,"new_local",tolua_AllToLua_cCraftingGrid_new00_local); - tolua_function(tolua_S,".call",tolua_AllToLua_cCraftingGrid_new00_local); - tolua_function(tolua_S,"GetWidth",tolua_AllToLua_cCraftingGrid_GetWidth00); - tolua_function(tolua_S,"GetHeight",tolua_AllToLua_cCraftingGrid_GetHeight00); - tolua_function(tolua_S,"GetItem",tolua_AllToLua_cCraftingGrid_GetItem00); - tolua_function(tolua_S,"SetItem",tolua_AllToLua_cCraftingGrid_SetItem00); - tolua_function(tolua_S,"SetItem",tolua_AllToLua_cCraftingGrid_SetItem01); - tolua_function(tolua_S,"Clear",tolua_AllToLua_cCraftingGrid_Clear00); - tolua_function(tolua_S,"ConsumeGrid",tolua_AllToLua_cCraftingGrid_ConsumeGrid00); - tolua_function(tolua_S,"Dump",tolua_AllToLua_cCraftingGrid_Dump00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cCraftingRecipe","cCraftingRecipe","",NULL); - tolua_beginmodule(tolua_S,"cCraftingRecipe"); - tolua_function(tolua_S,"Clear",tolua_AllToLua_cCraftingRecipe_Clear00); - tolua_function(tolua_S,"GetIngredientsWidth",tolua_AllToLua_cCraftingRecipe_GetIngredientsWidth00); - tolua_function(tolua_S,"GetIngredientsHeight",tolua_AllToLua_cCraftingRecipe_GetIngredientsHeight00); - tolua_function(tolua_S,"GetIngredient",tolua_AllToLua_cCraftingRecipe_GetIngredient00); - tolua_function(tolua_S,"GetResult",tolua_AllToLua_cCraftingRecipe_GetResult00); - tolua_function(tolua_S,"SetResult",tolua_AllToLua_cCraftingRecipe_SetResult00); - tolua_function(tolua_S,"SetResult",tolua_AllToLua_cCraftingRecipe_SetResult01); - tolua_function(tolua_S,"SetIngredient",tolua_AllToLua_cCraftingRecipe_SetIngredient00); - tolua_function(tolua_S,"SetIngredient",tolua_AllToLua_cCraftingRecipe_SetIngredient01); - tolua_function(tolua_S,"ConsumeIngredients",tolua_AllToLua_cCraftingRecipe_ConsumeIngredients00); - tolua_function(tolua_S,"Dump",tolua_AllToLua_cCraftingRecipe_Dump00); - tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cLuaItems","cLuaItems","",NULL); - tolua_beginmodule(tolua_S,"cLuaItems"); - tolua_function(tolua_S,"Get",tolua_AllToLua_cLuaItems_Get00); - tolua_function(tolua_S,"Set",tolua_AllToLua_cLuaItems_Set00); - tolua_function(tolua_S,"Add",tolua_AllToLua_cLuaItems_Add00); - tolua_function(tolua_S,"Delete",tolua_AllToLua_cLuaItems_Delete00); - tolua_function(tolua_S,"Clear",tolua_AllToLua_cLuaItems_Clear00); - tolua_function(tolua_S,"Size",tolua_AllToLua_cLuaItems_Size00); - tolua_function(tolua_S,"Add",tolua_AllToLua_cLuaItems_Add01); - tolua_function(tolua_S,"Set",tolua_AllToLua_cLuaItems_Set01); - tolua_endmodule(tolua_S); - tolua_endmodule(tolua_S); - return 1; -} - - -#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501 - TOLUA_API int luaopen_AllToLua (lua_State* tolua_S) { - return tolua_AllToLua_open(tolua_S); -}; -#endif - +/* +** Lua binding: AllToLua +** Generated automatically by tolua++-1.0.92 on Thu Jun 14 14:20:17 2012. +*/ + +#ifndef __cplusplus +#include "stdlib.h" +#endif +#include "string.h" + +#include "tolua++.h" + +/* Exported function */ +TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S); + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules +#include "tolua_base.h" +#include "cTorch.h" +#include "cStairs.h" +#include "cStep.h" +#include "cLadder.h" +#include "../iniFile/iniFile.h" +#include "BlockID.h" +#include "PacketID.h" +#include "Defines.h" +#include "LuaFunctions.h" +#include "cStringMap.h" +#include "cChatColor.h" +#include "cClientHandle.h" +#include "cEntity.h" +#include "cPawn.h" +#include "cPlayer.h" +#include "cPluginManager.h" +#include "cPlugin.h" +#include "cPlugin_NewLua.h" +#include "cPlugin_Lua.h" +#include "cServer.h" +#include "cWorld.h" +#include "cInventory.h" +#include "cItem.h" +#include "cWebAdmin.h" +#include "cWebPlugin.h" +#include "cWebPlugin_Lua.h" +#include "cPickup.h" +#include "cRoot.h" +#include "cTCPLink.h" +#include "Vector3f.h" +#include "Vector3d.h" +#include "Vector3i.h" +#include "Matrix4f.h" +#include "cCuboid.h" +#include "cMCLogger.h" +#include "cTracer.h" +#include "cGroup.h" +#include "packets/cPacket_Login.h" +#include "packets/cPacket_BlockDig.h" +#include "packets/cPacket_BlockPlace.h" +#include "cLuaChunk.h" +#include "CraftingRecipes.h" +#include "LuaItems.h" + +/* function to release collected object via destructor */ +#ifdef __cplusplus + +static int tolua_collect_cMCLogger (lua_State* tolua_S) +{ + cMCLogger* self = (cMCLogger*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cItem (lua_State* tolua_S) +{ + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_Vector3f (lua_State* tolua_S) +{ + Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cIniFile (lua_State* tolua_S) +{ + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cPickup (lua_State* tolua_S) +{ + cPickup* self = (cPickup*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cPacket_BlockDig (lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cTracer (lua_State* tolua_S) +{ + cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cPlugin (lua_State* tolua_S) +{ + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cCraftingGrid (lua_State* tolua_S) +{ + cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cCuboid (lua_State* tolua_S) +{ + cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cWebPlugin (lua_State* tolua_S) +{ + cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_Vector3i (lua_State* tolua_S) +{ + Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cEntity (lua_State* tolua_S) +{ + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cTCPLink (lua_State* tolua_S) +{ + cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_Vector3d (lua_State* tolua_S) +{ + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} +#endif + + +/* function to register type */ +static void tolua_reg_types (lua_State* tolua_S) +{ + tolua_usertype(tolua_S,"BLOCKTYPE"); + tolua_usertype(tolua_S,"TakeDamageInfo"); + tolua_usertype(tolua_S,"cLuaItems"); + tolua_usertype(tolua_S,"cLuaChunk"); + tolua_usertype(tolua_S,"cCraftingGrid"); + tolua_usertype(tolua_S,"cCraftingRecipe"); + tolua_usertype(tolua_S,"cPlugin"); + tolua_usertype(tolua_S,"cEntity"); + tolua_usertype(tolua_S,"NIBBLETYPE"); + tolua_usertype(tolua_S,"Lua__cPacket_BlockDig"); + tolua_usertype(tolua_S,"cTCPLink"); + tolua_usertype(tolua_S,"Lua__cTCPLink"); + tolua_usertype(tolua_S,"Json::Value"); + tolua_usertype(tolua_S,"cServer"); + tolua_usertype(tolua_S,"cRoot"); + tolua_usertype(tolua_S,"cMCLogger"); + tolua_usertype(tolua_S,"cGroup"); + tolua_usertype(tolua_S,"cTracer"); + tolua_usertype(tolua_S,"cPlugin::CommandStruct"); + tolua_usertype(tolua_S,"cPickup"); + tolua_usertype(tolua_S,"cItems"); + tolua_usertype(tolua_S,"cPacket_Login"); + tolua_usertype(tolua_S,"cClientHandle"); + tolua_usertype(tolua_S,"cStep"); + tolua_usertype(tolua_S,"cFurnaceRecipe"); + tolua_usertype(tolua_S,"cCuboid"); + tolua_usertype(tolua_S,"cChatColor"); + tolua_usertype(tolua_S,"Vector3i"); + tolua_usertype(tolua_S,"cPacket_PickupSpawn"); + tolua_usertype(tolua_S,"Lua__cWebPlugin"); + tolua_usertype(tolua_S,"Lua__cPawn"); + tolua_usertype(tolua_S,"cStairs"); + tolua_usertype(tolua_S,"cItem"); + tolua_usertype(tolua_S,"Vector3f"); + tolua_usertype(tolua_S,"cPlugin_Lua"); + tolua_usertype(tolua_S,"cWebPlugin_Lua"); + tolua_usertype(tolua_S,"Lua__cPlugin_NewLua"); + tolua_usertype(tolua_S,"cPacket"); + tolua_usertype(tolua_S,"cPacket_BlockDig"); + tolua_usertype(tolua_S,"cWebAdmin"); + tolua_usertype(tolua_S,"cCraftingRecipes"); + tolua_usertype(tolua_S,"cBlockEntity"); + tolua_usertype(tolua_S,"cGroupManager"); + tolua_usertype(tolua_S,"Lua__cPickup"); + tolua_usertype(tolua_S,"Lua__cPlugin"); + tolua_usertype(tolua_S,"cWebPlugin"); + tolua_usertype(tolua_S,"cPacket_BlockPlace"); + tolua_usertype(tolua_S,"cLadder"); + tolua_usertype(tolua_S,"cPluginManager"); + tolua_usertype(tolua_S,"HTTPFormData"); + tolua_usertype(tolua_S,"cIniFile"); + tolua_usertype(tolua_S,"Lua__cPlayer"); + tolua_usertype(tolua_S,"HTTPRequest"); + tolua_usertype(tolua_S,"cPawn"); + tolua_usertype(tolua_S,"cPlayer"); + tolua_usertype(tolua_S,"cTorch"); + tolua_usertype(tolua_S,"cStringMap"); + tolua_usertype(tolua_S,"cInventory"); + tolua_usertype(tolua_S,"cWorld"); + tolua_usertype(tolua_S,"cPlugin_NewLua"); + tolua_usertype(tolua_S,"Lua__cEntity"); + tolua_usertype(tolua_S,"Vector3d"); +} + +/* method: DirectionToMetaData of class cTorch */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTorch_DirectionToMetaData00 +static int tolua_AllToLua_cTorch_DirectionToMetaData00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cTorch",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + char a_Direction = ((char) tolua_tonumber(tolua_S,2,0)); + { + char tolua_ret = (char) cTorch::DirectionToMetaData(a_Direction); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DirectionToMetaData'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: MetaDataToDirection of class cTorch */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTorch_MetaDataToDirection00 +static int tolua_AllToLua_cTorch_MetaDataToDirection00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cTorch",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + char a_MetaData = ((char) tolua_tonumber(tolua_S,2,0)); + { + char tolua_ret = (char) cTorch::MetaDataToDirection(a_MetaData); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'MetaDataToDirection'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: RotationToMetaData of class cStairs */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cStairs_RotationToMetaData00 +static int tolua_AllToLua_cStairs_RotationToMetaData00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cStairs",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + float a_Rotation = ((float) tolua_tonumber(tolua_S,2,0)); + int a_Direction = ((int) tolua_tonumber(tolua_S,3,0)); + { + char tolua_ret = (char) cStairs::RotationToMetaData(a_Rotation,a_Direction); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'RotationToMetaData'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DirectionToMetaData of class cStep */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cStep_DirectionToMetaData00 +static int tolua_AllToLua_cStep_DirectionToMetaData00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cStep",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + int a_Direction = ((int) tolua_tonumber(tolua_S,2,0)); + { + char tolua_ret = (char) cStep::DirectionToMetaData(a_Direction); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DirectionToMetaData'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DirectionToMetaData of class cLadder */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLadder_DirectionToMetaData00 +static int tolua_AllToLua_cLadder_DirectionToMetaData00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cLadder",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + char a_Direction = ((char) tolua_tonumber(tolua_S,2,0)); + { + char tolua_ret = (char) cLadder::DirectionToMetaData(a_Direction); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DirectionToMetaData'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: MetaDataToDirection of class cLadder */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLadder_MetaDataToDirection00 +static int tolua_AllToLua_cLadder_MetaDataToDirection00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cLadder",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + char a_MetaData = ((char) tolua_tonumber(tolua_S,2,0)); + { + char tolua_ret = (char) cLadder::MetaDataToDirection(a_MetaData); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'MetaDataToDirection'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_new00 +static int tolua_AllToLua_cIniFile_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,1,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const std::string iniPath = ((const std::string) tolua_tocppstring(tolua_S,2,"")); + { + cIniFile* tolua_ret = (cIniFile*) Mtolua_new((cIniFile)(iniPath)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cIniFile"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_new00_local +static int tolua_AllToLua_cIniFile_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,1,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const std::string iniPath = ((const std::string) tolua_tocppstring(tolua_S,2,"")); + { + cIniFile* tolua_ret = (cIniFile*) Mtolua_new((cIniFile)(iniPath)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cIniFile"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: CaseSensitive of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_CaseSensitive00 +static int tolua_AllToLua_cIniFile_CaseSensitive00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CaseSensitive'", NULL); +#endif + { + self->CaseSensitive(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'CaseSensitive'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: CaseInsensitive of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_CaseInsensitive00 +static int tolua_AllToLua_cIniFile_CaseInsensitive00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CaseInsensitive'", NULL); +#endif + { + self->CaseInsensitive(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'CaseInsensitive'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Path of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Path00 +static int tolua_AllToLua_cIniFile_Path00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string newPath = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Path'", NULL); +#endif + { + self->Path(newPath); + tolua_pushcppstring(tolua_S,(const char*)newPath); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Path'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Path of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Path01 +static int tolua_AllToLua_cIniFile_Path01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Path'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->Path(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cIniFile_Path00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetPath of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetPath00 +static int tolua_AllToLua_cIniFile_SetPath00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string newPath = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPath'", NULL); +#endif + { + self->SetPath(newPath); + tolua_pushcppstring(tolua_S,(const char*)newPath); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetPath'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: ReadFile of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_ReadFile00 +static int tolua_AllToLua_cIniFile_ReadFile00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ReadFile'", NULL); +#endif + { + bool tolua_ret = (bool) self->ReadFile(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'ReadFile'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: WriteFile of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_WriteFile00 +static int tolua_AllToLua_cIniFile_WriteFile00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'WriteFile'", NULL); +#endif + { + bool tolua_ret = (bool) self->WriteFile(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'WriteFile'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Erase of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Erase00 +static int tolua_AllToLua_cIniFile_Erase00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Erase'", NULL); +#endif + { + self->Erase(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Erase'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Clear of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Clear00 +static int tolua_AllToLua_cIniFile_Clear00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL); +#endif + { + self->Clear(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Reset of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Reset00 +static int tolua_AllToLua_cIniFile_Reset00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Reset'", NULL); +#endif + { + self->Reset(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Reset'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: FindKey of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_FindKey00 +static int tolua_AllToLua_cIniFile_FindKey00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'FindKey'", NULL); +#endif + { + long tolua_ret = (long) self->FindKey(keyname); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'FindKey'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: FindValue of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_FindValue00 +static int tolua_AllToLua_cIniFile_FindValue00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); + const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'FindValue'", NULL); +#endif + { + long tolua_ret = (long) self->FindValue(keyID,valuename); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'FindValue'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: NumKeys of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumKeys00 +static int tolua_AllToLua_cIniFile_NumKeys00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumKeys'", NULL); +#endif + { + unsigned tolua_ret = (unsigned) self->NumKeys(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'NumKeys'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetNumKeys of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetNumKeys00 +static int tolua_AllToLua_cIniFile_GetNumKeys00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumKeys'", NULL); +#endif + { + unsigned tolua_ret = (unsigned) self->GetNumKeys(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetNumKeys'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: AddKeyName of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_AddKeyName00 +static int tolua_AllToLua_cIniFile_AddKeyName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddKeyName'", NULL); +#endif + { + unsigned tolua_ret = (unsigned) self->AddKeyName(keyname); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'AddKeyName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: KeyName of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_KeyName00 +static int tolua_AllToLua_cIniFile_KeyName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KeyName'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->KeyName(keyID); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'KeyName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetKeyName of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetKeyName00 +static int tolua_AllToLua_cIniFile_GetKeyName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetKeyName'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->GetKeyName(keyID); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetKeyName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: NumValues of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumValues00 +static int tolua_AllToLua_cIniFile_NumValues00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumValues'", NULL); +#endif + { + unsigned tolua_ret = (unsigned) self->NumValues(keyname); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'NumValues'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetNumValues of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetNumValues00 +static int tolua_AllToLua_cIniFile_GetNumValues00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumValues'", NULL); +#endif + { + unsigned tolua_ret = (unsigned) self->GetNumValues(keyname); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetNumValues'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: NumValues of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumValues01 +static int tolua_AllToLua_cIniFile_NumValues01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumValues'", NULL); +#endif + { + unsigned tolua_ret = (unsigned) self->NumValues(keyID); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cIniFile_NumValues00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetNumValues of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetNumValues01 +static int tolua_AllToLua_cIniFile_GetNumValues01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumValues'", NULL); +#endif + { + unsigned tolua_ret = (unsigned) self->GetNumValues(keyID); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cIniFile_GetNumValues00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: ValueName of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_ValueName00 +static int tolua_AllToLua_cIniFile_ValueName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ValueName'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->ValueName(keyname,valueID); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'ValueName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValueName of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueName00 +static int tolua_AllToLua_cIniFile_GetValueName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueName'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->GetValueName(keyname,valueID); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetValueName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: ValueName of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_ValueName01 +static int tolua_AllToLua_cIniFile_ValueName01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); + const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ValueName'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->ValueName(keyID,valueID); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cIniFile_ValueName00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValueName of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueName01 +static int tolua_AllToLua_cIniFile_GetValueName01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); + const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueName'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->GetValueName(keyID,valueID); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cIniFile_GetValueName00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValue of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValue00 +static int tolua_AllToLua_cIniFile_GetValue00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValue'", NULL); +#endif + { + AString tolua_ret = (AString) self->GetValue(keyname,valuename); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetValue'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValue of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValue01 +static int tolua_AllToLua_cIniFile_GetValue01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_iscppstring(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); + const AString defValue = ((const AString) tolua_tocppstring(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValue'", NULL); +#endif + { + AString tolua_ret = (AString) self->GetValue(keyname,valuename,defValue); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + tolua_pushcppstring(tolua_S,(const char*)defValue); + } + } + return 4; +tolua_lerror: + return tolua_AllToLua_cIniFile_GetValue00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValue of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValue02 +static int tolua_AllToLua_cIniFile_GetValue02(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); + const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValue'", NULL); +#endif + { + AString tolua_ret = (AString) self->GetValue(keyID,valueID); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cIniFile_GetValue01(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValue of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValue03 +static int tolua_AllToLua_cIniFile_GetValue03(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_iscppstring(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); + const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); + const AString defValue = ((const AString) tolua_tocppstring(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValue'", NULL); +#endif + { + AString tolua_ret = (AString) self->GetValue(keyID,valueID,defValue); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)defValue); + } + } + return 2; +tolua_lerror: + return tolua_AllToLua_cIniFile_GetValue02(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValueF of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueF00 +static int tolua_AllToLua_cIniFile_GetValueF00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); + const double defValue = ((const double) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueF'", NULL); +#endif + { + double tolua_ret = (double) self->GetValueF(keyname,valuename,defValue); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetValueF'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValueI of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueI00 +static int tolua_AllToLua_cIniFile_GetValueI00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); + const int defValue = ((const int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueI'", NULL); +#endif + { + int tolua_ret = (int) self->GetValueI(keyname,valuename,defValue); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetValueI'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValueB of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueB00 +static int tolua_AllToLua_cIniFile_GetValueB00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isboolean(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); + const bool defValue = ((const bool) tolua_toboolean(tolua_S,4,false)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueB'", NULL); +#endif + { + bool tolua_ret = (bool) self->GetValueB(keyname,valuename,defValue); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetValueB'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValueSet of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueSet00 +static int tolua_AllToLua_cIniFile_GetValueSet00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueSet'", NULL); +#endif + { + AString tolua_ret = (AString) self->GetValueSet(keyname,valuename); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetValueSet'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValueSet of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueSet01 +static int tolua_AllToLua_cIniFile_GetValueSet01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_iscppstring(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); + const AString defValue = ((const AString) tolua_tocppstring(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueSet'", NULL); +#endif + { + AString tolua_ret = (AString) self->GetValueSet(keyname,valuename,defValue); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + tolua_pushcppstring(tolua_S,(const char*)defValue); + } + } + return 4; +tolua_lerror: + return tolua_AllToLua_cIniFile_GetValueSet00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValueSetF of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueSetF00 +static int tolua_AllToLua_cIniFile_GetValueSetF00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); + const double defValue = ((const double) tolua_tonumber(tolua_S,4,0.0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueSetF'", NULL); +#endif + { + double tolua_ret = (double) self->GetValueSetF(keyname,valuename,defValue); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetValueSetF'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValueSetI of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueSetI00 +static int tolua_AllToLua_cIniFile_GetValueSetI00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); + const int defValue = ((const int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueSetI'", NULL); +#endif + { + int tolua_ret = (int) self->GetValueSetI(keyname,valuename,defValue); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetValueSetI'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValueSetB of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueSetB00 +static int tolua_AllToLua_cIniFile_GetValueSetB00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isboolean(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); + const bool defValue = ((const bool) tolua_toboolean(tolua_S,4,false)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueSetB'", NULL); +#endif + { + bool tolua_ret = (bool) self->GetValueSetB(keyname,valuename,defValue); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetValueSetB'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetValue of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetValue00 +static int tolua_AllToLua_cIniFile_SetValue00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_iscppstring(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); + const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); + const std::string value = ((const std::string) tolua_tocppstring(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValue'", NULL); +#endif + { + bool tolua_ret = (bool) self->SetValue(keyID,valueID,value); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)value); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetValue'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetValue of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetValue01 +static int tolua_AllToLua_cIniFile_SetValue01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_iscppstring(tolua_S,4,0,&tolua_err) || + !tolua_isboolean(tolua_S,5,1,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0)); + const std::string value = ((const std::string) tolua_tocppstring(tolua_S,4,0)); + const bool create = ((const bool) tolua_toboolean(tolua_S,5,true)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValue'", NULL); +#endif + { + bool tolua_ret = (bool) self->SetValue(keyname,valuename,value,create); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + tolua_pushcppstring(tolua_S,(const char*)value); + } + } + return 4; +tolua_lerror: + return tolua_AllToLua_cIniFile_SetValue00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetValueI of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetValueI00 +static int tolua_AllToLua_cIniFile_SetValueI00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isboolean(tolua_S,5,1,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0)); + const int value = ((const int) tolua_tonumber(tolua_S,4,0)); + const bool create = ((const bool) tolua_toboolean(tolua_S,5,true)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValueI'", NULL); +#endif + { + bool tolua_ret = (bool) self->SetValueI(keyname,valuename,value,create); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetValueI'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetValueB of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetValueB00 +static int tolua_AllToLua_cIniFile_SetValueB00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isboolean(tolua_S,4,0,&tolua_err) || + !tolua_isboolean(tolua_S,5,1,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0)); + const bool value = ((const bool) tolua_toboolean(tolua_S,4,0)); + const bool create = ((const bool) tolua_toboolean(tolua_S,5,true)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValueB'", NULL); +#endif + { + bool tolua_ret = (bool) self->SetValueB(keyname,valuename,value,create); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetValueB'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetValueF of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetValueF00 +static int tolua_AllToLua_cIniFile_SetValueF00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isboolean(tolua_S,5,1,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0)); + const double value = ((const double) tolua_tonumber(tolua_S,4,0)); + const bool create = ((const bool) tolua_toboolean(tolua_S,5,true)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValueF'", NULL); +#endif + { + bool tolua_ret = (bool) self->SetValueF(keyname,valuename,value,create); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetValueF'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DeleteValueByID of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteValueByID00 +static int tolua_AllToLua_cIniFile_DeleteValueByID00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); + const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteValueByID'", NULL); +#endif + { + bool tolua_ret = (bool) self->DeleteValueByID(keyID,valueID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DeleteValueByID'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DeleteValue of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteValue00 +static int tolua_AllToLua_cIniFile_DeleteValue00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteValue'", NULL); +#endif + { + bool tolua_ret = (bool) self->DeleteValue(keyname,valuename); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DeleteValue'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DeleteKey of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteKey00 +static int tolua_AllToLua_cIniFile_DeleteKey00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteKey'", NULL); +#endif + { + bool tolua_ret = (bool) self->DeleteKey(keyname); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DeleteKey'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: NumHeaderComments of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumHeaderComments00 +static int tolua_AllToLua_cIniFile_NumHeaderComments00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumHeaderComments'", NULL); +#endif + { + unsigned tolua_ret = (unsigned) self->NumHeaderComments(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'NumHeaderComments'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: HeaderComment of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_HeaderComment00 +static int tolua_AllToLua_cIniFile_HeaderComment00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string comment = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HeaderComment'", NULL); +#endif + { + self->HeaderComment(comment); + tolua_pushcppstring(tolua_S,(const char*)comment); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'HeaderComment'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: HeaderComment of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_HeaderComment01 +static int tolua_AllToLua_cIniFile_HeaderComment01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned commentID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HeaderComment'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->HeaderComment(commentID); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cIniFile_HeaderComment00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DeleteHeaderComment of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteHeaderComment00 +static int tolua_AllToLua_cIniFile_DeleteHeaderComment00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + unsigned commentID = ((unsigned) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteHeaderComment'", NULL); +#endif + { + bool tolua_ret = (bool) self->DeleteHeaderComment(commentID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DeleteHeaderComment'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DeleteHeaderComments of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteHeaderComments00 +static int tolua_AllToLua_cIniFile_DeleteHeaderComments00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteHeaderComments'", NULL); +#endif + { + self->DeleteHeaderComments(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DeleteHeaderComments'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: NumKeyComments of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumKeyComments00 +static int tolua_AllToLua_cIniFile_NumKeyComments00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumKeyComments'", NULL); +#endif + { + unsigned tolua_ret = (unsigned) self->NumKeyComments(keyID); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'NumKeyComments'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: NumKeyComments of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumKeyComments01 +static int tolua_AllToLua_cIniFile_NumKeyComments01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumKeyComments'", NULL); +#endif + { + unsigned tolua_ret = (unsigned) self->NumKeyComments(keyname); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +tolua_lerror: + return tolua_AllToLua_cIniFile_NumKeyComments00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: KeyComment of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_KeyComment00 +static int tolua_AllToLua_cIniFile_KeyComment00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); + const std::string comment = ((const std::string) tolua_tocppstring(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KeyComment'", NULL); +#endif + { + bool tolua_ret = (bool) self->KeyComment(keyID,comment); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)comment); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'KeyComment'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: KeyComment of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_KeyComment01 +static int tolua_AllToLua_cIniFile_KeyComment01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + const std::string comment = ((const std::string) tolua_tocppstring(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KeyComment'", NULL); +#endif + { + bool tolua_ret = (bool) self->KeyComment(keyname,comment); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)comment); + } + } + return 3; +tolua_lerror: + return tolua_AllToLua_cIniFile_KeyComment00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: KeyComment of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_KeyComment02 +static int tolua_AllToLua_cIniFile_KeyComment02(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); + const unsigned commentID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KeyComment'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->KeyComment(keyID,commentID); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cIniFile_KeyComment01(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: KeyComment of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_KeyComment03 +static int tolua_AllToLua_cIniFile_KeyComment03(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + const unsigned commentID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KeyComment'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->KeyComment(keyname,commentID); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +tolua_lerror: + return tolua_AllToLua_cIniFile_KeyComment02(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DeleteKeyComment of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteKeyComment00 +static int tolua_AllToLua_cIniFile_DeleteKeyComment00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); + const unsigned commentID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteKeyComment'", NULL); +#endif + { + bool tolua_ret = (bool) self->DeleteKeyComment(keyID,commentID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DeleteKeyComment'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DeleteKeyComment of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteKeyComment01 +static int tolua_AllToLua_cIniFile_DeleteKeyComment01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + const unsigned commentID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteKeyComment'", NULL); +#endif + { + bool tolua_ret = (bool) self->DeleteKeyComment(keyname,commentID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +tolua_lerror: + return tolua_AllToLua_cIniFile_DeleteKeyComment00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DeleteKeyComments of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteKeyComments00 +static int tolua_AllToLua_cIniFile_DeleteKeyComments00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteKeyComments'", NULL); +#endif + { + bool tolua_ret = (bool) self->DeleteKeyComments(keyID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DeleteKeyComments'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DeleteKeyComments of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteKeyComments01 +static int tolua_AllToLua_cIniFile_DeleteKeyComments01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteKeyComments'", NULL); +#endif + { + bool tolua_ret = (bool) self->DeleteKeyComments(keyname); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +tolua_lerror: + return tolua_AllToLua_cIniFile_DeleteKeyComments00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* function: BlockStringToType */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_BlockStringToType00 +static int tolua_AllToLua_BlockStringToType00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_iscppstring(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const AString a_BlockTypeString = ((const AString) tolua_tocppstring(tolua_S,1,0)); + { + int tolua_ret = (int) BlockStringToType(a_BlockTypeString); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)a_BlockTypeString); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'BlockStringToType'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: StringToItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_StringToItem00 +static int tolua_AllToLua_StringToItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_iscppstring(tolua_S,1,0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const AString a_ItemTypeString = ((const AString) tolua_tocppstring(tolua_S,1,0)); + cItem* a_Item = ((cItem*) tolua_tousertype(tolua_S,2,0)); + { + bool tolua_ret = (bool) StringToItem(a_ItemTypeString,*a_Item); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)a_ItemTypeString); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'StringToItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: g_BlockLightValue */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockLightValue +static int tolua_get_AllToLua_g_BlockLightValue(lua_State* tolua_S) +{ + int tolua_index; +#ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } +#endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); +#ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)g_BlockLightValue[tolua_index]); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: g_BlockLightValue */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockLightValue +static int tolua_set_AllToLua_g_BlockLightValue(lua_State* tolua_S) +{ + int tolua_index; +#ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } +#endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); +#ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); +#endif + g_BlockLightValue[tolua_index] = ((unsigned char) tolua_tonumber(tolua_S,3,0)); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: g_BlockSpreadLightFalloff */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockSpreadLightFalloff +static int tolua_get_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) +{ + int tolua_index; +#ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } +#endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); +#ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)g_BlockSpreadLightFalloff[tolua_index]); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: g_BlockSpreadLightFalloff */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockSpreadLightFalloff +static int tolua_set_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) +{ + int tolua_index; +#ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } +#endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); +#ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); +#endif + g_BlockSpreadLightFalloff[tolua_index] = ((unsigned char) tolua_tonumber(tolua_S,3,0)); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: g_BlockTransparent */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockTransparent +static int tolua_get_AllToLua_g_BlockTransparent(lua_State* tolua_S) +{ + int tolua_index; +#ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } +#endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); +#ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); +#endif + tolua_pushboolean(tolua_S,(bool)g_BlockTransparent[tolua_index]); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: g_BlockTransparent */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockTransparent +static int tolua_set_AllToLua_g_BlockTransparent(lua_State* tolua_S) +{ + int tolua_index; +#ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } +#endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); +#ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); +#endif + g_BlockTransparent[tolua_index] = ((bool) tolua_toboolean(tolua_S,3,0)); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: g_BlockOneHitDig */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockOneHitDig +static int tolua_get_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) +{ + int tolua_index; +#ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } +#endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); +#ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); +#endif + tolua_pushboolean(tolua_S,(bool)g_BlockOneHitDig[tolua_index]); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: g_BlockOneHitDig */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockOneHitDig +static int tolua_set_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) +{ + int tolua_index; +#ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } +#endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); +#ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); +#endif + g_BlockOneHitDig[tolua_index] = ((bool) tolua_toboolean(tolua_S,3,0)); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* function: IsValidBlock */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_IsValidBlock00 +static int tolua_AllToLua_IsValidBlock00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnumber(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + int a_BlockID = ((int) tolua_tonumber(tolua_S,1,0)); + { + bool tolua_ret = (bool) IsValidBlock(a_BlockID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsValidBlock'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: IsValidItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_IsValidItem00 +static int tolua_AllToLua_IsValidItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnumber(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + int a_ItemID = ((int) tolua_tonumber(tolua_S,1,0)); + { + bool tolua_ret = (bool) IsValidItem(a_ItemID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsValidItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: AddDirection */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_AddDirection00 +static int tolua_AllToLua_AddDirection00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnumber(tolua_S,1,0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isboolean(tolua_S,5,1,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + int a_X = ((int) tolua_tonumber(tolua_S,1,0)); + unsigned char a_Y = ((unsigned char) tolua_tonumber(tolua_S,2,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,3,0)); + char a_Direction = ((char) tolua_tonumber(tolua_S,4,0)); + bool a_bInverse = ((bool) tolua_toboolean(tolua_S,5,false)); + { + AddDirection(a_X,a_Y,a_Z,a_Direction,a_bInverse); + tolua_pushnumber(tolua_S,(lua_Number)a_X); + tolua_pushnumber(tolua_S,(lua_Number)a_Y); + tolua_pushnumber(tolua_S,(lua_Number)a_Z); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'AddDirection'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: ItemCategory::IsPickaxe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsPickaxe00 +static int tolua_AllToLua_ItemCategory_IsPickaxe00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnumber(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0)); + { + bool tolua_ret = (bool) ItemCategory::IsPickaxe(a_ItemID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsPickaxe'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: ItemCategory::IsAxe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsAxe00 +static int tolua_AllToLua_ItemCategory_IsAxe00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnumber(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0)); + { + bool tolua_ret = (bool) ItemCategory::IsAxe(a_ItemID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsAxe'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: ItemCategory::IsSword */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsSword00 +static int tolua_AllToLua_ItemCategory_IsSword00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnumber(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0)); + { + bool tolua_ret = (bool) ItemCategory::IsSword(a_ItemID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsSword'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: ItemCategory::IsHoe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsHoe00 +static int tolua_AllToLua_ItemCategory_IsHoe00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnumber(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0)); + { + bool tolua_ret = (bool) ItemCategory::IsHoe(a_ItemID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsHoe'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: ItemCategory::IsShovel */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsShovel00 +static int tolua_AllToLua_ItemCategory_IsShovel00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnumber(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0)); + { + bool tolua_ret = (bool) ItemCategory::IsShovel(a_ItemID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsShovel'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: ItemCategory::IsTool */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsTool00 +static int tolua_AllToLua_ItemCategory_IsTool00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnumber(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0)); + { + bool tolua_ret = (bool) ItemCategory::IsTool(a_ItemID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsTool'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: GetTime */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_GetTime00 +static int tolua_AllToLua_GetTime00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnoobj(tolua_S,1,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + unsigned int tolua_ret = (unsigned int) GetTime(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetTime'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: GetChar */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_GetChar00 +static int tolua_AllToLua_GetChar00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_iscppstring(tolua_S,1,0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + std::string a_Str = ((std::string) tolua_tocppstring(tolua_S,1,0)); + unsigned int a_Idx = ((unsigned int) tolua_tonumber(tolua_S,2,0)); + { + std::string tolua_ret = (std::string) GetChar(a_Str,a_Idx); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)a_Str); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetChar'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: clear of class cStringMap */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cStringMap_clear00 +static int tolua_AllToLua_cStringMap_clear00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cStringMap",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cStringMap* self = (cStringMap*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'clear'", NULL); +#endif + { + self->clear(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'clear'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: size of class cStringMap */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cStringMap_size00 +static int tolua_AllToLua_cStringMap_size00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cStringMap",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cStringMap* self = (const cStringMap*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'size'", NULL); +#endif + { + unsigned int tolua_ret = (unsigned int) self->size(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'size'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: get of class cStringMap */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cStringMap_get00 +static int tolua_AllToLua_cStringMap_get00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cStringMap",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cStringMap* self = (cStringMap*) tolua_tousertype(tolua_S,1,0); + const std::string index = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'get'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->get(index); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)index); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'get'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Color of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Color +static int tolua_get_cChatColor_Color(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Color); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Delimiter of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Delimiter +static int tolua_get_cChatColor_Delimiter(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Delimiter); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Black of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Black +static int tolua_get_cChatColor_Black(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Black); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Navy of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Navy +static int tolua_get_cChatColor_Navy(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Navy); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Green of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Green +static int tolua_get_cChatColor_Green(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Green); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Blue of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Blue +static int tolua_get_cChatColor_Blue(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Blue); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Red of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Red +static int tolua_get_cChatColor_Red(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Red); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Purple of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Purple +static int tolua_get_cChatColor_Purple(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Purple); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Gold of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Gold +static int tolua_get_cChatColor_Gold(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Gold); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: LightGray of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_LightGray +static int tolua_get_cChatColor_LightGray(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::LightGray); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Gray of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Gray +static int tolua_get_cChatColor_Gray(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Gray); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: DarkPurple of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_DarkPurple +static int tolua_get_cChatColor_DarkPurple(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::DarkPurple); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: LightGreen of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_LightGreen +static int tolua_get_cChatColor_LightGreen(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::LightGreen); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: LightBlue of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_LightBlue +static int tolua_get_cChatColor_LightBlue(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::LightBlue); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Rose of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Rose +static int tolua_get_cChatColor_Rose(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Rose); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: LightPurple of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_LightPurple +static int tolua_get_cChatColor_LightPurple(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::LightPurple); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Yellow of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Yellow +static int tolua_get_cChatColor_Yellow(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Yellow); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: White of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_White +static int tolua_get_cChatColor_White(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::White); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Random of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Random +static int tolua_get_cChatColor_Random(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Random); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Bold of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Bold +static int tolua_get_cChatColor_Bold(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Bold); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Strikethrough of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Strikethrough +static int tolua_get_cChatColor_Strikethrough(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Strikethrough); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Underlined of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Underlined +static int tolua_get_cChatColor_Underlined(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Underlined); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Italic of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Italic +static int tolua_get_cChatColor_Italic(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Italic); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Plain of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Plain +static int tolua_get_cChatColor_Plain(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Plain); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: MakeColor of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cChatColor_MakeColor00 +static int tolua_AllToLua_cChatColor_MakeColor00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cChatColor",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + char a_Color = ((char) tolua_tonumber(tolua_S,2,0)); + { + const std::string tolua_ret = (const std::string) cChatColor::MakeColor(a_Color); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'MakeColor'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPlayer of class cClientHandle */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_GetPlayer00 +static int tolua_AllToLua_cClientHandle_GetPlayer00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cClientHandle",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cClientHandle* self = (cClientHandle*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPlayer'", NULL); +#endif + { + cPlayer* tolua_ret = (cPlayer*) self->GetPlayer(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPlayer"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPlayer'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Kick of class cClientHandle */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_Kick00 +static int tolua_AllToLua_cClientHandle_Kick00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cClientHandle",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cClientHandle* self = (cClientHandle*) tolua_tousertype(tolua_S,1,0); + const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Kick'", NULL); +#endif + { + self->Kick(a_Reason); + tolua_pushcppstring(tolua_S,(const char*)a_Reason); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Kick'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetUsername of class cClientHandle */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_GetUsername00 +static int tolua_AllToLua_cClientHandle_GetUsername00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cClientHandle",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cClientHandle* self = (const cClientHandle*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetUsername'", NULL); +#endif + { + const AString tolua_ret = (const AString) self->GetUsername(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetUsername'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPing of class cClientHandle */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_GetPing00 +static int tolua_AllToLua_cClientHandle_GetPing00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cClientHandle",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cClientHandle* self = (const cClientHandle*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPing'", NULL); +#endif + { + short tolua_ret = (short) self->GetPing(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPing'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetViewDistance of class cClientHandle */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_SetViewDistance00 +static int tolua_AllToLua_cClientHandle_SetViewDistance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cClientHandle",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cClientHandle* self = (cClientHandle*) tolua_tousertype(tolua_S,1,0); + int a_ViewDistance = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetViewDistance'", NULL); +#endif + { + self->SetViewDistance(a_ViewDistance); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetViewDistance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetViewDistance of class cClientHandle */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_GetViewDistance00 +static int tolua_AllToLua_cClientHandle_GetViewDistance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cClientHandle",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cClientHandle* self = (cClientHandle*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetViewDistance'", NULL); +#endif + { + int tolua_ret = (int) self->GetViewDistance(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetViewDistance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetUniqueID of class cClientHandle */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_GetUniqueID00 +static int tolua_AllToLua_cClientHandle_GetUniqueID00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cClientHandle",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cClientHandle* self = (const cClientHandle*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetUniqueID'", NULL); +#endif + { + int tolua_ret = (int) self->GetUniqueID(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetUniqueID'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_delete00 +static int tolua_AllToLua_cEntity_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Initialize of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_Initialize00 +static int tolua_AllToLua_cEntity_Initialize00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL); +#endif + { + self->Initialize(a_World); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetEntityType of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetEntityType00 +static int tolua_AllToLua_cEntity_GetEntityType00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEntityType'", NULL); +#endif + { + unsigned int tolua_ret = (unsigned int) self->GetEntityType(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetEntityType'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsA of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_IsA00 +static int tolua_AllToLua_cEntity_IsA00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + const char* a_EntityType = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsA'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsA(a_EntityType); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsA'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetClass of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetClass00 +static int tolua_AllToLua_cEntity_GetClass00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetClass'", NULL); +#endif + { + const char* tolua_ret = (const char*) self->GetClass(); + tolua_pushstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetClass'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetWorld of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetWorld00 +static int tolua_AllToLua_cEntity_GetWorld00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWorld'", NULL); +#endif + { + cWorld* tolua_ret = (cWorld*) self->GetWorld(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWorld"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetWorld'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPosition of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPosition00 +static int tolua_AllToLua_cEntity_GetPosition00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPosition'", NULL); +#endif + { + const Vector3d& tolua_ret = (const Vector3d&) self->GetPosition(); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const Vector3d"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPosition'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPosX of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPosX00 +static int tolua_AllToLua_cEntity_GetPosX00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPosX'", NULL); +#endif + { + const double tolua_ret = (const double) self->GetPosX(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPosX'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPosY of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPosY00 +static int tolua_AllToLua_cEntity_GetPosY00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPosY'", NULL); +#endif + { + const double tolua_ret = (const double) self->GetPosY(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPosY'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPosZ of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPosZ00 +static int tolua_AllToLua_cEntity_GetPosZ00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPosZ'", NULL); +#endif + { + const double tolua_ret = (const double) self->GetPosZ(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPosZ'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetRot of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetRot00 +static int tolua_AllToLua_cEntity_GetRot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetRot'", NULL); +#endif + { + const Vector3f& tolua_ret = (const Vector3f&) self->GetRot(); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const Vector3f"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetRot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetRotation of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetRotation00 +static int tolua_AllToLua_cEntity_GetRotation00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetRotation'", NULL); +#endif + { + float tolua_ret = (float) self->GetRotation(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetRotation'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPitch of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPitch00 +static int tolua_AllToLua_cEntity_GetPitch00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPitch'", NULL); +#endif + { + float tolua_ret = (float) self->GetPitch(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPitch'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetRoll of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetRoll00 +static int tolua_AllToLua_cEntity_GetRoll00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetRoll'", NULL); +#endif + { + float tolua_ret = (float) self->GetRoll(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetRoll'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetLookVector of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetLookVector00 +static int tolua_AllToLua_cEntity_GetLookVector00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLookVector'", NULL); +#endif + { + Vector3f tolua_ret = (Vector3f) self->GetLookVector(); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetLookVector'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetChunkX of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetChunkX00 +static int tolua_AllToLua_cEntity_GetChunkX00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetChunkX'", NULL); +#endif + { + int tolua_ret = (int) self->GetChunkX(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetChunkX'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetChunkY of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetChunkY00 +static int tolua_AllToLua_cEntity_GetChunkY00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetChunkY'", NULL); +#endif + { + int tolua_ret = (int) self->GetChunkY(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetChunkY'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetChunkZ of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetChunkZ00 +static int tolua_AllToLua_cEntity_GetChunkZ00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetChunkZ'", NULL); +#endif + { + int tolua_ret = (int) self->GetChunkZ(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetChunkZ'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetPosX of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosX00 +static int tolua_AllToLua_cEntity_SetPosX00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPosX'", NULL); +#endif + { + self->SetPosX(a_PosX); + tolua_pushnumber(tolua_S,(lua_Number)a_PosX); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetPosX'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetPosY of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosY00 +static int tolua_AllToLua_cEntity_SetPosY00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + const double a_PosY = ((const double) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPosY'", NULL); +#endif + { + self->SetPosY(a_PosY); + tolua_pushnumber(tolua_S,(lua_Number)a_PosY); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetPosY'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetPosZ of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosZ00 +static int tolua_AllToLua_cEntity_SetPosZ00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + const double a_PosZ = ((const double) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPosZ'", NULL); +#endif + { + self->SetPosZ(a_PosZ); + tolua_pushnumber(tolua_S,(lua_Number)a_PosZ); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetPosZ'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetPosition of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosition00 +static int tolua_AllToLua_cEntity_SetPosition00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0)); + const double a_PosY = ((const double) tolua_tonumber(tolua_S,3,0)); + const double a_PosZ = ((const double) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPosition'", NULL); +#endif + { + self->SetPosition(a_PosX,a_PosY,a_PosZ); + tolua_pushnumber(tolua_S,(lua_Number)a_PosX); + tolua_pushnumber(tolua_S,(lua_Number)a_PosY); + tolua_pushnumber(tolua_S,(lua_Number)a_PosZ); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetPosition'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetPosition of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosition01 +static int tolua_AllToLua_cEntity_SetPosition01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + const Vector3d* a_Pos = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPosition'", NULL); +#endif + { + self->SetPosition(*a_Pos); + } + } + return 0; +tolua_lerror: + return tolua_AllToLua_cEntity_SetPosition00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetRot of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetRot00 +static int tolua_AllToLua_cEntity_SetRot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + const Vector3f* a_Rot = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetRot'", NULL); +#endif + { + self->SetRot(*a_Rot); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetRot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetRotation of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetRotation00 +static int tolua_AllToLua_cEntity_SetRotation00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + float a_Rotation = ((float) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetRotation'", NULL); +#endif + { + self->SetRotation(a_Rotation); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetRotation'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetPitch of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPitch00 +static int tolua_AllToLua_cEntity_SetPitch00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + float a_Pitch = ((float) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPitch'", NULL); +#endif + { + self->SetPitch(a_Pitch); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetPitch'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetRoll of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetRoll00 +static int tolua_AllToLua_cEntity_SetRoll00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + float a_Roll = ((float) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetRoll'", NULL); +#endif + { + self->SetRoll(a_Roll); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetRoll'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetUniqueID of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetUniqueID00 +static int tolua_AllToLua_cEntity_GetUniqueID00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetUniqueID'", NULL); +#endif + { + int tolua_ret = (int) self->GetUniqueID(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetUniqueID'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsDestroyed of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_IsDestroyed00 +static int tolua_AllToLua_cEntity_IsDestroyed00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsDestroyed'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsDestroyed(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsDestroyed'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Destroy of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_Destroy00 +static int tolua_AllToLua_cEntity_Destroy00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Destroy'", NULL); +#endif + { + self->Destroy(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Destroy'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Tick of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_Tick00 +static int tolua_AllToLua_cEntity_Tick00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + float a_Dt = ((float) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Tick'", NULL); +#endif + { + self->Tick(a_Dt); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Tick'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SpawnOn of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SpawnOn00 +static int tolua_AllToLua_cEntity_SpawnOn00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cClientHandle",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + cClientHandle* a_Client = ((cClientHandle*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SpawnOn'", NULL); +#endif + { + self->SpawnOn(a_Client); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SpawnOn'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + class Lua__cEntity : public cEntity, public ToluaBase { +public: + void Initialize( cWorld* a_World) { + if (push_method("Initialize", tolua_AllToLua_cEntity_Initialize00)) { + tolua_pushusertype(lua_state, (void*)a_World, "cWorld"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cEntity:: Initialize(a_World); + }; + }; + unsigned int GetEntityType( void ) { + if (push_method("GetEntityType", tolua_AllToLua_cEntity_GetEntityType00)) { + ToluaBase::dbcall(lua_state, 1, 1); + unsigned int tolua_ret = (unsigned int )tolua_tonumber(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return (unsigned int ) cEntity:: GetEntityType(); + }; + }; + bool IsA( const char* a_EntityType) { + if (push_method("IsA", tolua_AllToLua_cEntity_IsA00)) { + tolua_pushstring(lua_state, (const char*)a_EntityType); + ToluaBase::dbcall(lua_state, 2, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cEntity:: IsA(a_EntityType); + }; + }; + const char* GetClass( void ) { + if (push_method("GetClass", tolua_AllToLua_cEntity_GetClass00)) { + ToluaBase::dbcall(lua_state, 1, 1); + const char* tolua_ret = ( const char* )tolua_tostring(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( const char* ) cEntity:: GetClass(); + }; + }; + void Tick( float a_Dt) { + if (push_method("Tick", tolua_AllToLua_cEntity_Tick00)) { + tolua_pushnumber(lua_state, (lua_Number)a_Dt); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + if (lua_state) + LOG("pure-virtual method cEntity::Tick not implemented."); + else { + LOG("pure-virtual method cEntity::Tick called with no lua_state. Aborting"); + ::abort(); + }; + return ( void )0; + }; + }; + + void cEntity__Initialize( cWorld* a_World) { + return ( void )cEntity::Initialize(a_World); + }; + unsigned int cEntity__GetEntityType( void ) { + return (unsigned int )cEntity::GetEntityType(); + }; + bool cEntity__IsA( const char* a_EntityType) { + return ( bool )cEntity::IsA(a_EntityType); + }; + const char* cEntity__GetClass( void ) { + return ( const char* )cEntity::GetClass(); + }; + Lua__cEntity( const double& a_X, const double& a_Y, const double& a_Z): cEntity(a_X,a_Y,a_Z){}; +}; + +/* method: tolua__set_instance of class Lua__cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_tolua__set_instance00 +static int tolua_AllToLua_Lua__cEntity_tolua__set_instance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); + lua_State* L = tolua_S; + lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); +#endif + { + self->tolua__set_instance(L,lo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cEntity__Initialize of class Lua__cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_cEntity__Initialize00 +static int tolua_AllToLua_Lua__cEntity_cEntity__Initialize00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); + cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cEntity__Initialize'", NULL); +#endif + { + self->cEntity__Initialize(a_World); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cEntity__Initialize'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cEntity__GetEntityType of class Lua__cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_cEntity__GetEntityType00 +static int tolua_AllToLua_Lua__cEntity_cEntity__GetEntityType00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cEntity__GetEntityType'", NULL); +#endif + { + unsigned int tolua_ret = (unsigned int) self->cEntity__GetEntityType(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cEntity__GetEntityType'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cEntity__IsA of class Lua__cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_cEntity__IsA00 +static int tolua_AllToLua_Lua__cEntity_cEntity__IsA00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); + const char* a_EntityType = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cEntity__IsA'", NULL); +#endif + { + bool tolua_ret = (bool) self->cEntity__IsA(a_EntityType); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cEntity__IsA'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cEntity__GetClass of class Lua__cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_cEntity__GetClass00 +static int tolua_AllToLua_Lua__cEntity_cEntity__GetClass00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cEntity__GetClass'", NULL); +#endif + { + const char* tolua_ret = (const char*) self->cEntity__GetClass(); + tolua_pushstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cEntity__GetClass'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Lua__cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_new00 +static int tolua_AllToLua_Lua__cEntity_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const double a_X = ((const double) tolua_tonumber(tolua_S,2,0)); + const double a_Y = ((const double) tolua_tonumber(tolua_S,3,0)); + const double a_Z = ((const double) tolua_tonumber(tolua_S,4,0)); + { + Lua__cEntity* tolua_ret = (Lua__cEntity*) Mtolua_new((Lua__cEntity)(a_X,a_Y,a_Z)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cEntity"); + tolua_pushnumber(tolua_S,(lua_Number)a_X); + tolua_pushnumber(tolua_S,(lua_Number)a_Y); + tolua_pushnumber(tolua_S,(lua_Number)a_Z); + } + } + return 4; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Lua__cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_new00_local +static int tolua_AllToLua_Lua__cEntity_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const double a_X = ((const double) tolua_tonumber(tolua_S,2,0)); + const double a_Y = ((const double) tolua_tonumber(tolua_S,3,0)); + const double a_Z = ((const double) tolua_tonumber(tolua_S,4,0)); + { + Lua__cEntity* tolua_ret = (Lua__cEntity*) Mtolua_new((Lua__cEntity)(a_X,a_Y,a_Z)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cEntity"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + tolua_pushnumber(tolua_S,(lua_Number)a_X); + tolua_pushnumber(tolua_S,(lua_Number)a_Y); + tolua_pushnumber(tolua_S,(lua_Number)a_Z); + } + } + return 4; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class Lua__cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_delete00 +static int tolua_AllToLua_Lua__cEntity_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + +/* function to release collected object via destructor */ +#ifdef __cplusplus + +static int tolua_collect_Lua__cEntity (lua_State* tolua_S) +{ + Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); + delete self; + return 0; +} +#endif + +/* get function: Damage of class TakeDamageInfo */ +#ifndef TOLUA_DISABLE_tolua_get_TakeDamageInfo_Damage +static int tolua_get_TakeDamageInfo_Damage(lua_State* tolua_S) +{ + TakeDamageInfo* self = (TakeDamageInfo*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Damage'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->Damage); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Damage of class TakeDamageInfo */ +#ifndef TOLUA_DISABLE_tolua_set_TakeDamageInfo_Damage +static int tolua_set_TakeDamageInfo_Damage(lua_State* tolua_S) +{ + TakeDamageInfo* self = (TakeDamageInfo*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Damage'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Damage = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Instigator of class TakeDamageInfo */ +#ifndef TOLUA_DISABLE_tolua_get_TakeDamageInfo_Instigator_ptr +static int tolua_get_TakeDamageInfo_Instigator_ptr(lua_State* tolua_S) +{ + TakeDamageInfo* self = (TakeDamageInfo*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Instigator'",NULL); +#endif + tolua_pushusertype(tolua_S,(void*)self->Instigator,"cEntity"); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Instigator of class TakeDamageInfo */ +#ifndef TOLUA_DISABLE_tolua_set_TakeDamageInfo_Instigator_ptr +static int tolua_set_TakeDamageInfo_Instigator_ptr(lua_State* tolua_S) +{ + TakeDamageInfo* self = (TakeDamageInfo*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Instigator'",NULL); + if (!tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Instigator = ((cEntity*) tolua_tousertype(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: TeleportToEntity of class cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_TeleportToEntity00 +static int tolua_AllToLua_cPawn_TeleportToEntity00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0); + cEntity* a_Entity = ((cEntity*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TeleportToEntity'", NULL); +#endif + { + self->TeleportToEntity(a_Entity); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'TeleportToEntity'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: TeleportTo of class cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_TeleportTo00 +static int tolua_AllToLua_cPawn_TeleportTo00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0); + const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0)); + const double a_PosY = ((const double) tolua_tonumber(tolua_S,3,0)); + const double a_PosZ = ((const double) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TeleportTo'", NULL); +#endif + { + self->TeleportTo(a_PosX,a_PosY,a_PosZ); + tolua_pushnumber(tolua_S,(lua_Number)a_PosX); + tolua_pushnumber(tolua_S,(lua_Number)a_PosY); + tolua_pushnumber(tolua_S,(lua_Number)a_PosZ); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'TeleportTo'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Heal of class cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_Heal00 +static int tolua_AllToLua_cPawn_Heal00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0); + int a_Health = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Heal'", NULL); +#endif + { + self->Heal(a_Health); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Heal'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: TakeDamage of class cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_TakeDamage00 +static int tolua_AllToLua_cPawn_TakeDamage00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0); + int a_Damage = ((int) tolua_tonumber(tolua_S,2,0)); + cEntity* a_Instigator = ((cEntity*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TakeDamage'", NULL); +#endif + { + self->TakeDamage(a_Damage,a_Instigator); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'TakeDamage'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: KilledBy of class cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_KilledBy00 +static int tolua_AllToLua_cPawn_KilledBy00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0); + cEntity* a_Killer = ((cEntity*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KilledBy'", NULL); +#endif + { + self->KilledBy(a_Killer); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'KilledBy'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetHealth of class cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_GetHealth00 +static int tolua_AllToLua_cPawn_GetHealth00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHealth'", NULL); +#endif + { + int tolua_ret = (int) self->GetHealth(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetHealth'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + class Lua__cPawn : public cPawn, public ToluaBase { +public: + void TeleportToEntity( cEntity* a_Entity) { + if (push_method("TeleportToEntity", tolua_AllToLua_cPawn_TeleportToEntity00)) { + tolua_pushusertype(lua_state, (void*)a_Entity, "cEntity"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPawn:: TeleportToEntity(a_Entity); + }; + }; + void TeleportTo( const double& a_PosX, const double& a_PosY, const double& a_PosZ) { + if (push_method("TeleportTo", tolua_AllToLua_cPawn_TeleportTo00)) { + tolua_pushnumber(lua_state, (lua_Number)a_PosX); + tolua_pushnumber(lua_state, (lua_Number)a_PosY); + tolua_pushnumber(lua_state, (lua_Number)a_PosZ); + ToluaBase::dbcall(lua_state, 4, 0); + } else { + return ( void ) cPawn:: TeleportTo(a_PosX,a_PosY,a_PosZ); + }; + }; + void TakeDamage( int a_Damage, cEntity* a_Instigator) { + if (push_method("TakeDamage", tolua_AllToLua_cPawn_TakeDamage00)) { + tolua_pushnumber(lua_state, (lua_Number)a_Damage); + tolua_pushusertype(lua_state, (void*)a_Instigator, "cEntity"); + ToluaBase::dbcall(lua_state, 3, 0); + } else { + return ( void ) cPawn:: TakeDamage(a_Damage,a_Instigator); + }; + }; + void KilledBy( cEntity* a_Killer) { + if (push_method("KilledBy", tolua_AllToLua_cPawn_KilledBy00)) { + tolua_pushusertype(lua_state, (void*)a_Killer, "cEntity"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPawn:: KilledBy(a_Killer); + }; + }; + void Initialize( cWorld* a_World) { + if (push_method("Initialize", tolua_AllToLua_cEntity_Initialize00)) { + tolua_pushusertype(lua_state, (void*)a_World, "cWorld"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPawn:: Initialize(a_World); + }; + }; + unsigned int GetEntityType( void ) { + if (push_method("GetEntityType", tolua_AllToLua_cEntity_GetEntityType00)) { + ToluaBase::dbcall(lua_state, 1, 1); + unsigned int tolua_ret = (unsigned int )tolua_tonumber(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return (unsigned int ) cPawn:: GetEntityType(); + }; + }; + bool IsA( const char* a_EntityType) { + if (push_method("IsA", tolua_AllToLua_cEntity_IsA00)) { + tolua_pushstring(lua_state, (const char*)a_EntityType); + ToluaBase::dbcall(lua_state, 2, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPawn:: IsA(a_EntityType); + }; + }; + const char* GetClass( void ) { + if (push_method("GetClass", tolua_AllToLua_cEntity_GetClass00)) { + ToluaBase::dbcall(lua_state, 1, 1); + const char* tolua_ret = ( const char* )tolua_tostring(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( const char* ) cPawn:: GetClass(); + }; + }; + void Tick( float a_Dt) { + if (push_method("Tick", tolua_AllToLua_cEntity_Tick00)) { + tolua_pushnumber(lua_state, (lua_Number)a_Dt); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + if (lua_state) + LOG("pure-virtual method cPawn::Tick not implemented."); + else { + LOG("pure-virtual method cPawn::Tick called with no lua_state. Aborting"); + ::abort(); + }; + return ( void )0; + }; + }; + + void cPawn__TeleportToEntity( cEntity* a_Entity) { + return ( void )cPawn::TeleportToEntity(a_Entity); + }; + void cPawn__TeleportTo( const double& a_PosX, const double& a_PosY, const double& a_PosZ) { + return ( void )cPawn::TeleportTo(a_PosX,a_PosY,a_PosZ); + }; + void cPawn__TakeDamage( int a_Damage, cEntity* a_Instigator) { + return ( void )cPawn::TakeDamage(a_Damage,a_Instigator); + }; + void cPawn__KilledBy( cEntity* a_Killer) { + return ( void )cPawn::KilledBy(a_Killer); + }; + void cPawn__Initialize( cWorld* a_World) { + return ( void )cPawn::Initialize(a_World); + }; + unsigned int cPawn__GetEntityType( void ) { + return (unsigned int )cPawn::GetEntityType(); + }; + bool cPawn__IsA( const char* a_EntityType) { + return ( bool )cPawn::IsA(a_EntityType); + }; + const char* cPawn__GetClass( void ) { + return ( const char* )cPawn::GetClass(); + }; +}; + +/* method: tolua__set_instance of class Lua__cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPawn_tolua__set_instance00 +static int tolua_AllToLua_Lua__cPawn_tolua__set_instance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPawn",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPawn* self = (Lua__cPawn*) tolua_tousertype(tolua_S,1,0); + lua_State* L = tolua_S; + lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); +#endif + { + self->tolua__set_instance(L,lo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPawn__TeleportToEntity of class Lua__cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPawn_cPawn__TeleportToEntity00 +static int tolua_AllToLua_Lua__cPawn_cPawn__TeleportToEntity00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPawn",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPawn* self = (Lua__cPawn*) tolua_tousertype(tolua_S,1,0); + cEntity* a_Entity = ((cEntity*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPawn__TeleportToEntity'", NULL); +#endif + { + self->cPawn__TeleportToEntity(a_Entity); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPawn__TeleportToEntity'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPawn__TeleportTo of class Lua__cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPawn_cPawn__TeleportTo00 +static int tolua_AllToLua_Lua__cPawn_cPawn__TeleportTo00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPawn",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPawn* self = (Lua__cPawn*) tolua_tousertype(tolua_S,1,0); + const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0)); + const double a_PosY = ((const double) tolua_tonumber(tolua_S,3,0)); + const double a_PosZ = ((const double) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPawn__TeleportTo'", NULL); +#endif + { + self->cPawn__TeleportTo(a_PosX,a_PosY,a_PosZ); + tolua_pushnumber(tolua_S,(lua_Number)a_PosX); + tolua_pushnumber(tolua_S,(lua_Number)a_PosY); + tolua_pushnumber(tolua_S,(lua_Number)a_PosZ); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPawn__TeleportTo'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPawn__TakeDamage of class Lua__cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPawn_cPawn__TakeDamage00 +static int tolua_AllToLua_Lua__cPawn_cPawn__TakeDamage00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPawn",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPawn* self = (Lua__cPawn*) tolua_tousertype(tolua_S,1,0); + int a_Damage = ((int) tolua_tonumber(tolua_S,2,0)); + cEntity* a_Instigator = ((cEntity*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPawn__TakeDamage'", NULL); +#endif + { + self->cPawn__TakeDamage(a_Damage,a_Instigator); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPawn__TakeDamage'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPawn__KilledBy of class Lua__cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPawn_cPawn__KilledBy00 +static int tolua_AllToLua_Lua__cPawn_cPawn__KilledBy00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPawn",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPawn* self = (Lua__cPawn*) tolua_tousertype(tolua_S,1,0); + cEntity* a_Killer = ((cEntity*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPawn__KilledBy'", NULL); +#endif + { + self->cPawn__KilledBy(a_Killer); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPawn__KilledBy'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Initialize of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_Initialize00 +static int tolua_AllToLua_cPlayer_Initialize00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL); +#endif + { + self->Initialize(a_World); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetEyeHeight of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetEyeHeight00 +static int tolua_AllToLua_cPlayer_GetEyeHeight00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEyeHeight'", NULL); +#endif + { + double tolua_ret = (double) self->GetEyeHeight(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetEyeHeight'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetEyePosition of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetEyePosition00 +static int tolua_AllToLua_cPlayer_GetEyePosition00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEyePosition'", NULL); +#endif + { + Vector3d tolua_ret = (Vector3d) self->GetEyePosition(); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetEyePosition'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetFlying of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetFlying00 +static int tolua_AllToLua_cPlayer_GetFlying00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetFlying'", NULL); +#endif + { + bool tolua_ret = (bool) self->GetFlying(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetFlying'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetStance of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetStance00 +static int tolua_AllToLua_cPlayer_GetStance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetStance'", NULL); +#endif + { + const double tolua_ret = (const double) self->GetStance(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetStance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetInventory of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetInventory00 +static int tolua_AllToLua_cPlayer_GetInventory00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetInventory'", NULL); +#endif + { + cInventory& tolua_ret = (cInventory&) self->GetInventory(); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cInventory"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetInventory'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: TeleportTo of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_TeleportTo00 +static int tolua_AllToLua_cPlayer_TeleportTo00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0)); + const double a_PosY = ((const double) tolua_tonumber(tolua_S,3,0)); + const double a_PosZ = ((const double) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TeleportTo'", NULL); +#endif + { + self->TeleportTo(a_PosX,a_PosY,a_PosZ); + tolua_pushnumber(tolua_S,(lua_Number)a_PosX); + tolua_pushnumber(tolua_S,(lua_Number)a_PosY); + tolua_pushnumber(tolua_S,(lua_Number)a_PosZ); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'TeleportTo'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetGameMode of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetGameMode00 +static int tolua_AllToLua_cPlayer_GetGameMode00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetGameMode'", NULL); +#endif + { + eGameMode tolua_ret = (eGameMode) self->GetGameMode(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetGameMode'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetIP of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetIP00 +static int tolua_AllToLua_cPlayer_GetIP00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetIP'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->GetIP(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetIP'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetLastBlockActionTime of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetLastBlockActionTime00 +static int tolua_AllToLua_cPlayer_GetLastBlockActionTime00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLastBlockActionTime'", NULL); +#endif + { + float tolua_ret = (float) self->GetLastBlockActionTime(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetLastBlockActionTime'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetLastBlockActionCnt of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetLastBlockActionCnt00 +static int tolua_AllToLua_cPlayer_GetLastBlockActionCnt00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLastBlockActionCnt'", NULL); +#endif + { + int tolua_ret = (int) self->GetLastBlockActionCnt(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetLastBlockActionCnt'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetLastBlockActionCnt of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetLastBlockActionCnt00 +static int tolua_AllToLua_cPlayer_SetLastBlockActionCnt00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + int tolua_var_1 = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetLastBlockActionCnt'", NULL); +#endif + { + self->SetLastBlockActionCnt(tolua_var_1); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetLastBlockActionCnt'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetLastBlockActionTime of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetLastBlockActionTime00 +static int tolua_AllToLua_cPlayer_SetLastBlockActionTime00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetLastBlockActionTime'", NULL); +#endif + { + self->SetLastBlockActionTime(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetLastBlockActionTime'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetGameMode of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetGameMode00 +static int tolua_AllToLua_cPlayer_SetGameMode00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + eGameMode a_GameMode = ((eGameMode) (int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetGameMode'", NULL); +#endif + { + self->SetGameMode(a_GameMode); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetGameMode'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: MoveTo of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_MoveTo00 +static int tolua_AllToLua_cPlayer_MoveTo00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const Vector3d* a_NewPos = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'MoveTo'", NULL); +#endif + { + self->MoveTo(*a_NewPos); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'MoveTo'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetClientHandle of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetClientHandle00 +static int tolua_AllToLua_cPlayer_GetClientHandle00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetClientHandle'", NULL); +#endif + { + cClientHandle* tolua_ret = (cClientHandle*) self->GetClientHandle(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cClientHandle"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetClientHandle'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SendMessage of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SendMessage00 +static int tolua_AllToLua_cPlayer_SendMessage00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const char* a_Message = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendMessage'", NULL); +#endif + { + self->SendMessage(a_Message); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SendMessage'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetName of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetName00 +static int tolua_AllToLua_cPlayer_GetName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL); +#endif + { + const AString tolua_ret = (const AString) self->GetName(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetName of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetName00 +static int tolua_AllToLua_cPlayer_SetName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const AString a_Name = ((const AString) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetName'", NULL); +#endif + { + self->SetName(a_Name); + tolua_pushcppstring(tolua_S,(const char*)a_Name); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: AddToGroup of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_AddToGroup00 +static int tolua_AllToLua_cPlayer_AddToGroup00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const char* a_GroupName = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddToGroup'", NULL); +#endif + { + self->AddToGroup(a_GroupName); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'AddToGroup'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: CanUseCommand of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_CanUseCommand00 +static int tolua_AllToLua_cPlayer_CanUseCommand00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const char* a_Command = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CanUseCommand'", NULL); +#endif + { + bool tolua_ret = (bool) self->CanUseCommand(a_Command); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'CanUseCommand'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: HasPermission of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_HasPermission00 +static int tolua_AllToLua_cPlayer_HasPermission00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const char* a_Permission = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HasPermission'", NULL); +#endif + { + bool tolua_ret = (bool) self->HasPermission(a_Permission); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'HasPermission'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsInGroup of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_IsInGroup00 +static int tolua_AllToLua_cPlayer_IsInGroup00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const char* a_Group = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsInGroup'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsInGroup(a_Group); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsInGroup'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetColor of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetColor00 +static int tolua_AllToLua_cPlayer_GetColor00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetColor'", NULL); +#endif + { + AString tolua_ret = (AString) self->GetColor(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetColor'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: TossItem of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_TossItem00 +static int tolua_AllToLua_cPlayer_TossItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isboolean(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,1,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + bool a_bDraggingItem = ((bool) tolua_toboolean(tolua_S,2,0)); + int a_Amount = ((int) tolua_tonumber(tolua_S,3,1)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TossItem'", NULL); +#endif + { + self->TossItem(a_bDraggingItem,a_Amount); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'TossItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Heal of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_Heal00 +static int tolua_AllToLua_cPlayer_Heal00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + int a_Health = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Heal'", NULL); +#endif + { + self->Heal(a_Health); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Heal'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: TakeDamage of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_TakeDamage00 +static int tolua_AllToLua_cPlayer_TakeDamage00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + int a_Damage = ((int) tolua_tonumber(tolua_S,2,0)); + cEntity* a_Instigator = ((cEntity*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TakeDamage'", NULL); +#endif + { + self->TakeDamage(a_Damage,a_Instigator); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'TakeDamage'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: KilledBy of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_KilledBy00 +static int tolua_AllToLua_cPlayer_KilledBy00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + cEntity* a_Killer = ((cEntity*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KilledBy'", NULL); +#endif + { + self->KilledBy(a_Killer); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'KilledBy'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Respawn of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_Respawn00 +static int tolua_AllToLua_cPlayer_Respawn00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Respawn'", NULL); +#endif + { + self->Respawn(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Respawn'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetVisible of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetVisible00 +static int tolua_AllToLua_cPlayer_SetVisible00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isboolean(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + bool a_bVisible = ((bool) tolua_toboolean(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetVisible'", NULL); +#endif + { + self->SetVisible(a_bVisible); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetVisible'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsVisible of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_IsVisible00 +static int tolua_AllToLua_cPlayer_IsVisible00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsVisible'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsVisible(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsVisible'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: MoveToWorld of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_MoveToWorld00 +static int tolua_AllToLua_cPlayer_MoveToWorld00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const char* a_WorldName = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'MoveToWorld'", NULL); +#endif + { + bool tolua_ret = (bool) self->MoveToWorld(a_WorldName); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'MoveToWorld'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: LoadPermissionsFromDisk of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_LoadPermissionsFromDisk00 +static int tolua_AllToLua_cPlayer_LoadPermissionsFromDisk00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'LoadPermissionsFromDisk'", NULL); +#endif + { + self->LoadPermissionsFromDisk(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'LoadPermissionsFromDisk'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + class Lua__cPlayer : public cPlayer, public ToluaBase { +public: + void Initialize( cWorld* a_World) { + if (push_method("Initialize", tolua_AllToLua_cPlayer_Initialize00)) { + tolua_pushusertype(lua_state, (void*)a_World, "cWorld"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPlayer:: Initialize(a_World); + }; + }; + void TeleportTo( const double& a_PosX, const double& a_PosY, const double& a_PosZ) { + if (push_method("TeleportTo", tolua_AllToLua_cPlayer_TeleportTo00)) { + tolua_pushnumber(lua_state, (lua_Number)a_PosX); + tolua_pushnumber(lua_state, (lua_Number)a_PosY); + tolua_pushnumber(lua_state, (lua_Number)a_PosZ); + ToluaBase::dbcall(lua_state, 4, 0); + } else { + return ( void ) cPlayer:: TeleportTo(a_PosX,a_PosY,a_PosZ); + }; + }; + void MoveTo( const Vector3d& a_NewPos) { + if (push_method("MoveTo", tolua_AllToLua_cPlayer_MoveTo00)) { + tolua_pushusertype(lua_state, (void*)&a_NewPos, "const Vector3d"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPlayer:: MoveTo(a_NewPos); + }; + }; + void TeleportToEntity( cEntity* a_Entity) { + if (push_method("TeleportToEntity", tolua_AllToLua_cPawn_TeleportToEntity00)) { + tolua_pushusertype(lua_state, (void*)a_Entity, "cEntity"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPlayer:: TeleportToEntity(a_Entity); + }; + }; + void TakeDamage( int a_Damage, cEntity* a_Instigator) { + if (push_method("TakeDamage", tolua_AllToLua_cPawn_TakeDamage00)) { + tolua_pushnumber(lua_state, (lua_Number)a_Damage); + tolua_pushusertype(lua_state, (void*)a_Instigator, "cEntity"); + ToluaBase::dbcall(lua_state, 3, 0); + } else { + return ( void ) cPlayer:: TakeDamage(a_Damage,a_Instigator); + }; + }; + void KilledBy( cEntity* a_Killer) { + if (push_method("KilledBy", tolua_AllToLua_cPawn_KilledBy00)) { + tolua_pushusertype(lua_state, (void*)a_Killer, "cEntity"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPlayer:: KilledBy(a_Killer); + }; + }; + unsigned int GetEntityType( void ) { + if (push_method("GetEntityType", tolua_AllToLua_cEntity_GetEntityType00)) { + ToluaBase::dbcall(lua_state, 1, 1); + unsigned int tolua_ret = (unsigned int )tolua_tonumber(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return (unsigned int ) cPlayer:: GetEntityType(); + }; + }; + bool IsA( const char* a_EntityType) { + if (push_method("IsA", tolua_AllToLua_cEntity_IsA00)) { + tolua_pushstring(lua_state, (const char*)a_EntityType); + ToluaBase::dbcall(lua_state, 2, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlayer:: IsA(a_EntityType); + }; + }; + const char* GetClass( void ) { + if (push_method("GetClass", tolua_AllToLua_cEntity_GetClass00)) { + ToluaBase::dbcall(lua_state, 1, 1); + const char* tolua_ret = ( const char* )tolua_tostring(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( const char* ) cPlayer:: GetClass(); + }; + }; + void Tick( float a_Dt) { + if (push_method("Tick", tolua_AllToLua_cEntity_Tick00)) { + tolua_pushnumber(lua_state, (lua_Number)a_Dt); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + if (lua_state) + LOG("pure-virtual method cPlayer::Tick not implemented."); + else { + LOG("pure-virtual method cPlayer::Tick called with no lua_state. Aborting"); + ::abort(); + }; + return ( void )0; + }; + }; + + void cPlayer__Initialize( cWorld* a_World) { + return ( void )cPlayer::Initialize(a_World); + }; + void cPlayer__TeleportTo( const double& a_PosX, const double& a_PosY, const double& a_PosZ) { + return ( void )cPlayer::TeleportTo(a_PosX,a_PosY,a_PosZ); + }; + void cPlayer__MoveTo( const Vector3d& a_NewPos) { + return ( void )cPlayer::MoveTo(a_NewPos); + }; + void cPlayer__TeleportToEntity( cEntity* a_Entity) { + return ( void )cPlayer::TeleportToEntity(a_Entity); + }; + void cPlayer__TakeDamage( int a_Damage, cEntity* a_Instigator) { + return ( void )cPlayer::TakeDamage(a_Damage,a_Instigator); + }; + void cPlayer__KilledBy( cEntity* a_Killer) { + return ( void )cPlayer::KilledBy(a_Killer); + }; + unsigned int cPlayer__GetEntityType( void ) { + return (unsigned int )cPlayer::GetEntityType(); + }; + bool cPlayer__IsA( const char* a_EntityType) { + return ( bool )cPlayer::IsA(a_EntityType); + }; + const char* cPlayer__GetClass( void ) { + return ( const char* )cPlayer::GetClass(); + }; +}; + +/* method: tolua__set_instance of class Lua__cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlayer_tolua__set_instance00 +static int tolua_AllToLua_Lua__cPlayer_tolua__set_instance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlayer* self = (Lua__cPlayer*) tolua_tousertype(tolua_S,1,0); + lua_State* L = tolua_S; + lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); +#endif + { + self->tolua__set_instance(L,lo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlayer__Initialize of class Lua__cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlayer_cPlayer__Initialize00 +static int tolua_AllToLua_Lua__cPlayer_cPlayer__Initialize00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlayer* self = (Lua__cPlayer*) tolua_tousertype(tolua_S,1,0); + cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlayer__Initialize'", NULL); +#endif + { + self->cPlayer__Initialize(a_World); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlayer__Initialize'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlayer__TeleportTo of class Lua__cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlayer_cPlayer__TeleportTo00 +static int tolua_AllToLua_Lua__cPlayer_cPlayer__TeleportTo00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlayer",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlayer* self = (Lua__cPlayer*) tolua_tousertype(tolua_S,1,0); + const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0)); + const double a_PosY = ((const double) tolua_tonumber(tolua_S,3,0)); + const double a_PosZ = ((const double) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlayer__TeleportTo'", NULL); +#endif + { + self->cPlayer__TeleportTo(a_PosX,a_PosY,a_PosZ); + tolua_pushnumber(tolua_S,(lua_Number)a_PosX); + tolua_pushnumber(tolua_S,(lua_Number)a_PosY); + tolua_pushnumber(tolua_S,(lua_Number)a_PosZ); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlayer__TeleportTo'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlayer__MoveTo of class Lua__cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlayer_cPlayer__MoveTo00 +static int tolua_AllToLua_Lua__cPlayer_cPlayer__MoveTo00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlayer",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlayer* self = (Lua__cPlayer*) tolua_tousertype(tolua_S,1,0); + const Vector3d* a_NewPos = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlayer__MoveTo'", NULL); +#endif + { + self->cPlayer__MoveTo(*a_NewPos); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlayer__MoveTo'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPluginManager of class cPluginManager */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_GetPluginManager00 +static int tolua_AllToLua_cPluginManager_GetPluginManager00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cPluginManager",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + cPluginManager* tolua_ret = (cPluginManager*) cPluginManager::GetPluginManager(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPluginManager"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPluginManager'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPlugin of class cPluginManager */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_GetPlugin00 +static int tolua_AllToLua_cPluginManager_GetPlugin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cPluginManager",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cPluginManager* self = (const cPluginManager*) tolua_tousertype(tolua_S,1,0); + const char* a_Plugin = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPlugin'", NULL); +#endif + { + cPlugin* tolua_ret = (cPlugin*) self->GetPlugin(a_Plugin); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPlugin"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPlugin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: ReloadPlugins of class cPluginManager */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_ReloadPlugins00 +static int tolua_AllToLua_cPluginManager_ReloadPlugins00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ReloadPlugins'", NULL); +#endif + { + self->ReloadPlugins(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'ReloadPlugins'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: AddPlugin of class cPluginManager */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_AddPlugin00 +static int tolua_AllToLua_cPluginManager_AddPlugin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); + lua_State* a_LuaState = tolua_S; + cPlugin* a_Plugin = ((cPlugin*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddPlugin'", NULL); +#endif + { + bool tolua_ret = (bool) self->AddPlugin(a_LuaState,a_Plugin); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'AddPlugin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: AddHook of class cPluginManager */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_AddHook00 +static int tolua_AllToLua_cPluginManager_AddHook00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlugin",0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); + cPlugin* a_Plugin = ((cPlugin*) tolua_tousertype(tolua_S,2,0)); + cPluginManager::PluginHook a_Hook = ((cPluginManager::PluginHook) (int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddHook'", NULL); +#endif + { + self->AddHook(a_Plugin,a_Hook); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'AddHook'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetNumPlugins of class cPluginManager */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_GetNumPlugins00 +static int tolua_AllToLua_cPluginManager_GetNumPlugins00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cPluginManager",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cPluginManager* self = (const cPluginManager*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumPlugins'", NULL); +#endif + { + unsigned int tolua_ret = (unsigned int) self->GetNumPlugins(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetNumPlugins'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: RemovePlugin of class cPluginManager */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_RemovePlugin00 +static int tolua_AllToLua_cPluginManager_RemovePlugin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlugin",0,&tolua_err) || + !tolua_isboolean(tolua_S,3,1,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); + cPlugin* a_Plugin = ((cPlugin*) tolua_tousertype(tolua_S,2,0)); + bool a_bDelete = ((bool) tolua_toboolean(tolua_S,3,false)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'RemovePlugin'", NULL); +#endif + { + self->RemovePlugin(a_Plugin,a_bDelete); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'RemovePlugin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: RemoveLuaPlugin of class cPluginManager */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_RemoveLuaPlugin00 +static int tolua_AllToLua_cPluginManager_RemoveLuaPlugin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); + std::string a_FileName = ((std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'RemoveLuaPlugin'", NULL); +#endif + { + self->RemoveLuaPlugin(a_FileName); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'RemoveLuaPlugin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetLuaPlugin of class cPluginManager */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_GetLuaPlugin00 +static int tolua_AllToLua_cPluginManager_GetLuaPlugin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); + lua_State* a_State = tolua_S; +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLuaPlugin'", NULL); +#endif + { + cPlugin_Lua* tolua_ret = (cPlugin_Lua*) self->GetLuaPlugin(a_State); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPlugin_Lua"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetLuaPlugin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_delete00 +static int tolua_AllToLua_cPlugin_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnDisable of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnDisable00 +static int tolua_AllToLua_cPlugin_OnDisable00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnDisable'", NULL); +#endif + { + self->OnDisable(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnDisable'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Initialize of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_Initialize00 +static int tolua_AllToLua_cPlugin_Initialize00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL); +#endif + { + bool tolua_ret = (bool) self->Initialize(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Tick of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_Tick00 +static int tolua_AllToLua_cPlugin_Tick00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + float a_Dt = ((float) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Tick'", NULL); +#endif + { + self->Tick(a_Dt); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Tick'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnCollectItem of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnCollectItem00 +static int tolua_AllToLua_cPlugin_OnCollectItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPickup",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cPickup* a_Pickup = ((cPickup*) tolua_tousertype(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnCollectItem'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnCollectItem(a_Pickup,a_Player); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnCollectItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnDisconnect of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnDisconnect00 +static int tolua_AllToLua_cPlugin_OnDisconnect00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnDisconnect'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnDisconnect(a_Reason,a_Player); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)a_Reason); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnDisconnect'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnBlockPlace of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnBlockPlace00 +static int tolua_AllToLua_cPlugin_OnBlockPlace00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPacket_BlockPlace",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cPacket_BlockPlace* a_PacketData = ((cPacket_BlockPlace*) tolua_tousertype(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnBlockPlace'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnBlockPlace(a_PacketData,a_Player); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnBlockPlace'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnBlockDig of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnBlockDig00 +static int tolua_AllToLua_cPlugin_OnBlockDig00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPacket_BlockDig",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,4,"cItem",0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cPacket_BlockDig* a_PacketData = ((cPacket_BlockDig*) tolua_tousertype(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); + cItem* a_PickupItem = ((cItem*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnBlockDig'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnBlockDig(a_PacketData,a_Player,a_PickupItem); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnBlockDig'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnChat of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnChat00 +static int tolua_AllToLua_cPlugin_OnChat00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + const char* a_Chat = ((const char*) tolua_tostring(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnChat'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnChat(a_Chat,a_Player); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnChat'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnLogin of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnLogin00 +static int tolua_AllToLua_cPlugin_OnLogin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPacket_Login",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cPacket_Login* a_PacketData = ((cPacket_Login*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnLogin'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnLogin(a_PacketData); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnLogin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnPlayerSpawn of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnPlayerSpawn00 +static int tolua_AllToLua_cPlugin_OnPlayerSpawn00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnPlayerSpawn'", NULL); +#endif + { + self->OnPlayerSpawn(a_Player); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnPlayerSpawn'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnPlayerJoin of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnPlayerJoin00 +static int tolua_AllToLua_cPlugin_OnPlayerJoin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnPlayerJoin'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnPlayerJoin(a_Player); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnPlayerJoin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnPlayerMove of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnPlayerMove00 +static int tolua_AllToLua_cPlugin_OnPlayerMove00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnPlayerMove'", NULL); +#endif + { + self->OnPlayerMove(a_Player); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnPlayerMove'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnTakeDamage of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnTakeDamage00 +static int tolua_AllToLua_cPlugin_OnTakeDamage00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPawn",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"TakeDamageInfo",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cPawn* a_Pawn = ((cPawn*) tolua_tousertype(tolua_S,2,0)); + TakeDamageInfo* a_TakeDamageInfo = ((TakeDamageInfo*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnTakeDamage'", NULL); +#endif + { + self->OnTakeDamage(a_Pawn,a_TakeDamageInfo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnTakeDamage'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnKilled of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnKilled00 +static int tolua_AllToLua_cPlugin_OnKilled00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPawn",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cPawn* a_Killed = ((cPawn*) tolua_tousertype(tolua_S,2,0)); + cEntity* a_Killer = ((cEntity*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnKilled'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnKilled(a_Killed,a_Killer); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnKilled'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnChunkGenerated of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnChunkGenerated00 +static int tolua_AllToLua_cPlugin_OnChunkGenerated00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); + int a_ChunkX = ((int) tolua_tonumber(tolua_S,3,0)); + int a_ChunkZ = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnChunkGenerated'", NULL); +#endif + { + self->OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnChunkGenerated'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnChunkGenerating of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnChunkGenerating00 +static int tolua_AllToLua_cPlugin_OnChunkGenerating00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isusertype(tolua_S,4,"cLuaChunk",0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + int a_ChunkX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_ChunkZ = ((int) tolua_tonumber(tolua_S,3,0)); + cLuaChunk* a_pLuaChunk = ((cLuaChunk*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnChunkGenerating'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnChunkGenerating'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnPreCrafting of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnPreCrafting00 +static int tolua_AllToLua_cPlugin_OnPreCrafting00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) || + !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0)); + const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0)); + cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnPreCrafting'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnPreCrafting(a_Player,a_Grid,a_Recipe); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnPreCrafting'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnCraftingNoRecipe of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnCraftingNoRecipe00 +static int tolua_AllToLua_cPlugin_OnCraftingNoRecipe00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) || + !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0)); + const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0)); + cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnCraftingNoRecipe'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnCraftingNoRecipe'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnPostCrafting of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnPostCrafting00 +static int tolua_AllToLua_cPlugin_OnPostCrafting00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) || + !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0)); + const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0)); + cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnPostCrafting'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnPostCrafting(a_Player,a_Grid,a_Recipe); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnPostCrafting'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnBlockToPickup of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnBlockToPickup00 +static int tolua_AllToLua_cPlugin_OnBlockToPickup00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"BLOCKTYPE",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"NIBBLETYPE",0,&tolua_err)) || + !tolua_isusertype(tolua_S,4,"const cPlayer",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"const cItem",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,6,&tolua_err) || !tolua_isusertype(tolua_S,6,"cItems",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,7,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + BLOCKTYPE a_BlockType = *((BLOCKTYPE*) tolua_tousertype(tolua_S,2,0)); + NIBBLETYPE a_BlockMeta = *((NIBBLETYPE*) tolua_tousertype(tolua_S,3,0)); + const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,4,0)); + const cItem* a_EquippedItem = ((const cItem*) tolua_tousertype(tolua_S,5,0)); + cItems* a_Pickups = ((cItems*) tolua_tousertype(tolua_S,6,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnBlockToPickup'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,*a_EquippedItem,*a_Pickups); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnBlockToPickup'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetName of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_GetName00 +static int tolua_AllToLua_cPlugin_GetName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cPlugin* self = (const cPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL); +#endif + { + const char* tolua_ret = (const char*) self->GetName(); + tolua_pushstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetName of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_SetName00 +static int tolua_AllToLua_cPlugin_SetName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + const char* a_Name = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetName'", NULL); +#endif + { + self->SetName(a_Name); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetVersion of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_GetVersion00 +static int tolua_AllToLua_cPlugin_GetVersion00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cPlugin* self = (const cPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetVersion'", NULL); +#endif + { + int tolua_ret = (int) self->GetVersion(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetVersion'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetVersion of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_SetVersion00 +static int tolua_AllToLua_cPlugin_SetVersion00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + int a_Version = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetVersion'", NULL); +#endif + { + self->SetVersion(a_Version); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetVersion'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Command of class CommandStruct */ +#ifndef TOLUA_DISABLE_tolua_get_cPlugin__CommandStruct_Command +static int tolua_get_cPlugin__CommandStruct_Command(lua_State* tolua_S) +{ + cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Command'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Command); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Command of class CommandStruct */ +#ifndef TOLUA_DISABLE_tolua_set_cPlugin__CommandStruct_Command +static int tolua_set_cPlugin__CommandStruct_Command(lua_State* tolua_S) +{ + cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Command'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Command = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Description of class CommandStruct */ +#ifndef TOLUA_DISABLE_tolua_get_cPlugin__CommandStruct_Description +static int tolua_get_cPlugin__CommandStruct_Description(lua_State* tolua_S) +{ + cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Description'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Description); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Description of class CommandStruct */ +#ifndef TOLUA_DISABLE_tolua_set_cPlugin__CommandStruct_Description +static int tolua_set_cPlugin__CommandStruct_Description(lua_State* tolua_S) +{ + cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Description'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Description = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Permission of class CommandStruct */ +#ifndef TOLUA_DISABLE_tolua_get_cPlugin__CommandStruct_Permission +static int tolua_get_cPlugin__CommandStruct_Permission(lua_State* tolua_S) +{ + cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Permission'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Permission); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Permission of class CommandStruct */ +#ifndef TOLUA_DISABLE_tolua_set_cPlugin__CommandStruct_Permission +static int tolua_set_cPlugin__CommandStruct_Permission(lua_State* tolua_S) +{ + cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Permission'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Permission = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: AddCommand of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_AddCommand00 +static int tolua_AllToLua_cPlugin_AddCommand00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_iscppstring(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + std::string a_Command = ((std::string) tolua_tocppstring(tolua_S,2,0)); + std::string a_Description = ((std::string) tolua_tocppstring(tolua_S,3,0)); + std::string a_Permission = ((std::string) tolua_tocppstring(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddCommand'", NULL); +#endif + { + self->AddCommand(a_Command,a_Description,a_Permission); + tolua_pushcppstring(tolua_S,(const char*)a_Command); + tolua_pushcppstring(tolua_S,(const char*)a_Description); + tolua_pushcppstring(tolua_S,(const char*)a_Permission); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'AddCommand'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + class Lua__cPlugin : public cPlugin, public ToluaBase { +public: + void OnDisable( void ) { + if (push_method("OnDisable", tolua_AllToLua_cPlugin_OnDisable00)) { + ToluaBase::dbcall(lua_state, 1, 0); + } else { + return ( void ) cPlugin:: OnDisable(); + }; + }; + bool Initialize( void ) { + if (push_method("Initialize", tolua_AllToLua_cPlugin_Initialize00)) { + ToluaBase::dbcall(lua_state, 1, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + if (lua_state) + LOG("pure-virtual method cPlugin::Initialize not implemented."); + else { + LOG("pure-virtual method cPlugin::Initialize called with no lua_state. Aborting"); + ::abort(); + }; + return ( bool )0; + }; + }; + void Tick( float a_Dt) { + if (push_method("Tick", tolua_AllToLua_cPlugin_Tick00)) { + tolua_pushnumber(lua_state, (lua_Number)a_Dt); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPlugin:: Tick(a_Dt); + }; + }; + bool OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player) { + if (push_method("OnCollectItem", tolua_AllToLua_cPlugin_OnCollectItem00)) { + tolua_pushusertype(lua_state, (void*)a_Pickup, "cPickup"); + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 3, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnCollectItem(a_Pickup,a_Player); + }; + }; + bool OnDisconnect( const AString& a_Reason, cPlayer* a_Player) { + if (push_method("OnDisconnect", tolua_AllToLua_cPlugin_OnDisconnect00)) { + tolua_pushcppstring(lua_state, (const char*)a_Reason); + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 3, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnDisconnect(a_Reason,a_Player); + }; + }; + bool OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player) { + if (push_method("OnBlockPlace", tolua_AllToLua_cPlugin_OnBlockPlace00)) { + tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_BlockPlace"); + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 3, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnBlockPlace(a_PacketData,a_Player); + }; + }; + bool OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem) { + if (push_method("OnBlockDig", tolua_AllToLua_cPlugin_OnBlockDig00)) { + tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_BlockDig"); + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + tolua_pushusertype(lua_state, (void*)a_PickupItem, "cItem"); + ToluaBase::dbcall(lua_state, 4, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnBlockDig(a_PacketData,a_Player,a_PickupItem); + }; + }; + bool OnChat( const char* a_Chat, cPlayer* a_Player) { + if (push_method("OnChat", tolua_AllToLua_cPlugin_OnChat00)) { + tolua_pushstring(lua_state, (const char*)a_Chat); + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 3, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnChat(a_Chat,a_Player); + }; + }; + bool OnLogin( cPacket_Login* a_PacketData) { + if (push_method("OnLogin", tolua_AllToLua_cPlugin_OnLogin00)) { + tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_Login"); + ToluaBase::dbcall(lua_state, 2, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnLogin(a_PacketData); + }; + }; + void OnPlayerSpawn( cPlayer* a_Player) { + if (push_method("OnPlayerSpawn", tolua_AllToLua_cPlugin_OnPlayerSpawn00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPlugin:: OnPlayerSpawn(a_Player); + }; + }; + bool OnPlayerJoin( cPlayer* a_Player) { + if (push_method("OnPlayerJoin", tolua_AllToLua_cPlugin_OnPlayerJoin00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 2, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnPlayerJoin(a_Player); + }; + }; + void OnPlayerMove( cPlayer* a_Player) { + if (push_method("OnPlayerMove", tolua_AllToLua_cPlugin_OnPlayerMove00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPlugin:: OnPlayerMove(a_Player); + }; + }; + void OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo) { + if (push_method("OnTakeDamage", tolua_AllToLua_cPlugin_OnTakeDamage00)) { + tolua_pushusertype(lua_state, (void*)a_Pawn, "cPawn"); + tolua_pushusertype(lua_state, (void*)a_TakeDamageInfo, "TakeDamageInfo"); + ToluaBase::dbcall(lua_state, 3, 0); + } else { + return ( void ) cPlugin:: OnTakeDamage(a_Pawn,a_TakeDamageInfo); + }; + }; + bool OnKilled( cPawn* a_Killed, cEntity* a_Killer) { + if (push_method("OnKilled", tolua_AllToLua_cPlugin_OnKilled00)) { + tolua_pushusertype(lua_state, (void*)a_Killed, "cPawn"); + tolua_pushusertype(lua_state, (void*)a_Killer, "cEntity"); + ToluaBase::dbcall(lua_state, 3, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnKilled(a_Killed,a_Killer); + }; + }; + void OnChunkGenerated( cWorld* a_World, int a_ChunkX, int a_ChunkZ) { + if (push_method("OnChunkGenerated", tolua_AllToLua_cPlugin_OnChunkGenerated00)) { + tolua_pushusertype(lua_state, (void*)a_World, "cWorld"); + tolua_pushnumber(lua_state, (lua_Number)a_ChunkX); + tolua_pushnumber(lua_state, (lua_Number)a_ChunkZ); + ToluaBase::dbcall(lua_state, 4, 0); + } else { + return ( void ) cPlugin:: OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ); + }; + }; + bool OnChunkGenerating( int a_ChunkX, int a_ChunkZ, cLuaChunk* a_pLuaChunk) { + if (push_method("OnChunkGenerating", tolua_AllToLua_cPlugin_OnChunkGenerating00)) { + tolua_pushnumber(lua_state, (lua_Number)a_ChunkX); + tolua_pushnumber(lua_state, (lua_Number)a_ChunkZ); + tolua_pushusertype(lua_state, (void*)a_pLuaChunk, "cLuaChunk"); + ToluaBase::dbcall(lua_state, 4, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk); + }; + }; + bool OnPreCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + if (push_method("OnPreCrafting", tolua_AllToLua_cPlugin_OnPreCrafting00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); + tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid"); + tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe"); + ToluaBase::dbcall(lua_state, 4, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnPreCrafting(a_Player,a_Grid,a_Recipe); + }; + }; + bool OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + if (push_method("OnCraftingNoRecipe", tolua_AllToLua_cPlugin_OnCraftingNoRecipe00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); + tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid"); + tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe"); + ToluaBase::dbcall(lua_state, 4, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); + }; + }; + bool OnPostCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + if (push_method("OnPostCrafting", tolua_AllToLua_cPlugin_OnPostCrafting00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); + tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid"); + tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe"); + ToluaBase::dbcall(lua_state, 4, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnPostCrafting(a_Player,a_Grid,a_Recipe); + }; + }; + bool OnBlockToPickup( BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer* a_Player, const cItem& a_EquippedItem, cItems& a_Pickups) { + if (push_method("OnBlockToPickup", tolua_AllToLua_cPlugin_OnBlockToPickup00)) { + void* tolua_obj0 = (void*)new BLOCKTYPE(a_BlockType); + tolua_pushusertype_and_takeownership(lua_state, tolua_obj0, "BLOCKTYPE"); + void* tolua_obj1 = (void*)new NIBBLETYPE(a_BlockMeta); + tolua_pushusertype_and_takeownership(lua_state, tolua_obj1, "NIBBLETYPE"); + tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); + tolua_pushusertype(lua_state, (void*)&a_EquippedItem, "const cItem"); + tolua_pushusertype(lua_state, (void*)&a_Pickups, "cItems"); + ToluaBase::dbcall(lua_state, 6, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,a_EquippedItem,a_Pickups); + }; + }; + + void cPlugin__OnDisable( void ) { + return ( void )cPlugin::OnDisable(); + }; + void cPlugin__Tick( float a_Dt) { + return ( void )cPlugin::Tick(a_Dt); + }; + bool cPlugin__OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player) { + return ( bool )cPlugin::OnCollectItem(a_Pickup,a_Player); + }; + bool cPlugin__OnDisconnect( const AString& a_Reason, cPlayer* a_Player) { + return ( bool )cPlugin::OnDisconnect(a_Reason,a_Player); + }; + bool cPlugin__OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player) { + return ( bool )cPlugin::OnBlockPlace(a_PacketData,a_Player); + }; + bool cPlugin__OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem) { + return ( bool )cPlugin::OnBlockDig(a_PacketData,a_Player,a_PickupItem); + }; + bool cPlugin__OnChat( const char* a_Chat, cPlayer* a_Player) { + return ( bool )cPlugin::OnChat(a_Chat,a_Player); + }; + bool cPlugin__OnLogin( cPacket_Login* a_PacketData) { + return ( bool )cPlugin::OnLogin(a_PacketData); + }; + void cPlugin__OnPlayerSpawn( cPlayer* a_Player) { + return ( void )cPlugin::OnPlayerSpawn(a_Player); + }; + bool cPlugin__OnPlayerJoin( cPlayer* a_Player) { + return ( bool )cPlugin::OnPlayerJoin(a_Player); + }; + void cPlugin__OnPlayerMove( cPlayer* a_Player) { + return ( void )cPlugin::OnPlayerMove(a_Player); + }; + void cPlugin__OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo) { + return ( void )cPlugin::OnTakeDamage(a_Pawn,a_TakeDamageInfo); + }; + bool cPlugin__OnKilled( cPawn* a_Killed, cEntity* a_Killer) { + return ( bool )cPlugin::OnKilled(a_Killed,a_Killer); + }; + void cPlugin__OnChunkGenerated( cWorld* a_World, int a_ChunkX, int a_ChunkZ) { + return ( void )cPlugin::OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ); + }; + bool cPlugin__OnChunkGenerating( int a_ChunkX, int a_ChunkZ, cLuaChunk* a_pLuaChunk) { + return ( bool )cPlugin::OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk); + }; + bool cPlugin__OnPreCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + return ( bool )cPlugin::OnPreCrafting(a_Player,a_Grid,a_Recipe); + }; + bool cPlugin__OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + return ( bool )cPlugin::OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); + }; + bool cPlugin__OnPostCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + return ( bool )cPlugin::OnPostCrafting(a_Player,a_Grid,a_Recipe); + }; + bool cPlugin__OnBlockToPickup( BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer* a_Player, const cItem& a_EquippedItem, cItems& a_Pickups) { + return ( bool )cPlugin::OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,a_EquippedItem,a_Pickups); + }; + Lua__cPlugin( void ): cPlugin(){}; +}; + +/* method: tolua__set_instance of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_tolua__set_instance00 +static int tolua_AllToLua_Lua__cPlugin_tolua__set_instance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + lua_State* L = tolua_S; + lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); +#endif + { + self->tolua__set_instance(L,lo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnDisable of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisable00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisable00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnDisable'", NULL); +#endif + { + self->cPlugin__OnDisable(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnDisable'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__Tick of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__Tick00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__Tick00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + float a_Dt = ((float) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__Tick'", NULL); +#endif + { + self->cPlugin__Tick(a_Dt); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__Tick'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnCollectItem of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnCollectItem00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnCollectItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPickup",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + cPickup* a_Pickup = ((cPickup*) tolua_tousertype(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnCollectItem'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnCollectItem(a_Pickup,a_Player); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnCollectItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnDisconnect of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisconnect00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisconnect00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnDisconnect'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnDisconnect(a_Reason,a_Player); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)a_Reason); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnDisconnect'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnBlockPlace of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockPlace00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockPlace00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPacket_BlockPlace",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + cPacket_BlockPlace* a_PacketData = ((cPacket_BlockPlace*) tolua_tousertype(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnBlockPlace'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnBlockPlace(a_PacketData,a_Player); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnBlockPlace'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnBlockDig of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockDig00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockDig00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPacket_BlockDig",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,4,"cItem",0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + cPacket_BlockDig* a_PacketData = ((cPacket_BlockDig*) tolua_tousertype(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); + cItem* a_PickupItem = ((cItem*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnBlockDig'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnBlockDig(a_PacketData,a_Player,a_PickupItem); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnBlockDig'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnChat of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnChat00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnChat00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + const char* a_Chat = ((const char*) tolua_tostring(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnChat'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnChat(a_Chat,a_Player); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnChat'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnLogin of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnLogin00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnLogin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPacket_Login",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + cPacket_Login* a_PacketData = ((cPacket_Login*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnLogin'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnLogin(a_PacketData); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnLogin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnPlayerSpawn of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerSpawn00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerSpawn00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnPlayerSpawn'", NULL); +#endif + { + self->cPlugin__OnPlayerSpawn(a_Player); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnPlayerSpawn'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnPlayerJoin of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerJoin00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerJoin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnPlayerJoin'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnPlayerJoin(a_Player); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnPlayerJoin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnPlayerMove of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerMove00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerMove00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnPlayerMove'", NULL); +#endif + { + self->cPlugin__OnPlayerMove(a_Player); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnPlayerMove'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnTakeDamage of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnTakeDamage00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnTakeDamage00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPawn",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"TakeDamageInfo",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + cPawn* a_Pawn = ((cPawn*) tolua_tousertype(tolua_S,2,0)); + TakeDamageInfo* a_TakeDamageInfo = ((TakeDamageInfo*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnTakeDamage'", NULL); +#endif + { + self->cPlugin__OnTakeDamage(a_Pawn,a_TakeDamageInfo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnTakeDamage'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnKilled of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnKilled00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnKilled00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPawn",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + cPawn* a_Killed = ((cPawn*) tolua_tousertype(tolua_S,2,0)); + cEntity* a_Killer = ((cEntity*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnKilled'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnKilled(a_Killed,a_Killer); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnKilled'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnChunkGenerated of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerated00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerated00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); + int a_ChunkX = ((int) tolua_tonumber(tolua_S,3,0)); + int a_ChunkZ = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnChunkGenerated'", NULL); +#endif + { + self->cPlugin__OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnChunkGenerated'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnChunkGenerating of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerating00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerating00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isusertype(tolua_S,4,"cLuaChunk",0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + int a_ChunkX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_ChunkZ = ((int) tolua_tonumber(tolua_S,3,0)); + cLuaChunk* a_pLuaChunk = ((cLuaChunk*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnChunkGenerating'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnChunkGenerating'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnPreCrafting of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnPreCrafting00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnPreCrafting00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) || + !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0)); + const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0)); + cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnPreCrafting'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnPreCrafting(a_Player,a_Grid,a_Recipe); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnPreCrafting'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnCraftingNoRecipe of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnCraftingNoRecipe00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnCraftingNoRecipe00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) || + !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0)); + const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0)); + cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnCraftingNoRecipe'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnCraftingNoRecipe'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnPostCrafting of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnPostCrafting00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnPostCrafting00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) || + !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0)); + const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0)); + cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnPostCrafting'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnPostCrafting(a_Player,a_Grid,a_Recipe); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnPostCrafting'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnBlockToPickup of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockToPickup00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockToPickup00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"BLOCKTYPE",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"NIBBLETYPE",0,&tolua_err)) || + !tolua_isusertype(tolua_S,4,"const cPlayer",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"const cItem",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,6,&tolua_err) || !tolua_isusertype(tolua_S,6,"cItems",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,7,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + BLOCKTYPE a_BlockType = *((BLOCKTYPE*) tolua_tousertype(tolua_S,2,0)); + NIBBLETYPE a_BlockMeta = *((NIBBLETYPE*) tolua_tousertype(tolua_S,3,0)); + const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,4,0)); + const cItem* a_EquippedItem = ((const cItem*) tolua_tousertype(tolua_S,5,0)); + cItems* a_Pickups = ((cItems*) tolua_tousertype(tolua_S,6,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnBlockToPickup'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,*a_EquippedItem,*a_Pickups); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnBlockToPickup'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_new00 +static int tolua_AllToLua_Lua__cPlugin_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + Lua__cPlugin* tolua_ret = (Lua__cPlugin*) Mtolua_new((Lua__cPlugin)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPlugin"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_new00_local +static int tolua_AllToLua_Lua__cPlugin_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + Lua__cPlugin* tolua_ret = (Lua__cPlugin*) Mtolua_new((Lua__cPlugin)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPlugin"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_delete00 +static int tolua_AllToLua_Lua__cPlugin_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + +/* function to release collected object via destructor */ +#ifdef __cplusplus + +static int tolua_collect_Lua__cPlugin (lua_State* tolua_S) +{ + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + delete self; + return 0; +} +#endif + +/* method: OnDisable of class cPlugin_NewLua */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_NewLua_OnDisable00 +static int tolua_AllToLua_cPlugin_NewLua_OnDisable00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin_NewLua",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin_NewLua* self = (cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnDisable'", NULL); +#endif + { + self->OnDisable(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnDisable'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Initialize of class cPlugin_NewLua */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_NewLua_Initialize00 +static int tolua_AllToLua_cPlugin_NewLua_Initialize00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin_NewLua",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin_NewLua* self = (cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL); +#endif + { + bool tolua_ret = (bool) self->Initialize(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Tick of class cPlugin_NewLua */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_NewLua_Tick00 +static int tolua_AllToLua_cPlugin_NewLua_Tick00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin_NewLua",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin_NewLua* self = (cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); + float a_Dt = ((float) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Tick'", NULL); +#endif + { + self->Tick(a_Dt); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Tick'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: CreateWebPlugin of class cPlugin_NewLua */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_NewLua_CreateWebPlugin00 +static int tolua_AllToLua_cPlugin_NewLua_CreateWebPlugin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin_NewLua",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin_NewLua* self = (cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); + lua_State* a_LuaState = tolua_S; +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CreateWebPlugin'", NULL); +#endif + { + cWebPlugin_Lua* tolua_ret = (cWebPlugin_Lua*) self->CreateWebPlugin(a_LuaState); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWebPlugin_Lua"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'CreateWebPlugin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + class Lua__cPlugin_NewLua : public cPlugin_NewLua, public ToluaBase { +public: + void OnDisable( void ) { + if (push_method("OnDisable", tolua_AllToLua_cPlugin_NewLua_OnDisable00)) { + ToluaBase::dbcall(lua_state, 1, 0); + } else { + return ( void ) cPlugin_NewLua:: OnDisable(); + }; + }; + bool Initialize( void ) { + if (push_method("Initialize", tolua_AllToLua_cPlugin_NewLua_Initialize00)) { + ToluaBase::dbcall(lua_state, 1, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: Initialize(); + }; + }; + void Tick( float a_Dt) { + if (push_method("Tick", tolua_AllToLua_cPlugin_NewLua_Tick00)) { + tolua_pushnumber(lua_state, (lua_Number)a_Dt); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPlugin_NewLua:: Tick(a_Dt); + }; + }; + bool OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player) { + if (push_method("OnCollectItem", tolua_AllToLua_cPlugin_OnCollectItem00)) { + tolua_pushusertype(lua_state, (void*)a_Pickup, "cPickup"); + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 3, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnCollectItem(a_Pickup,a_Player); + }; + }; + bool OnDisconnect( const AString& a_Reason, cPlayer* a_Player) { + if (push_method("OnDisconnect", tolua_AllToLua_cPlugin_OnDisconnect00)) { + tolua_pushcppstring(lua_state, (const char*)a_Reason); + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 3, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnDisconnect(a_Reason,a_Player); + }; + }; + bool OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player) { + if (push_method("OnBlockPlace", tolua_AllToLua_cPlugin_OnBlockPlace00)) { + tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_BlockPlace"); + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 3, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnBlockPlace(a_PacketData,a_Player); + }; + }; + bool OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem) { + if (push_method("OnBlockDig", tolua_AllToLua_cPlugin_OnBlockDig00)) { + tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_BlockDig"); + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + tolua_pushusertype(lua_state, (void*)a_PickupItem, "cItem"); + ToluaBase::dbcall(lua_state, 4, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnBlockDig(a_PacketData,a_Player,a_PickupItem); + }; + }; + bool OnChat( const char* a_Chat, cPlayer* a_Player) { + if (push_method("OnChat", tolua_AllToLua_cPlugin_OnChat00)) { + tolua_pushstring(lua_state, (const char*)a_Chat); + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 3, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnChat(a_Chat,a_Player); + }; + }; + bool OnLogin( cPacket_Login* a_PacketData) { + if (push_method("OnLogin", tolua_AllToLua_cPlugin_OnLogin00)) { + tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_Login"); + ToluaBase::dbcall(lua_state, 2, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnLogin(a_PacketData); + }; + }; + void OnPlayerSpawn( cPlayer* a_Player) { + if (push_method("OnPlayerSpawn", tolua_AllToLua_cPlugin_OnPlayerSpawn00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPlugin_NewLua:: OnPlayerSpawn(a_Player); + }; + }; + bool OnPlayerJoin( cPlayer* a_Player) { + if (push_method("OnPlayerJoin", tolua_AllToLua_cPlugin_OnPlayerJoin00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 2, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnPlayerJoin(a_Player); + }; + }; + void OnPlayerMove( cPlayer* a_Player) { + if (push_method("OnPlayerMove", tolua_AllToLua_cPlugin_OnPlayerMove00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPlugin_NewLua:: OnPlayerMove(a_Player); + }; + }; + void OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo) { + if (push_method("OnTakeDamage", tolua_AllToLua_cPlugin_OnTakeDamage00)) { + tolua_pushusertype(lua_state, (void*)a_Pawn, "cPawn"); + tolua_pushusertype(lua_state, (void*)a_TakeDamageInfo, "TakeDamageInfo"); + ToluaBase::dbcall(lua_state, 3, 0); + } else { + return ( void ) cPlugin_NewLua:: OnTakeDamage(a_Pawn,a_TakeDamageInfo); + }; + }; + bool OnKilled( cPawn* a_Killed, cEntity* a_Killer) { + if (push_method("OnKilled", tolua_AllToLua_cPlugin_OnKilled00)) { + tolua_pushusertype(lua_state, (void*)a_Killed, "cPawn"); + tolua_pushusertype(lua_state, (void*)a_Killer, "cEntity"); + ToluaBase::dbcall(lua_state, 3, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnKilled(a_Killed,a_Killer); + }; + }; + void OnChunkGenerated( cWorld* a_World, int a_ChunkX, int a_ChunkZ) { + if (push_method("OnChunkGenerated", tolua_AllToLua_cPlugin_OnChunkGenerated00)) { + tolua_pushusertype(lua_state, (void*)a_World, "cWorld"); + tolua_pushnumber(lua_state, (lua_Number)a_ChunkX); + tolua_pushnumber(lua_state, (lua_Number)a_ChunkZ); + ToluaBase::dbcall(lua_state, 4, 0); + } else { + return ( void ) cPlugin_NewLua:: OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ); + }; + }; + bool OnChunkGenerating( int a_ChunkX, int a_ChunkZ, cLuaChunk* a_pLuaChunk) { + if (push_method("OnChunkGenerating", tolua_AllToLua_cPlugin_OnChunkGenerating00)) { + tolua_pushnumber(lua_state, (lua_Number)a_ChunkX); + tolua_pushnumber(lua_state, (lua_Number)a_ChunkZ); + tolua_pushusertype(lua_state, (void*)a_pLuaChunk, "cLuaChunk"); + ToluaBase::dbcall(lua_state, 4, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk); + }; + }; + bool OnPreCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + if (push_method("OnPreCrafting", tolua_AllToLua_cPlugin_OnPreCrafting00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); + tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid"); + tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe"); + ToluaBase::dbcall(lua_state, 4, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnPreCrafting(a_Player,a_Grid,a_Recipe); + }; + }; + bool OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + if (push_method("OnCraftingNoRecipe", tolua_AllToLua_cPlugin_OnCraftingNoRecipe00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); + tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid"); + tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe"); + ToluaBase::dbcall(lua_state, 4, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); + }; + }; + bool OnPostCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + if (push_method("OnPostCrafting", tolua_AllToLua_cPlugin_OnPostCrafting00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); + tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid"); + tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe"); + ToluaBase::dbcall(lua_state, 4, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnPostCrafting(a_Player,a_Grid,a_Recipe); + }; + }; + bool OnBlockToPickup( BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer* a_Player, const cItem& a_EquippedItem, cItems& a_Pickups) { + if (push_method("OnBlockToPickup", tolua_AllToLua_cPlugin_OnBlockToPickup00)) { + void* tolua_obj0 = (void*)new BLOCKTYPE(a_BlockType); + tolua_pushusertype_and_takeownership(lua_state, tolua_obj0, "BLOCKTYPE"); + void* tolua_obj1 = (void*)new NIBBLETYPE(a_BlockMeta); + tolua_pushusertype_and_takeownership(lua_state, tolua_obj1, "NIBBLETYPE"); + tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); + tolua_pushusertype(lua_state, (void*)&a_EquippedItem, "const cItem"); + tolua_pushusertype(lua_state, (void*)&a_Pickups, "cItems"); + ToluaBase::dbcall(lua_state, 6, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,a_EquippedItem,a_Pickups); + }; + }; + + void cPlugin_NewLua__OnDisable( void ) { + return ( void )cPlugin_NewLua::OnDisable(); + }; + bool cPlugin_NewLua__Initialize( void ) { + return ( bool )cPlugin_NewLua::Initialize(); + }; + void cPlugin_NewLua__Tick( float a_Dt) { + return ( void )cPlugin_NewLua::Tick(a_Dt); + }; + bool cPlugin_NewLua__OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player) { + return ( bool )cPlugin_NewLua::OnCollectItem(a_Pickup,a_Player); + }; + bool cPlugin_NewLua__OnDisconnect( const AString& a_Reason, cPlayer* a_Player) { + return ( bool )cPlugin_NewLua::OnDisconnect(a_Reason,a_Player); + }; + bool cPlugin_NewLua__OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player) { + return ( bool )cPlugin_NewLua::OnBlockPlace(a_PacketData,a_Player); + }; + bool cPlugin_NewLua__OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem) { + return ( bool )cPlugin_NewLua::OnBlockDig(a_PacketData,a_Player,a_PickupItem); + }; + bool cPlugin_NewLua__OnChat( const char* a_Chat, cPlayer* a_Player) { + return ( bool )cPlugin_NewLua::OnChat(a_Chat,a_Player); + }; + bool cPlugin_NewLua__OnLogin( cPacket_Login* a_PacketData) { + return ( bool )cPlugin_NewLua::OnLogin(a_PacketData); + }; + void cPlugin_NewLua__OnPlayerSpawn( cPlayer* a_Player) { + return ( void )cPlugin_NewLua::OnPlayerSpawn(a_Player); + }; + bool cPlugin_NewLua__OnPlayerJoin( cPlayer* a_Player) { + return ( bool )cPlugin_NewLua::OnPlayerJoin(a_Player); + }; + void cPlugin_NewLua__OnPlayerMove( cPlayer* a_Player) { + return ( void )cPlugin_NewLua::OnPlayerMove(a_Player); + }; + void cPlugin_NewLua__OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo) { + return ( void )cPlugin_NewLua::OnTakeDamage(a_Pawn,a_TakeDamageInfo); + }; + bool cPlugin_NewLua__OnKilled( cPawn* a_Killed, cEntity* a_Killer) { + return ( bool )cPlugin_NewLua::OnKilled(a_Killed,a_Killer); + }; + void cPlugin_NewLua__OnChunkGenerated( cWorld* a_World, int a_ChunkX, int a_ChunkZ) { + return ( void )cPlugin_NewLua::OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ); + }; + bool cPlugin_NewLua__OnChunkGenerating( int a_ChunkX, int a_ChunkZ, cLuaChunk* a_pLuaChunk) { + return ( bool )cPlugin_NewLua::OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk); + }; + bool cPlugin_NewLua__OnPreCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + return ( bool )cPlugin_NewLua::OnPreCrafting(a_Player,a_Grid,a_Recipe); + }; + bool cPlugin_NewLua__OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + return ( bool )cPlugin_NewLua::OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); + }; + bool cPlugin_NewLua__OnPostCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + return ( bool )cPlugin_NewLua::OnPostCrafting(a_Player,a_Grid,a_Recipe); + }; + bool cPlugin_NewLua__OnBlockToPickup( BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer* a_Player, const cItem& a_EquippedItem, cItems& a_Pickups) { + return ( bool )cPlugin_NewLua::OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,a_EquippedItem,a_Pickups); + }; +}; + +/* method: tolua__set_instance of class Lua__cPlugin_NewLua */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_NewLua_tolua__set_instance00 +static int tolua_AllToLua_Lua__cPlugin_NewLua_tolua__set_instance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin_NewLua",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin_NewLua* self = (Lua__cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); + lua_State* L = tolua_S; + lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); +#endif + { + self->tolua__set_instance(L,lo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin_NewLua__OnDisable of class Lua__cPlugin_NewLua */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__OnDisable00 +static int tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__OnDisable00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin_NewLua",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin_NewLua* self = (Lua__cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin_NewLua__OnDisable'", NULL); +#endif + { + self->cPlugin_NewLua__OnDisable(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin_NewLua__OnDisable'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin_NewLua__Initialize of class Lua__cPlugin_NewLua */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Initialize00 +static int tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Initialize00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin_NewLua",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin_NewLua* self = (Lua__cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin_NewLua__Initialize'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin_NewLua__Initialize(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin_NewLua__Initialize'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin_NewLua__Tick of class Lua__cPlugin_NewLua */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Tick00 +static int tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Tick00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin_NewLua",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin_NewLua* self = (Lua__cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); + float a_Dt = ((float) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin_NewLua__Tick'", NULL); +#endif + { + self->cPlugin_NewLua__Tick(a_Dt); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin_NewLua__Tick'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetFileName of class cPlugin_Lua */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_Lua_GetFileName00 +static int tolua_AllToLua_cPlugin_Lua_GetFileName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin_Lua",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin_Lua* self = (cPlugin_Lua*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetFileName'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->GetFileName(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetFileName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetServer of class cServer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_GetServer00 +static int tolua_AllToLua_cServer_GetServer00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cServer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + cServer* tolua_ret = (cServer*) cServer::GetServer(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cServer"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetServer'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: ServerCommand of class cServer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_ServerCommand00 +static int tolua_AllToLua_cServer_ServerCommand00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cServer",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cServer* self = (cServer*) tolua_tousertype(tolua_S,1,0); + const char* a_Cmd = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ServerCommand'", NULL); +#endif + { + self->ServerCommand(a_Cmd); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'ServerCommand'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SendMessage of class cServer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_SendMessage00 +static int tolua_AllToLua_cServer_SendMessage00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cServer",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",1,&tolua_err) || + !tolua_isboolean(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cServer* self = (cServer*) tolua_tousertype(tolua_S,1,0); + const char* a_Message = ((const char*) tolua_tostring(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); + bool a_bExclude = ((bool) tolua_toboolean(tolua_S,4,false)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendMessage'", NULL); +#endif + { + self->SendMessage(a_Message,a_Player,a_bExclude); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SendMessage'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetTime of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetTime00 +static int tolua_AllToLua_cWorld_GetTime00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + float tolua_ret = (float) cWorld::GetTime(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetTime'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetGameMode of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetGameMode00 +static int tolua_AllToLua_cWorld_GetGameMode00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetGameMode'", NULL); +#endif + { + eGameMode tolua_ret = (eGameMode) self->GetGameMode(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetGameMode'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetWorldTime of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetWorldTime00 +static int tolua_AllToLua_cWorld_SetWorldTime00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + long long a_WorldTime = ((long long) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetWorldTime'", NULL); +#endif + { + self->SetWorldTime(a_WorldTime); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetWorldTime'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetHeight of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetHeight00 +static int tolua_AllToLua_cWorld_GetHeight00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHeight'", NULL); +#endif + { + int tolua_ret = (int) self->GetHeight(a_X,a_Z); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetHeight'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: UnloadUnusedChunks of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_UnloadUnusedChunks00 +static int tolua_AllToLua_cWorld_UnloadUnusedChunks00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'UnloadUnusedChunks'", NULL); +#endif + { + self->UnloadUnusedChunks(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'UnloadUnusedChunks'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetMaxPlayers of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetMaxPlayers00 +static int tolua_AllToLua_cWorld_GetMaxPlayers00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxPlayers'", NULL); +#endif + { + unsigned int tolua_ret = (unsigned int) self->GetMaxPlayers(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetMaxPlayers'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetMaxPlayers of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetMaxPlayers00 +static int tolua_AllToLua_cWorld_SetMaxPlayers00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int iMax = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetMaxPlayers'", NULL); +#endif + { + self->SetMaxPlayers(iMax); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetMaxPlayers'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetNumPlayers of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetNumPlayers00 +static int tolua_AllToLua_cWorld_GetNumPlayers00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumPlayers'", NULL); +#endif + { + unsigned int tolua_ret = (unsigned int) self->GetNumPlayers(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetNumPlayers'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPlayer of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetPlayer00 +static int tolua_AllToLua_cWorld_GetPlayer00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + const char* a_PlayerName = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPlayer'", NULL); +#endif + { + cPlayer* tolua_ret = (cPlayer*) self->GetPlayer(a_PlayerName); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPlayer"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPlayer'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: UpdateSign of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_UpdateSign00 +static int tolua_AllToLua_cWorld_UpdateSign00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_iscppstring(tolua_S,5,0,&tolua_err) || + !tolua_iscppstring(tolua_S,6,0,&tolua_err) || + !tolua_iscppstring(tolua_S,7,0,&tolua_err) || + !tolua_iscppstring(tolua_S,8,0,&tolua_err) || + !tolua_isnoobj(tolua_S,9,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); + const AString a_Line1 = ((const AString) tolua_tocppstring(tolua_S,5,0)); + const AString a_Line2 = ((const AString) tolua_tocppstring(tolua_S,6,0)); + const AString a_Line3 = ((const AString) tolua_tocppstring(tolua_S,7,0)); + const AString a_Line4 = ((const AString) tolua_tocppstring(tolua_S,8,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'UpdateSign'", NULL); +#endif + { + self->UpdateSign(a_X,a_Y,a_Z,a_Line1,a_Line2,a_Line3,a_Line4); + tolua_pushcppstring(tolua_S,(const char*)a_Line1); + tolua_pushcppstring(tolua_S,(const char*)a_Line2); + tolua_pushcppstring(tolua_S,(const char*)a_Line3); + tolua_pushcppstring(tolua_S,(const char*)a_Line4); + } + } + return 4; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'UpdateSign'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: RegenerateChunk of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_RegenerateChunk00 +static int tolua_AllToLua_cWorld_RegenerateChunk00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_ChunkX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_ChunkZ = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'RegenerateChunk'", NULL); +#endif + { + self->RegenerateChunk(a_ChunkX,a_ChunkZ); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'RegenerateChunk'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GenerateChunk of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GenerateChunk00 +static int tolua_AllToLua_cWorld_GenerateChunk00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_ChunkX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_ChunkZ = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GenerateChunk'", NULL); +#endif + { + self->GenerateChunk(a_ChunkX,a_ChunkZ); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GenerateChunk'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetBlock of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetBlock00 +static int tolua_AllToLua_cWorld_SetBlock00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnoobj(tolua_S,7,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); + char a_BlockType = ((char) tolua_tonumber(tolua_S,5,0)); + char a_BlockMeta = ((char) tolua_tonumber(tolua_S,6,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBlock'", NULL); +#endif + { + self->SetBlock(a_X,a_Y,a_Z,a_BlockType,a_BlockMeta); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetBlock'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: FastSetBlock of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_FastSetBlock00 +static int tolua_AllToLua_cWorld_FastSetBlock00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnoobj(tolua_S,7,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); + char a_BlockType = ((char) tolua_tonumber(tolua_S,5,0)); + char a_BlockMeta = ((char) tolua_tonumber(tolua_S,6,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'FastSetBlock'", NULL); +#endif + { + self->FastSetBlock(a_X,a_Y,a_Z,a_BlockType,a_BlockMeta); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'FastSetBlock'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBlock of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlock00 +static int tolua_AllToLua_cWorld_GetBlock00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlock'", NULL); +#endif + { + char tolua_ret = (char) self->GetBlock(a_X,a_Y,a_Z); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetBlock'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBlock of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlock01 +static int tolua_AllToLua_cWorld_GetBlock01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + const Vector3i* a_Pos = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlock'", NULL); +#endif + { + char tolua_ret = (char) self->GetBlock(*a_Pos); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cWorld_GetBlock00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBlockMeta of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockMeta00 +static int tolua_AllToLua_cWorld_GetBlockMeta00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockMeta'", NULL); +#endif + { + char tolua_ret = (char) self->GetBlockMeta(a_X,a_Y,a_Z); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetBlockMeta'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBlockMeta of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockMeta01 +static int tolua_AllToLua_cWorld_GetBlockMeta01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + const Vector3i* a_Pos = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockMeta'", NULL); +#endif + { + char tolua_ret = (char) self->GetBlockMeta(*a_Pos); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cWorld_GetBlockMeta00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetBlockMeta of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetBlockMeta00 +static int tolua_AllToLua_cWorld_SetBlockMeta00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); + char a_MetaData = ((char) tolua_tonumber(tolua_S,5,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBlockMeta'", NULL); +#endif + { + self->SetBlockMeta(a_X,a_Y,a_Z,a_MetaData); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetBlockMeta'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetBlockMeta of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetBlockMeta01 +static int tolua_AllToLua_cWorld_SetBlockMeta01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + const Vector3i* a_Pos = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); + char a_MetaData = ((char) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBlockMeta'", NULL); +#endif + { + self->SetBlockMeta(*a_Pos,a_MetaData); + } + } + return 0; +tolua_lerror: + return tolua_AllToLua_cWorld_SetBlockMeta00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBlockSkyLight of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockSkyLight00 +static int tolua_AllToLua_cWorld_GetBlockSkyLight00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockSkyLight'", NULL); +#endif + { + char tolua_ret = (char) self->GetBlockSkyLight(a_X,a_Y,a_Z); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetBlockSkyLight'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBlockTypeMeta of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockTypeMeta00 +static int tolua_AllToLua_cWorld_GetBlockTypeMeta00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnoobj(tolua_S,7,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); + int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); + char a_BlockType = ((char) tolua_tonumber(tolua_S,5,0)); + unsigned char a_BlockMeta = ((unsigned char) tolua_tonumber(tolua_S,6,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockTypeMeta'", NULL); +#endif + { + self->GetBlockTypeMeta(a_BlockX,a_BlockY,a_BlockZ,a_BlockType,a_BlockMeta); + tolua_pushnumber(tolua_S,(lua_Number)a_BlockType); + tolua_pushnumber(tolua_S,(lua_Number)a_BlockMeta); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetBlockTypeMeta'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DigBlock of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_DigBlock00 +static int tolua_AllToLua_cWorld_DigBlock00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DigBlock'", NULL); +#endif + { + bool tolua_ret = (bool) self->DigBlock(a_X,a_Y,a_Z); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DigBlock'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SendBlockTo of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SendBlockTo00 +static int tolua_AllToLua_cWorld_SendBlockTo00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isusertype(tolua_S,5,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,5,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendBlockTo'", NULL); +#endif + { + self->SendBlockTo(a_X,a_Y,a_Z,a_Player); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SendBlockTo'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetSpawnX of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetSpawnX00 +static int tolua_AllToLua_cWorld_GetSpawnX00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSpawnX'", NULL); +#endif + { + const double tolua_ret = (const double) self->GetSpawnX(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetSpawnX'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetSpawnY of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetSpawnY00 +static int tolua_AllToLua_cWorld_GetSpawnY00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSpawnY'", NULL); +#endif + { + const double tolua_ret = (const double) self->GetSpawnY(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetSpawnY'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetSpawnZ of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetSpawnZ00 +static int tolua_AllToLua_cWorld_GetSpawnZ00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSpawnZ'", NULL); +#endif + { + const double tolua_ret = (const double) self->GetSpawnZ(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetSpawnZ'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBlockEntity of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockEntity00 +static int tolua_AllToLua_cWorld_GetBlockEntity00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockEntity'", NULL); +#endif + { + OBSOLETE cBlockEntity* tolua_ret = (OBSOLETE cBlockEntity*) self->GetBlockEntity(a_X,a_Y,a_Z); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cBlockEntity"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetBlockEntity'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GrowTree of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowTree00 +static int tolua_AllToLua_cWorld_GrowTree00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); + int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowTree'", NULL); +#endif + { + self->GrowTree(a_BlockX,a_BlockY,a_BlockZ); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GrowTree'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GrowTreeFromSapling of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowTreeFromSapling00 +static int tolua_AllToLua_cWorld_GrowTreeFromSapling00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); + int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); + char a_SaplingMeta = ((char) tolua_tonumber(tolua_S,5,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowTreeFromSapling'", NULL); +#endif + { + self->GrowTreeFromSapling(a_BlockX,a_BlockY,a_BlockZ,a_SaplingMeta); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GrowTreeFromSapling'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GrowTreeByBiome of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowTreeByBiome00 +static int tolua_AllToLua_cWorld_GrowTreeByBiome00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); + int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowTreeByBiome'", NULL); +#endif + { + self->GrowTreeByBiome(a_BlockX,a_BlockY,a_BlockZ); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GrowTreeByBiome'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GrowPlant of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowPlant00 +static int tolua_AllToLua_cWorld_GrowPlant00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isboolean(tolua_S,5,1,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); + int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); + bool a_IsByBonemeal = ((bool) tolua_toboolean(tolua_S,5,false)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowPlant'", NULL); +#endif + { + bool tolua_ret = (bool) self->GrowPlant(a_BlockX,a_BlockY,a_BlockZ,a_IsByBonemeal); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GrowPlant'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GrowMelonPumpkin of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowMelonPumpkin00 +static int tolua_AllToLua_cWorld_GrowMelonPumpkin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); + int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); + char a_BlockType = ((char) tolua_tonumber(tolua_S,5,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowMelonPumpkin'", NULL); +#endif + { + self->GrowMelonPumpkin(a_BlockX,a_BlockY,a_BlockZ,a_BlockType); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GrowMelonPumpkin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBiomeAt of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBiomeAt00 +static int tolua_AllToLua_cWorld_GetBiomeAt00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_BlockZ = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBiomeAt'", NULL); +#endif + { + int tolua_ret = (int) self->GetBiomeAt(a_BlockX,a_BlockZ); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetBiomeAt'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetName of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetName00 +static int tolua_AllToLua_cWorld_GetName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL); +#endif + { + const AString tolua_ret = (const AString) self->GetName(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SaveAllChunks of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SaveAllChunks00 +static int tolua_AllToLua_cWorld_SaveAllChunks00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SaveAllChunks'", NULL); +#endif + { + self->SaveAllChunks(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SaveAllChunks'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetNumChunks of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetNumChunks00 +static int tolua_AllToLua_cWorld_GetNumChunks00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumChunks'", NULL); +#endif + { + int tolua_ret = (int) self->GetNumChunks(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetNumChunks'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetGeneratorQueueLength of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetGeneratorQueueLength00 +static int tolua_AllToLua_cWorld_GetGeneratorQueueLength00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetGeneratorQueueLength'", NULL); +#endif + { + int tolua_ret = (int) self->GetGeneratorQueueLength(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetGeneratorQueueLength'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetLightingQueueLength of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetLightingQueueLength00 +static int tolua_AllToLua_cWorld_GetLightingQueueLength00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLightingQueueLength'", NULL); +#endif + { + int tolua_ret = (int) self->GetLightingQueueLength(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetLightingQueueLength'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetStorageLoadQueueLength of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetStorageLoadQueueLength00 +static int tolua_AllToLua_cWorld_GetStorageLoadQueueLength00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetStorageLoadQueueLength'", NULL); +#endif + { + int tolua_ret = (int) self->GetStorageLoadQueueLength(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetStorageLoadQueueLength'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetStorageSaveQueueLength of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetStorageSaveQueueLength00 +static int tolua_AllToLua_cWorld_GetStorageSaveQueueLength00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetStorageSaveQueueLength'", NULL); +#endif + { + int tolua_ret = (int) self->GetStorageSaveQueueLength(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetStorageSaveQueueLength'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: CastThunderbolt of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_CastThunderbolt00 +static int tolua_AllToLua_cWorld_CastThunderbolt00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CastThunderbolt'", NULL); +#endif + { + self->CastThunderbolt(a_X,a_Y,a_Z); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'CastThunderbolt'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetWeather of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetWeather00 +static int tolua_AllToLua_cWorld_SetWeather00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + eWeather a_Weather = ((eWeather) (int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetWeather'", NULL); +#endif + { + self->SetWeather(a_Weather); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetWeather'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: ChangeWeather of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_ChangeWeather00 +static int tolua_AllToLua_cWorld_ChangeWeather00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ChangeWeather'", NULL); +#endif + { + self->ChangeWeather(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'ChangeWeather'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetWeather of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetWeather00 +static int tolua_AllToLua_cWorld_GetWeather00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWeather'", NULL); +#endif + { + eWeather tolua_ret = (eWeather) self->GetWeather(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetWeather'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetNextBlockTick of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetNextBlockTick00 +static int tolua_AllToLua_cWorld_SetNextBlockTick00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); + int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetNextBlockTick'", NULL); +#endif + { + self->SetNextBlockTick(a_BlockX,a_BlockY,a_BlockZ); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetNextBlockTick'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetMaxSugarcaneHeight of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetMaxSugarcaneHeight00 +static int tolua_AllToLua_cWorld_GetMaxSugarcaneHeight00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxSugarcaneHeight'", NULL); +#endif + { + int tolua_ret = (int) self->GetMaxSugarcaneHeight(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetMaxSugarcaneHeight'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetMaxCactusHeight of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetMaxCactusHeight00 +static int tolua_AllToLua_cWorld_GetMaxCactusHeight00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxCactusHeight'", NULL); +#endif + { + int tolua_ret = (int) self->GetMaxCactusHeight(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetMaxCactusHeight'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Clear of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_Clear00 +static int tolua_AllToLua_cInventory_Clear00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL); +#endif + { + self->Clear(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: AddItem of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_AddItem00 +static int tolua_AllToLua_cInventory_AddItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); + cItem* a_Item = ((cItem*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddItem'", NULL); +#endif + { + bool tolua_ret = (bool) self->AddItem(*a_Item); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'AddItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: RemoveItem of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_RemoveItem00 +static int tolua_AllToLua_cInventory_RemoveItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); + cItem* a_Item = ((cItem*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'RemoveItem'", NULL); +#endif + { + bool tolua_ret = (bool) self->RemoveItem(*a_Item); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'RemoveItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetSlot of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetSlot00 +static int tolua_AllToLua_cInventory_GetSlot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); + int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSlot'", NULL); +#endif + { + cItem* tolua_ret = (cItem*) self->GetSlot(a_SlotNum); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetSlot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetFromHotBar of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetFromHotBar00 +static int tolua_AllToLua_cInventory_GetFromHotBar00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); + int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetFromHotBar'", NULL); +#endif + { + cItem* tolua_ret = (cItem*) self->GetFromHotBar(a_SlotNum); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetFromHotBar'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetEquippedItem of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetEquippedItem00 +static int tolua_AllToLua_cInventory_GetEquippedItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEquippedItem'", NULL); +#endif + { + cItem& tolua_ret = (cItem&) self->GetEquippedItem(); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetEquippedItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetEquippedSlot of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_SetEquippedSlot00 +static int tolua_AllToLua_cInventory_SetEquippedSlot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); + int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetEquippedSlot'", NULL); +#endif + { + self->SetEquippedSlot(a_SlotNum); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetEquippedSlot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetEquippedSlot of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetEquippedSlot00 +static int tolua_AllToLua_cInventory_GetEquippedSlot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEquippedSlot'", NULL); +#endif + { + short tolua_ret = (short) self->GetEquippedSlot(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetEquippedSlot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SendSlot of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_SendSlot00 +static int tolua_AllToLua_cInventory_SendSlot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); + int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendSlot'", NULL); +#endif + { + self->SendSlot(a_SlotNum); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SendSlot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_new00 +static int tolua_AllToLua_cItem_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cItem",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,1,&tolua_err) || + !tolua_isnumber(tolua_S,3,1,&tolua_err) || + !tolua_isnumber(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,E_ITEM_EMPTY)); + char a_ItemCount = ((char) tolua_tonumber(tolua_S,3,0)); + short a_ItemHealth = ((short) tolua_tonumber(tolua_S,4,0)); + { + cItem* tolua_ret = (cItem*) Mtolua_new((cItem)(a_ItemID,a_ItemCount,a_ItemHealth)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_new00_local +static int tolua_AllToLua_cItem_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cItem",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,1,&tolua_err) || + !tolua_isnumber(tolua_S,3,1,&tolua_err) || + !tolua_isnumber(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,E_ITEM_EMPTY)); + char a_ItemCount = ((char) tolua_tonumber(tolua_S,3,0)); + short a_ItemHealth = ((short) tolua_tonumber(tolua_S,4,0)); + { + cItem* tolua_ret = (cItem*) Mtolua_new((cItem)(a_ItemID,a_ItemCount,a_ItemHealth)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cItem"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Empty of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_Empty00 +static int tolua_AllToLua_cItem_Empty00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Empty'", NULL); +#endif + { + self->Empty(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Empty'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Clear of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_Clear00 +static int tolua_AllToLua_cItem_Clear00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL); +#endif + { + self->Clear(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsEmpty of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_IsEmpty00 +static int tolua_AllToLua_cItem_IsEmpty00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cItem",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cItem* self = (const cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsEmpty'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsEmpty(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsEmpty'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Equals of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_Equals00 +static int tolua_AllToLua_cItem_Equals00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cItem",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cItem* self = (const cItem*) tolua_tousertype(tolua_S,1,0); + cItem* a_Item = ((cItem*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Equals'", NULL); +#endif + { + bool tolua_ret = (bool) self->Equals(*a_Item); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Equals'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetMaxDuration of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_GetMaxDuration00 +static int tolua_AllToLua_cItem_GetMaxDuration00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cItem",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cItem* self = (const cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxDuration'", NULL); +#endif + { + int tolua_ret = (int) self->GetMaxDuration(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetMaxDuration'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DamageItem of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_DamageItem00 +static int tolua_AllToLua_cItem_DamageItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DamageItem'", NULL); +#endif + { + bool tolua_ret = (bool) self->DamageItem(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DamageItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: HasDuration of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_HasDuration00 +static int tolua_AllToLua_cItem_HasDuration00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HasDuration'", NULL); +#endif + { + bool tolua_ret = (bool) self->HasDuration(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'HasDuration'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetJson of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_GetJson00 +static int tolua_AllToLua_cItem_GetJson00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cItem",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Json::Value",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cItem* self = (const cItem*) tolua_tousertype(tolua_S,1,0); + Json::Value* a_OutValue = ((Json::Value*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetJson'", NULL); +#endif + { + self->GetJson(*a_OutValue); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetJson'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: FromJson of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_FromJson00 +static int tolua_AllToLua_cItem_FromJson00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Json::Value",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); + const Json::Value* a_Value = ((const Json::Value*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'FromJson'", NULL); +#endif + { + self->FromJson(*a_Value); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'FromJson'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsEnchantable of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_IsEnchantable00 +static int tolua_AllToLua_cItem_IsEnchantable00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cItem",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + ENUM_ITEM_ID item = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,0)); + { + bool tolua_ret = (bool) cItem::IsEnchantable(item); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsEnchantable'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_ItemID of class cItem */ +#ifndef TOLUA_DISABLE_tolua_get_cItem_m_ItemID +static int tolua_get_cItem_m_ItemID(lua_State* tolua_S) +{ + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemID'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_ItemID); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_ItemID of class cItem */ +#ifndef TOLUA_DISABLE_tolua_set_cItem_m_ItemID +static int tolua_set_cItem_m_ItemID(lua_State* tolua_S) +{ + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemID'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_ItemCount of class cItem */ +#ifndef TOLUA_DISABLE_tolua_get_cItem_m_ItemCount +static int tolua_get_cItem_m_ItemCount(lua_State* tolua_S) +{ + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemCount'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_ItemCount); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_ItemCount of class cItem */ +#ifndef TOLUA_DISABLE_tolua_set_cItem_m_ItemCount +static int tolua_set_cItem_m_ItemCount(lua_State* tolua_S) +{ + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemCount'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_ItemCount = ((char) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_ItemHealth of class cItem */ +#ifndef TOLUA_DISABLE_tolua_get_cItem_m_ItemHealth +static int tolua_get_cItem_m_ItemHealth(lua_State* tolua_S) +{ + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemHealth'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_ItemHealth); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_ItemHealth of class cItem */ +#ifndef TOLUA_DISABLE_tolua_set_cItem_m_ItemHealth +static int tolua_set_cItem_m_ItemHealth(lua_State* tolua_S) +{ + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemHealth'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_ItemHealth = ((short) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Name of class HTTPFormData */ +#ifndef TOLUA_DISABLE_tolua_get_HTTPFormData_Name +static int tolua_get_HTTPFormData_Name(lua_State* tolua_S) +{ + HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Name'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Name); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Name of class HTTPFormData */ +#ifndef TOLUA_DISABLE_tolua_set_HTTPFormData_Name +static int tolua_set_HTTPFormData_Name(lua_State* tolua_S) +{ + HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Name'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Name = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Value of class HTTPFormData */ +#ifndef TOLUA_DISABLE_tolua_get_HTTPFormData_Value +static int tolua_get_HTTPFormData_Value(lua_State* tolua_S) +{ + HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Value'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Value); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Value of class HTTPFormData */ +#ifndef TOLUA_DISABLE_tolua_set_HTTPFormData_Value +static int tolua_set_HTTPFormData_Value(lua_State* tolua_S) +{ + HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Value'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Value = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Type of class HTTPFormData */ +#ifndef TOLUA_DISABLE_tolua_get_HTTPFormData_Type +static int tolua_get_HTTPFormData_Type(lua_State* tolua_S) +{ + HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Type'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Type); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Type of class HTTPFormData */ +#ifndef TOLUA_DISABLE_tolua_set_HTTPFormData_Type +static int tolua_set_HTTPFormData_Type(lua_State* tolua_S) +{ + HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Type'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Type = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Method of class HTTPRequest */ +#ifndef TOLUA_DISABLE_tolua_get_HTTPRequest_Method +static int tolua_get_HTTPRequest_Method(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Method'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Method); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Method of class HTTPRequest */ +#ifndef TOLUA_DISABLE_tolua_set_HTTPRequest_Method +static int tolua_set_HTTPRequest_Method(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Method'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Method = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Path of class HTTPRequest */ +#ifndef TOLUA_DISABLE_tolua_get_HTTPRequest_Path +static int tolua_get_HTTPRequest_Path(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Path'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Path); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Path of class HTTPRequest */ +#ifndef TOLUA_DISABLE_tolua_set_HTTPRequest_Path +static int tolua_set_HTTPRequest_Path(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Path'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Path = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Username of class HTTPRequest */ +#ifndef TOLUA_DISABLE_tolua_get_HTTPRequest_Username +static int tolua_get_HTTPRequest_Username(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Username'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Username); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Username of class HTTPRequest */ +#ifndef TOLUA_DISABLE_tolua_set_HTTPRequest_Username +static int tolua_set_HTTPRequest_Username(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Username'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Username = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class cWebPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_delete00 +static int tolua_AllToLua_cWebPlugin_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetName of class cWebPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_SetName00 +static int tolua_AllToLua_cWebPlugin_SetName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0); + std::string a_Name = ((std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetName'", NULL); +#endif + { + self->SetName(a_Name); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetName of class cWebPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_GetName00 +static int tolua_AllToLua_cWebPlugin_GetName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->GetName(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: HandleRequest of class cWebPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_HandleRequest00 +static int tolua_AllToLua_cWebPlugin_HandleRequest00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"HTTPRequest",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0); + HTTPRequest* a_Request = ((HTTPRequest*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HandleRequest'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->HandleRequest(a_Request); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'HandleRequest'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Initialize of class cWebPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_Initialize00 +static int tolua_AllToLua_cWebPlugin_Initialize00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL); +#endif + { + self->Initialize(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + class Lua__cWebPlugin : public cWebPlugin, public ToluaBase { +public: + std::string HandleRequest( HTTPRequest* a_Request) { + if (push_method("HandleRequest", tolua_AllToLua_cWebPlugin_HandleRequest00)) { + tolua_pushusertype(lua_state, (void*)a_Request, "HTTPRequest"); + ToluaBase::dbcall(lua_state, 2, 1); + std::string tolua_ret = ( std::string )tolua_tocppstring(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + if (lua_state) + LOG("pure-virtual method cWebPlugin::HandleRequest not implemented."); + else { + LOG("pure-virtual method cWebPlugin::HandleRequest called with no lua_state. Aborting"); + ::abort(); + }; + return ""; + }; + }; + void Initialize( void ) { + if (push_method("Initialize", tolua_AllToLua_cWebPlugin_Initialize00)) { + ToluaBase::dbcall(lua_state, 1, 0); + } else { + if (lua_state) + LOG("pure-virtual method cWebPlugin::Initialize not implemented."); + else { + LOG("pure-virtual method cWebPlugin::Initialize called with no lua_state. Aborting"); + ::abort(); + }; + return ( void )0; + }; + }; + + Lua__cWebPlugin( lua_State* L): cWebPlugin(L){}; +}; + +/* method: tolua__set_instance of class Lua__cWebPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cWebPlugin_tolua__set_instance00 +static int tolua_AllToLua_Lua__cWebPlugin_tolua__set_instance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cWebPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cWebPlugin* self = (Lua__cWebPlugin*) tolua_tousertype(tolua_S,1,0); + lua_State* L = tolua_S; + lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); +#endif + { + self->tolua__set_instance(L,lo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Lua__cWebPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cWebPlugin_new00 +static int tolua_AllToLua_Lua__cWebPlugin_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cWebPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + lua_State* L = tolua_S; + { + Lua__cWebPlugin* tolua_ret = (Lua__cWebPlugin*) Mtolua_new((Lua__cWebPlugin)(L)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cWebPlugin"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Lua__cWebPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cWebPlugin_new00_local +static int tolua_AllToLua_Lua__cWebPlugin_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cWebPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + lua_State* L = tolua_S; + { + Lua__cWebPlugin* tolua_ret = (Lua__cWebPlugin*) Mtolua_new((Lua__cWebPlugin)(L)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cWebPlugin"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class Lua__cWebPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cWebPlugin_delete00 +static int tolua_AllToLua_Lua__cWebPlugin_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cWebPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cWebPlugin* self = (Lua__cWebPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + +/* function to release collected object via destructor */ +#ifdef __cplusplus + +static int tolua_collect_Lua__cWebPlugin (lua_State* tolua_S) +{ + Lua__cWebPlugin* self = (Lua__cWebPlugin*) tolua_tousertype(tolua_S,1,0); + delete self; + return 0; +} +#endif + +/* method: new of class cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_new00 +static int tolua_AllToLua_cPickup_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cPickup",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"const cItem",0,&tolua_err)) || + !tolua_isnumber(tolua_S,6,1,&tolua_err) || + !tolua_isnumber(tolua_S,7,1,&tolua_err) || + !tolua_isnumber(tolua_S,8,1,&tolua_err) || + !tolua_isnoobj(tolua_S,9,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,5,0)); + float a_SpeedX = ((float) tolua_tonumber(tolua_S,6,0.f)); + float a_SpeedY = ((float) tolua_tonumber(tolua_S,7,0.f)); + float a_SpeedZ = ((float) tolua_tonumber(tolua_S,8,0.f)); + { + cPickup* tolua_ret = (cPickup*) Mtolua_new((cPickup)(a_X,a_Y,a_Z,*a_Item,a_SpeedX,a_SpeedY,a_SpeedZ)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPickup"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_new00_local +static int tolua_AllToLua_cPickup_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cPickup",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"const cItem",0,&tolua_err)) || + !tolua_isnumber(tolua_S,6,1,&tolua_err) || + !tolua_isnumber(tolua_S,7,1,&tolua_err) || + !tolua_isnumber(tolua_S,8,1,&tolua_err) || + !tolua_isnoobj(tolua_S,9,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,5,0)); + float a_SpeedX = ((float) tolua_tonumber(tolua_S,6,0.f)); + float a_SpeedY = ((float) tolua_tonumber(tolua_S,7,0.f)); + float a_SpeedZ = ((float) tolua_tonumber(tolua_S,8,0.f)); + { + cPickup* tolua_ret = (cPickup*) Mtolua_new((cPickup)(a_X,a_Y,a_Z,*a_Item,a_SpeedX,a_SpeedY,a_SpeedZ)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPickup"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_new01 +static int tolua_AllToLua_cPickup_new01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cPickup",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPacket_PickupSpawn",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cPacket_PickupSpawn* a_PickupSpawnPacket = ((cPacket_PickupSpawn*) tolua_tousertype(tolua_S,2,0)); + { + cPickup* tolua_ret = (cPickup*) Mtolua_new((cPickup)(a_PickupSpawnPacket)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPickup"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cPickup_new00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_new01_local +static int tolua_AllToLua_cPickup_new01_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cPickup",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPacket_PickupSpawn",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cPacket_PickupSpawn* a_PickupSpawnPacket = ((cPacket_PickupSpawn*) tolua_tousertype(tolua_S,2,0)); + { + cPickup* tolua_ret = (cPickup*) Mtolua_new((cPickup)(a_PickupSpawnPacket)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPickup"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cPickup_new00_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_delete00 +static int tolua_AllToLua_cPickup_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPickup",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPickup* self = (cPickup*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetItem of class cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_GetItem00 +static int tolua_AllToLua_cPickup_GetItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPickup",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPickup* self = (cPickup*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetItem'", NULL); +#endif + { + cItem* tolua_ret = (cItem*) self->GetItem(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: CollectedBy of class cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_CollectedBy00 +static int tolua_AllToLua_cPickup_CollectedBy00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPickup",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPickup* self = (cPickup*) tolua_tousertype(tolua_S,1,0); + cPlayer* a_Dest = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CollectedBy'", NULL); +#endif + { + bool tolua_ret = (bool) self->CollectedBy(a_Dest); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'CollectedBy'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + class Lua__cPickup : public cPickup, public ToluaBase { +public: + bool CollectedBy( cPlayer* a_Dest) { + if (push_method("CollectedBy", tolua_AllToLua_cPickup_CollectedBy00)) { + tolua_pushusertype(lua_state, (void*)a_Dest, "cPlayer"); + ToluaBase::dbcall(lua_state, 2, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPickup:: CollectedBy(a_Dest); + }; + }; + void Initialize( cWorld* a_World) { + if (push_method("Initialize", tolua_AllToLua_cEntity_Initialize00)) { + tolua_pushusertype(lua_state, (void*)a_World, "cWorld"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPickup:: Initialize(a_World); + }; + }; + unsigned int GetEntityType( void ) { + if (push_method("GetEntityType", tolua_AllToLua_cEntity_GetEntityType00)) { + ToluaBase::dbcall(lua_state, 1, 1); + unsigned int tolua_ret = (unsigned int )tolua_tonumber(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return (unsigned int ) cPickup:: GetEntityType(); + }; + }; + bool IsA( const char* a_EntityType) { + if (push_method("IsA", tolua_AllToLua_cEntity_IsA00)) { + tolua_pushstring(lua_state, (const char*)a_EntityType); + ToluaBase::dbcall(lua_state, 2, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPickup:: IsA(a_EntityType); + }; + }; + const char* GetClass( void ) { + if (push_method("GetClass", tolua_AllToLua_cEntity_GetClass00)) { + ToluaBase::dbcall(lua_state, 1, 1); + const char* tolua_ret = ( const char* )tolua_tostring(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( const char* ) cPickup:: GetClass(); + }; + }; + void Tick( float a_Dt) { + if (push_method("Tick", tolua_AllToLua_cEntity_Tick00)) { + tolua_pushnumber(lua_state, (lua_Number)a_Dt); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + if (lua_state) + LOG("pure-virtual method cPickup::Tick not implemented."); + else { + LOG("pure-virtual method cPickup::Tick called with no lua_state. Aborting"); + ::abort(); + }; + return ( void )0; + }; + }; + + bool cPickup__CollectedBy( cPlayer* a_Dest) { + return ( bool )cPickup::CollectedBy(a_Dest); + }; + void cPickup__Initialize( cWorld* a_World) { + return ( void )cPickup::Initialize(a_World); + }; + unsigned int cPickup__GetEntityType( void ) { + return (unsigned int )cPickup::GetEntityType(); + }; + bool cPickup__IsA( const char* a_EntityType) { + return ( bool )cPickup::IsA(a_EntityType); + }; + const char* cPickup__GetClass( void ) { + return ( const char* )cPickup::GetClass(); + }; + Lua__cPickup( int a_X, int a_Y, int a_Z, const cItem& a_Item, float a_SpeedX = 0.f, float a_SpeedY = 0.f, float a_SpeedZ = 0.f): cPickup(a_X,a_Y,a_Z,a_Item,a_SpeedX,a_SpeedY,a_SpeedZ){}; + Lua__cPickup( cPacket_PickupSpawn* a_PickupSpawnPacket): cPickup(a_PickupSpawnPacket){}; +}; + +/* method: tolua__set_instance of class Lua__cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_tolua__set_instance00 +static int tolua_AllToLua_Lua__cPickup_tolua__set_instance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPickup",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPickup* self = (Lua__cPickup*) tolua_tousertype(tolua_S,1,0); + lua_State* L = tolua_S; + lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); +#endif + { + self->tolua__set_instance(L,lo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPickup__CollectedBy of class Lua__cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_cPickup__CollectedBy00 +static int tolua_AllToLua_Lua__cPickup_cPickup__CollectedBy00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPickup",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPickup* self = (Lua__cPickup*) tolua_tousertype(tolua_S,1,0); + cPlayer* a_Dest = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPickup__CollectedBy'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPickup__CollectedBy(a_Dest); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPickup__CollectedBy'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Lua__cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_new00 +static int tolua_AllToLua_Lua__cPickup_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cPickup",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"cItem",0,&tolua_err)) || + !tolua_isnumber(tolua_S,6,1,&tolua_err) || + !tolua_isnumber(tolua_S,7,1,&tolua_err) || + !tolua_isnumber(tolua_S,8,1,&tolua_err) || + !tolua_isnoobj(tolua_S,9,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,5,0)); + float a_SpeedX = ((float) tolua_tonumber(tolua_S,6,0.f)); + float a_SpeedY = ((float) tolua_tonumber(tolua_S,7,0.f)); + float a_SpeedZ = ((float) tolua_tonumber(tolua_S,8,0.f)); + { + Lua__cPickup* tolua_ret = (Lua__cPickup*) Mtolua_new((Lua__cPickup)(a_X,a_Y,a_Z,*a_Item,a_SpeedX,a_SpeedY,a_SpeedZ)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPickup"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Lua__cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_new00_local +static int tolua_AllToLua_Lua__cPickup_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cPickup",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"cItem",0,&tolua_err)) || + !tolua_isnumber(tolua_S,6,1,&tolua_err) || + !tolua_isnumber(tolua_S,7,1,&tolua_err) || + !tolua_isnumber(tolua_S,8,1,&tolua_err) || + !tolua_isnoobj(tolua_S,9,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,5,0)); + float a_SpeedX = ((float) tolua_tonumber(tolua_S,6,0.f)); + float a_SpeedY = ((float) tolua_tonumber(tolua_S,7,0.f)); + float a_SpeedZ = ((float) tolua_tonumber(tolua_S,8,0.f)); + { + Lua__cPickup* tolua_ret = (Lua__cPickup*) Mtolua_new((Lua__cPickup)(a_X,a_Y,a_Z,*a_Item,a_SpeedX,a_SpeedY,a_SpeedZ)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPickup"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Lua__cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_new01 +static int tolua_AllToLua_Lua__cPickup_new01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cPickup",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPacket_PickupSpawn",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cPacket_PickupSpawn* a_PickupSpawnPacket = ((cPacket_PickupSpawn*) tolua_tousertype(tolua_S,2,0)); + { + Lua__cPickup* tolua_ret = (Lua__cPickup*) Mtolua_new((Lua__cPickup)(a_PickupSpawnPacket)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPickup"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Lua__cPickup_new00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Lua__cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_new01_local +static int tolua_AllToLua_Lua__cPickup_new01_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cPickup",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPacket_PickupSpawn",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cPacket_PickupSpawn* a_PickupSpawnPacket = ((cPacket_PickupSpawn*) tolua_tousertype(tolua_S,2,0)); + { + Lua__cPickup* tolua_ret = (Lua__cPickup*) Mtolua_new((Lua__cPickup)(a_PickupSpawnPacket)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPickup"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Lua__cPickup_new00_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class Lua__cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_delete00 +static int tolua_AllToLua_Lua__cPickup_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPickup",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPickup* self = (Lua__cPickup*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + +/* function to release collected object via destructor */ +#ifdef __cplusplus + +static int tolua_collect_Lua__cPickup (lua_State* tolua_S) +{ + Lua__cPickup* self = (Lua__cPickup*) tolua_tousertype(tolua_S,1,0); + delete self; + return 0; +} +#endif + +/* method: Get of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_Get00 +static int tolua_AllToLua_cRoot_Get00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + cRoot* tolua_ret = (cRoot*) cRoot::Get(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cRoot"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Get'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetServer of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetServer00 +static int tolua_AllToLua_cRoot_GetServer00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetServer'", NULL); +#endif + { + cServer* tolua_ret = (cServer*) self->GetServer(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cServer"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetServer'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetDefaultWorld of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetDefaultWorld00 +static int tolua_AllToLua_cRoot_GetDefaultWorld00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetDefaultWorld'", NULL); +#endif + { + cWorld* tolua_ret = (cWorld*) self->GetDefaultWorld(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWorld"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetDefaultWorld'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetWorld of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetWorld00 +static int tolua_AllToLua_cRoot_GetWorld00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); + const AString a_WorldName = ((const AString) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWorld'", NULL); +#endif + { + cWorld* tolua_ret = (cWorld*) self->GetWorld(a_WorldName); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWorld"); + tolua_pushcppstring(tolua_S,(const char*)a_WorldName); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetWorld'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetGroupManager of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetGroupManager00 +static int tolua_AllToLua_cRoot_GetGroupManager00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetGroupManager'", NULL); +#endif + { + cGroupManager* tolua_ret = (cGroupManager*) self->GetGroupManager(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cGroupManager"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetGroupManager'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetCraftingRecipes of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetCraftingRecipes00 +static int tolua_AllToLua_cRoot_GetCraftingRecipes00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetCraftingRecipes'", NULL); +#endif + { + cCraftingRecipes* tolua_ret = (cCraftingRecipes*) self->GetCraftingRecipes(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCraftingRecipes"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetCraftingRecipes'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetFurnaceRecipe of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetFurnaceRecipe00 +static int tolua_AllToLua_cRoot_GetFurnaceRecipe00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetFurnaceRecipe'", NULL); +#endif + { + cFurnaceRecipe* tolua_ret = (cFurnaceRecipe*) self->GetFurnaceRecipe(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cFurnaceRecipe"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetFurnaceRecipe'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetWebAdmin of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetWebAdmin00 +static int tolua_AllToLua_cRoot_GetWebAdmin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWebAdmin'", NULL); +#endif + { + cWebAdmin* tolua_ret = (cWebAdmin*) self->GetWebAdmin(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWebAdmin"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetWebAdmin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPluginManager of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetPluginManager00 +static int tolua_AllToLua_cRoot_GetPluginManager00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPluginManager'", NULL); +#endif + { + cPluginManager* tolua_ret = (cPluginManager*) self->GetPluginManager(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPluginManager"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPluginManager'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: ServerCommand of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_ServerCommand00 +static int tolua_AllToLua_cRoot_ServerCommand00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); + const char* a_Cmd = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ServerCommand'", NULL); +#endif + { + self->ServerCommand(a_Cmd); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'ServerCommand'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetTotalChunkCount of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetTotalChunkCount00 +static int tolua_AllToLua_cRoot_GetTotalChunkCount00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetTotalChunkCount'", NULL); +#endif + { + int tolua_ret = (int) self->GetTotalChunkCount(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetTotalChunkCount'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class cTCPLink */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTCPLink_delete00 +static int tolua_AllToLua_cTCPLink_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cTCPLink",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Connect of class cTCPLink */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTCPLink_Connect00 +static int tolua_AllToLua_cTCPLink_Connect00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cTCPLink",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0); + const AString a_Address = ((const AString) tolua_tocppstring(tolua_S,2,0)); + unsigned int a_Port = ((unsigned int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Connect'", NULL); +#endif + { + bool tolua_ret = (bool) self->Connect(a_Address,a_Port); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)a_Address); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Connect'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Send of class cTCPLink */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTCPLink_Send00 +static int tolua_AllToLua_cTCPLink_Send00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cTCPLink",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0); + const char* a_Data = ((const char*) tolua_tostring(tolua_S,2,0)); + unsigned int a_Size = ((unsigned int) tolua_tonumber(tolua_S,3,0)); + int a_Flags = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Send'", NULL); +#endif + { + int tolua_ret = (int) self->Send(a_Data,a_Size,a_Flags); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Send'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SendMessage of class cTCPLink */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTCPLink_SendMessage00 +static int tolua_AllToLua_cTCPLink_SendMessage00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cTCPLink",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,1,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0); + const char* a_Message = ((const char*) tolua_tostring(tolua_S,2,0)); + int a_Flags = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendMessage'", NULL); +#endif + { + int tolua_ret = (int) self->SendMessage(a_Message,a_Flags); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SendMessage'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: CloseSocket of class cTCPLink */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTCPLink_CloseSocket00 +static int tolua_AllToLua_cTCPLink_CloseSocket00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cTCPLink",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CloseSocket'", NULL); +#endif + { + self->CloseSocket(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'CloseSocket'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + class Lua__cTCPLink : public cTCPLink, public ToluaBase { +public: + void ReceivedData( char* a_Data, int a_Size) { + if (push_method("ReceivedData", NULL)) { + tolua_pushstring(lua_state, (const char*)a_Data); + tolua_pushnumber(lua_state, (lua_Number)a_Size); + ToluaBase::dbcall(lua_state, 3, 0); + } else { + if (lua_state) + LOG("pure-virtual method cTCPLink::ReceivedData not implemented."); + else { + LOG("pure-virtual method cTCPLink::ReceivedData called with no lua_state. Aborting"); + ::abort(); + }; + return ( void )0; + }; + }; + + Lua__cTCPLink( void ): cTCPLink(){}; +}; + +/* method: tolua__set_instance of class Lua__cTCPLink */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cTCPLink_tolua__set_instance00 +static int tolua_AllToLua_Lua__cTCPLink_tolua__set_instance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cTCPLink",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cTCPLink* self = (Lua__cTCPLink*) tolua_tousertype(tolua_S,1,0); + lua_State* L = tolua_S; + lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); +#endif + { + self->tolua__set_instance(L,lo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Lua__cTCPLink */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cTCPLink_new00 +static int tolua_AllToLua_Lua__cTCPLink_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cTCPLink",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + Lua__cTCPLink* tolua_ret = (Lua__cTCPLink*) Mtolua_new((Lua__cTCPLink)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cTCPLink"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Lua__cTCPLink */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cTCPLink_new00_local +static int tolua_AllToLua_Lua__cTCPLink_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cTCPLink",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + Lua__cTCPLink* tolua_ret = (Lua__cTCPLink*) Mtolua_new((Lua__cTCPLink)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cTCPLink"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class Lua__cTCPLink */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cTCPLink_delete00 +static int tolua_AllToLua_Lua__cTCPLink_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cTCPLink",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cTCPLink* self = (Lua__cTCPLink*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + +/* function to release collected object via destructor */ +#ifdef __cplusplus + +static int tolua_collect_Lua__cTCPLink (lua_State* tolua_S) +{ + Lua__cTCPLink* self = (Lua__cTCPLink*) tolua_tousertype(tolua_S,1,0); + delete self; + return 0; +} +#endif + +/* method: new of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new00 +static int tolua_AllToLua_Vector3f_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(*v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new00_local +static int tolua_AllToLua_Vector3f_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(*v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new01 +static int tolua_AllToLua_Vector3f_new01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f_new00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new01_local +static int tolua_AllToLua_Vector3f_new01_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f_new00_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new02 +static int tolua_AllToLua_Vector3f_new02(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(*v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f_new01(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new02_local +static int tolua_AllToLua_Vector3f_new02_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(*v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f_new01_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new03 +static int tolua_AllToLua_Vector3f_new03(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f_new02(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new03_local +static int tolua_AllToLua_Vector3f_new03_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f_new02_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new04 +static int tolua_AllToLua_Vector3f_new04(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else + { + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f_new03(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new04_local +static int tolua_AllToLua_Vector3f_new04_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else + { + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f_new03_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new05 +static int tolua_AllToLua_Vector3f_new05(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + float a_x = ((float) tolua_tonumber(tolua_S,2,0)); + float a_y = ((float) tolua_tonumber(tolua_S,3,0)); + float a_z = ((float) tolua_tonumber(tolua_S,4,0)); + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(a_x,a_y,a_z)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f_new04(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new05_local +static int tolua_AllToLua_Vector3f_new05_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + float a_x = ((float) tolua_tonumber(tolua_S,2,0)); + float a_y = ((float) tolua_tonumber(tolua_S,3,0)); + float a_z = ((float) tolua_tonumber(tolua_S,4,0)); + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(a_x,a_y,a_z)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f_new04_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Set of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Set00 +static int tolua_AllToLua_Vector3f_Set00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Vector3f",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); + float a_x = ((float) tolua_tonumber(tolua_S,2,0)); + float a_y = ((float) tolua_tonumber(tolua_S,3,0)); + float a_z = ((float) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Set'", NULL); +#endif + { + self->Set(a_x,a_y,a_z); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Set'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Normalize of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Normalize00 +static int tolua_AllToLua_Vector3f_Normalize00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Vector3f",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Normalize'", NULL); +#endif + { + self->Normalize(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Normalize'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: NormalizeCopy of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_NormalizeCopy00 +static int tolua_AllToLua_Vector3f_NormalizeCopy00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NormalizeCopy'", NULL); +#endif + { + Vector3f tolua_ret = (Vector3f) self->NormalizeCopy(); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'NormalizeCopy'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: NormalizeCopy of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_NormalizeCopy01 +static int tolua_AllToLua_Vector3f_NormalizeCopy01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); + Vector3f* a_V = ((Vector3f*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NormalizeCopy'", NULL); +#endif + { + self->NormalizeCopy(*a_V); + } + } + return 0; +tolua_lerror: + return tolua_AllToLua_Vector3f_NormalizeCopy00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Length of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Length00 +static int tolua_AllToLua_Vector3f_Length00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Length'", NULL); +#endif + { + float tolua_ret = (float) self->Length(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Length'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SqrLength of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_SqrLength00 +static int tolua_AllToLua_Vector3f_SqrLength00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SqrLength'", NULL); +#endif + { + float tolua_ret = (float) self->SqrLength(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SqrLength'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Dot of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Dot00 +static int tolua_AllToLua_Vector3f_Dot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); + const Vector3f* a_V = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Dot'", NULL); +#endif + { + float tolua_ret = (float) self->Dot(*a_V); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Dot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Cross of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Cross00 +static int tolua_AllToLua_Vector3f_Cross00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); + const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Cross'", NULL); +#endif + { + Vector3f tolua_ret = (Vector3f) self->Cross(*v); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Cross'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Equals of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Equals00 +static int tolua_AllToLua_Vector3f_Equals00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); + const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Equals'", NULL); +#endif + { + bool tolua_ret = (bool) self->Equals(*v); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Equals'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator+ of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__add00 +static int tolua_AllToLua_Vector3f__add00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); + const Vector3f* v2 = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator+'", NULL); +#endif + { + Vector3f tolua_ret = (Vector3f) self->operator+(*v2); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function '.add'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator+ of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__add01 +static int tolua_AllToLua_Vector3f__add01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); + const Vector3f* v2 = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator+'", NULL); +#endif + { + Vector3f tolua_ret = (Vector3f) self->operator+(v2); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f__add00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator- of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__sub00 +static int tolua_AllToLua_Vector3f__sub00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); + const Vector3f* v2 = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator-'", NULL); +#endif + { + Vector3f tolua_ret = (Vector3f) self->operator-(*v2); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function '.sub'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator- of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__sub01 +static int tolua_AllToLua_Vector3f__sub01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); + const Vector3f* v2 = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator-'", NULL); +#endif + { + Vector3f tolua_ret = (Vector3f) self->operator-(v2); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f__sub00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator* of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__mul00 +static int tolua_AllToLua_Vector3f__mul00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); + const float f = ((const float) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator*'", NULL); +#endif + { + Vector3f tolua_ret = (Vector3f) self->operator*(f); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function '.mul'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator* of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__mul01 +static int tolua_AllToLua_Vector3f__mul01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); + const Vector3f* v2 = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator*'", NULL); +#endif + { + Vector3f tolua_ret = (Vector3f) self->operator*(*v2); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f__mul00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: x of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3f_x +static int tolua_get_Vector3f_x(lua_State* tolua_S) +{ + Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->x); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: x of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_set_Vector3f_x +static int tolua_set_Vector3f_x(lua_State* tolua_S) +{ + Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->x = ((float) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: y of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3f_y +static int tolua_get_Vector3f_y(lua_State* tolua_S) +{ + Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->y); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: y of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_set_Vector3f_y +static int tolua_set_Vector3f_y(lua_State* tolua_S) +{ + Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->y = ((float) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: z of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3f_z +static int tolua_get_Vector3f_z(lua_State* tolua_S) +{ + Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->z); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: z of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_set_Vector3f_z +static int tolua_set_Vector3f_z(lua_State* tolua_S) +{ + Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->z = ((float) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new00 +static int tolua_AllToLua_Vector3d_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); + { + Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(*v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new00_local +static int tolua_AllToLua_Vector3d_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); + { + Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(*v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new01 +static int tolua_AllToLua_Vector3d_new01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); + { + Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3d_new00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new01_local +static int tolua_AllToLua_Vector3d_new01_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); + { + Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3d_new00_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new02 +static int tolua_AllToLua_Vector3d_new02(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else + { + { + Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3d_new01(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new02_local +static int tolua_AllToLua_Vector3d_new02_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else + { + { + Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3d_new01_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new03 +static int tolua_AllToLua_Vector3d_new03(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + double a_x = ((double) tolua_tonumber(tolua_S,2,0)); + double a_y = ((double) tolua_tonumber(tolua_S,3,0)); + double a_z = ((double) tolua_tonumber(tolua_S,4,0)); + { + Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(a_x,a_y,a_z)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3d_new02(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new03_local +static int tolua_AllToLua_Vector3d_new03_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + double a_x = ((double) tolua_tonumber(tolua_S,2,0)); + double a_y = ((double) tolua_tonumber(tolua_S,3,0)); + double a_z = ((double) tolua_tonumber(tolua_S,4,0)); + { + Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(a_x,a_y,a_z)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3d_new02_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Set of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Set00 +static int tolua_AllToLua_Vector3d_Set00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Vector3d",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); + double a_x = ((double) tolua_tonumber(tolua_S,2,0)); + double a_y = ((double) tolua_tonumber(tolua_S,3,0)); + double a_z = ((double) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Set'", NULL); +#endif + { + self->Set(a_x,a_y,a_z); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Set'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Normalize of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Normalize00 +static int tolua_AllToLua_Vector3d_Normalize00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Vector3d",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Normalize'", NULL); +#endif + { + self->Normalize(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Normalize'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: NormalizeCopy of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_NormalizeCopy00 +static int tolua_AllToLua_Vector3d_NormalizeCopy00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Vector3d",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NormalizeCopy'", NULL); +#endif + { + Vector3d tolua_ret = (Vector3d) self->NormalizeCopy(); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'NormalizeCopy'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: NormalizeCopy of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_NormalizeCopy01 +static int tolua_AllToLua_Vector3d_NormalizeCopy01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); + Vector3d* a_V = ((Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NormalizeCopy'", NULL); +#endif + { + self->NormalizeCopy(*a_V); + } + } + return 0; +tolua_lerror: + return tolua_AllToLua_Vector3d_NormalizeCopy00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Length of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Length00 +static int tolua_AllToLua_Vector3d_Length00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Length'", NULL); +#endif + { + double tolua_ret = (double) self->Length(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Length'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SqrLength of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_SqrLength00 +static int tolua_AllToLua_Vector3d_SqrLength00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SqrLength'", NULL); +#endif + { + double tolua_ret = (double) self->SqrLength(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SqrLength'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Dot of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Dot00 +static int tolua_AllToLua_Vector3d_Dot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const Vector3d* a_V = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Dot'", NULL); +#endif + { + double tolua_ret = (double) self->Dot(*a_V); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Dot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Cross of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Cross00 +static int tolua_AllToLua_Vector3d_Cross00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Cross'", NULL); +#endif + { + Vector3d tolua_ret = (Vector3d) self->Cross(*v); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Cross'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Equals of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Equals00 +static int tolua_AllToLua_Vector3d_Equals00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Equals'", NULL); +#endif + { + bool tolua_ret = (bool) self->Equals(*v); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Equals'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator+ of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__add00 +static int tolua_AllToLua_Vector3d__add00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const Vector3d* v2 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator+'", NULL); +#endif + { + Vector3d tolua_ret = (Vector3d) self->operator+(*v2); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function '.add'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator+ of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__add01 +static int tolua_AllToLua_Vector3d__add01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const Vector3d* v2 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator+'", NULL); +#endif + { + Vector3d tolua_ret = (Vector3d) self->operator+(v2); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3d__add00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator- of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__sub00 +static int tolua_AllToLua_Vector3d__sub00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const Vector3d* v2 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator-'", NULL); +#endif + { + Vector3d tolua_ret = (Vector3d) self->operator-(*v2); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function '.sub'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator- of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__sub01 +static int tolua_AllToLua_Vector3d__sub01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const Vector3d* v2 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator-'", NULL); +#endif + { + Vector3d tolua_ret = (Vector3d) self->operator-(v2); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3d__sub00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator* of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__mul00 +static int tolua_AllToLua_Vector3d__mul00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const double f = ((const double) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator*'", NULL); +#endif + { + Vector3d tolua_ret = (Vector3d) self->operator*(f); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function '.mul'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator* of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__mul01 +static int tolua_AllToLua_Vector3d__mul01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const Vector3d* v2 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator*'", NULL); +#endif + { + Vector3d tolua_ret = (Vector3d) self->operator*(*v2); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3d__mul00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: x of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3d_x +static int tolua_get_Vector3d_x(lua_State* tolua_S) +{ + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->x); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: x of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_set_Vector3d_x +static int tolua_set_Vector3d_x(lua_State* tolua_S) +{ + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->x = ((double) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: y of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3d_y +static int tolua_get_Vector3d_y(lua_State* tolua_S) +{ + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->y); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: y of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_set_Vector3d_y +static int tolua_set_Vector3d_y(lua_State* tolua_S) +{ + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->y = ((double) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: z of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3d_z +static int tolua_get_Vector3d_z(lua_State* tolua_S) +{ + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->z); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: z of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_set_Vector3d_z +static int tolua_set_Vector3d_z(lua_State* tolua_S) +{ + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->z = ((double) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new00 +static int tolua_AllToLua_Vector3i_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + { + Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)(*v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new00_local +static int tolua_AllToLua_Vector3i_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + { + Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)(*v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new01 +static int tolua_AllToLua_Vector3i_new01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else + { + { + Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3i_new00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new01_local +static int tolua_AllToLua_Vector3i_new01_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else + { + { + Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3i_new00_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new02 +static int tolua_AllToLua_Vector3i_new02(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + int a_x = ((int) tolua_tonumber(tolua_S,2,0)); + int a_y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_z = ((int) tolua_tonumber(tolua_S,4,0)); + { + Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)(a_x,a_y,a_z)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3i_new01(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new02_local +static int tolua_AllToLua_Vector3i_new02_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + int a_x = ((int) tolua_tonumber(tolua_S,2,0)); + int a_y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_z = ((int) tolua_tonumber(tolua_S,4,0)); + { + Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)(a_x,a_y,a_z)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3i_new01_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Set of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_Set00 +static int tolua_AllToLua_Vector3i_Set00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Vector3i",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); + int a_x = ((int) tolua_tonumber(tolua_S,2,0)); + int a_y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_z = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Set'", NULL); +#endif + { + self->Set(a_x,a_y,a_z); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Set'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Length of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_Length00 +static int tolua_AllToLua_Vector3i_Length00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3i",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3i* self = (const Vector3i*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Length'", NULL); +#endif + { + float tolua_ret = (float) self->Length(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Length'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SqrLength of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_SqrLength00 +static int tolua_AllToLua_Vector3i_SqrLength00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3i",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3i* self = (const Vector3i*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SqrLength'", NULL); +#endif + { + int tolua_ret = (int) self->SqrLength(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SqrLength'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Equals of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_Equals00 +static int tolua_AllToLua_Vector3i_Equals00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3i",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3i* self = (const Vector3i*) tolua_tousertype(tolua_S,1,0); + const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Equals'", NULL); +#endif + { + bool tolua_ret = (bool) self->Equals(*v); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Equals'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Equals of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_Equals01 +static int tolua_AllToLua_Vector3i_Equals01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3i",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3i* self = (const Vector3i*) tolua_tousertype(tolua_S,1,0); + const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Equals'", NULL); +#endif + { + bool tolua_ret = (bool) self->Equals(v); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3i_Equals00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: x of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3i_x +static int tolua_get_Vector3i_x(lua_State* tolua_S) +{ + Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->x); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: x of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_set_Vector3i_x +static int tolua_set_Vector3i_x(lua_State* tolua_S) +{ + Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->x = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: y of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3i_y +static int tolua_get_Vector3i_y(lua_State* tolua_S) +{ + Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->y); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: y of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_set_Vector3i_y +static int tolua_set_Vector3i_y(lua_State* tolua_S) +{ + Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->y = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: z of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3i_z +static int tolua_get_Vector3i_z(lua_State* tolua_S) +{ + Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->z); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: z of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_set_Vector3i_z +static int tolua_set_Vector3i_z(lua_State* tolua_S) +{ + Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->z = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new00 +static int tolua_AllToLua_cCuboid_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new00_local +static int tolua_AllToLua_cCuboid_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new01 +static int tolua_AllToLua_cCuboid_new01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cCuboid",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const cCuboid* a_Cuboid = ((const cCuboid*) tolua_tousertype(tolua_S,2,0)); + { + cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)(*a_Cuboid)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cCuboid_new00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new01_local +static int tolua_AllToLua_cCuboid_new01_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cCuboid",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const cCuboid* a_Cuboid = ((const cCuboid*) tolua_tousertype(tolua_S,2,0)); + { + cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)(*a_Cuboid)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cCuboid_new00_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new02 +static int tolua_AllToLua_cCuboid_new02(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3i",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3i* a_p1 = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); + const Vector3i* a_p2 = ((const Vector3i*) tolua_tousertype(tolua_S,3,0)); + { + cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)(*a_p1,*a_p2)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cCuboid_new01(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new02_local +static int tolua_AllToLua_cCuboid_new02_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3i",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3i* a_p1 = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); + const Vector3i* a_p2 = ((const Vector3i*) tolua_tousertype(tolua_S,3,0)); + { + cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)(*a_p1,*a_p2)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cCuboid_new01_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: p1 of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_get_cCuboid_p1 +static int tolua_get_cCuboid_p1(lua_State* tolua_S) +{ + cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'p1'",NULL); +#endif + tolua_pushusertype(tolua_S,(void*)&self->p1,"Vector3i"); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: p1 of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_set_cCuboid_p1 +static int tolua_set_cCuboid_p1(lua_State* tolua_S) +{ + cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'p1'",NULL); + if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3i",0,&tolua_err))) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->p1 = *((Vector3i*) tolua_tousertype(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: p2 of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_get_cCuboid_p2 +static int tolua_get_cCuboid_p2(lua_State* tolua_S) +{ + cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'p2'",NULL); +#endif + tolua_pushusertype(tolua_S,(void*)&self->p2,"Vector3i"); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: p2 of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_set_cCuboid_p2 +static int tolua_set_cCuboid_p2(lua_State* tolua_S) +{ + cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'p2'",NULL); + if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3i",0,&tolua_err))) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->p2 = *((Vector3i*) tolua_tousertype(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Sort of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_Sort00 +static int tolua_AllToLua_cCuboid_Sort00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCuboid",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Sort'", NULL); +#endif + { + self->Sort(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Sort'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsInside of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_IsInside00 +static int tolua_AllToLua_cCuboid_IsInside00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cCuboid",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cCuboid* self = (const cCuboid*) tolua_tousertype(tolua_S,1,0); + const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsInside'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsInside(*v); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsInside'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsInside of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_IsInside01 +static int tolua_AllToLua_cCuboid_IsInside01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cCuboid",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const cCuboid* self = (const cCuboid*) tolua_tousertype(tolua_S,1,0); + const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsInside'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsInside(*v); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cCuboid_IsInside00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cMCLogger */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cMCLogger_new00 +static int tolua_AllToLua_cMCLogger_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cMCLogger",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + char* a_File = ((char*) tolua_tostring(tolua_S,2,0)); + { + cMCLogger* tolua_ret = (cMCLogger*) Mtolua_new((cMCLogger)(a_File)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cMCLogger"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cMCLogger */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cMCLogger_new00_local +static int tolua_AllToLua_cMCLogger_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cMCLogger",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + char* a_File = ((char*) tolua_tostring(tolua_S,2,0)); + { + cMCLogger* tolua_ret = (cMCLogger*) Mtolua_new((cMCLogger)(a_File)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cMCLogger"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class cMCLogger */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cMCLogger_delete00 +static int tolua_AllToLua_cMCLogger_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cMCLogger",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cMCLogger* self = (cMCLogger*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: LogSimple of class cMCLogger */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cMCLogger_LogSimple00 +static int tolua_AllToLua_cMCLogger_LogSimple00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cMCLogger",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,1,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cMCLogger* self = (cMCLogger*) tolua_tousertype(tolua_S,1,0); + const char* a_Text = ((const char*) tolua_tostring(tolua_S,2,0)); + int a_LogType = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'LogSimple'", NULL); +#endif + { + self->LogSimple(a_Text,a_LogType); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'LogSimple'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_new00 +static int tolua_AllToLua_cTracer_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cTracer",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); + { + cTracer* tolua_ret = (cTracer*) Mtolua_new((cTracer)(a_World)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cTracer"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_new00_local +static int tolua_AllToLua_cTracer_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cTracer",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); + { + cTracer* tolua_ret = (cTracer*) Mtolua_new((cTracer)(a_World)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cTracer"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_delete00 +static int tolua_AllToLua_cTracer_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cTracer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Trace of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_Trace00 +static int tolua_AllToLua_cTracer_Trace00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cTracer",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3f",0,&tolua_err)) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); + const Vector3f* a_Start = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); + const Vector3f* a_Direction = ((const Vector3f*) tolua_tousertype(tolua_S,3,0)); + int a_Distance = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Trace'", NULL); +#endif + { + int tolua_ret = (int) self->Trace(*a_Start,*a_Direction,a_Distance); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Trace'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetValues of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_SetValues00 +static int tolua_AllToLua_cTracer_SetValues00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cTracer",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); + const Vector3f* a_Start = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); + const Vector3f* a_Direction = ((const Vector3f*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValues'", NULL); +#endif + { + self->SetValues(*a_Start,*a_Direction); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetValues'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: BlockHitPosition of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_get_cTracer_BlockHitPosition +static int tolua_get_cTracer_BlockHitPosition(lua_State* tolua_S) +{ + cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'BlockHitPosition'",NULL); +#endif + tolua_pushusertype(tolua_S,(void*)&self->BlockHitPosition,"Vector3f"); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: BlockHitPosition of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_set_cTracer_BlockHitPosition +static int tolua_set_cTracer_BlockHitPosition(lua_State* tolua_S) +{ + cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'BlockHitPosition'",NULL); + if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3f",0,&tolua_err))) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->BlockHitPosition = *((Vector3f*) tolua_tousertype(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: HitNormal of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_get_cTracer_HitNormal +static int tolua_get_cTracer_HitNormal(lua_State* tolua_S) +{ + cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'HitNormal'",NULL); +#endif + tolua_pushusertype(tolua_S,(void*)&self->HitNormal,"Vector3f"); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: HitNormal of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_set_cTracer_HitNormal +static int tolua_set_cTracer_HitNormal(lua_State* tolua_S) +{ + cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'HitNormal'",NULL); + if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3f",0,&tolua_err))) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->HitNormal = *((Vector3f*) tolua_tousertype(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: RealHit of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_get_cTracer_RealHit +static int tolua_get_cTracer_RealHit(lua_State* tolua_S) +{ + cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'RealHit'",NULL); +#endif + tolua_pushusertype(tolua_S,(void*)&self->RealHit,"Vector3f"); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: RealHit of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_set_cTracer_RealHit +static int tolua_set_cTracer_RealHit(lua_State* tolua_S) +{ + cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'RealHit'",NULL); + if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3f",0,&tolua_err))) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->RealHit = *((Vector3f*) tolua_tousertype(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetName of class cGroup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_SetName00 +static int tolua_AllToLua_cGroup_SetName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0); + std::string a_Name = ((std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetName'", NULL); +#endif + { + self->SetName(a_Name); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetName of class cGroup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_GetName00 +static int tolua_AllToLua_cGroup_GetName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cGroup",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cGroup* self = (const cGroup*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL); +#endif + { + const std::string tolua_ret = (const std::string) self->GetName(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetColor of class cGroup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_SetColor00 +static int tolua_AllToLua_cGroup_SetColor00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0); + std::string a_Color = ((std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetColor'", NULL); +#endif + { + self->SetColor(a_Color); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetColor'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: AddCommand of class cGroup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_AddCommand00 +static int tolua_AllToLua_cGroup_AddCommand00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0); + std::string a_Command = ((std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddCommand'", NULL); +#endif + { + self->AddCommand(a_Command); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'AddCommand'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: AddPermission of class cGroup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_AddPermission00 +static int tolua_AllToLua_cGroup_AddPermission00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0); + std::string a_Permission = ((std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddPermission'", NULL); +#endif + { + self->AddPermission(a_Permission); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'AddPermission'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: InheritFrom of class cGroup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_InheritFrom00 +static int tolua_AllToLua_cGroup_InheritFrom00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cGroup",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0); + cGroup* a_Group = ((cGroup*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'InheritFrom'", NULL); +#endif + { + self->InheritFrom(a_Group); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'InheritFrom'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: HasCommand of class cGroup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_HasCommand00 +static int tolua_AllToLua_cGroup_HasCommand00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0); + std::string a_Command = ((std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HasCommand'", NULL); +#endif + { + bool tolua_ret = (bool) self->HasCommand(a_Command); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'HasCommand'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetColor of class cGroup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_GetColor00 +static int tolua_AllToLua_cGroup_GetColor00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cGroup",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cGroup* self = (const cGroup*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetColor'", NULL); +#endif + { + const AString tolua_ret = (const AString) self->GetColor(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetColor'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_ProtocolVersion of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_m_ProtocolVersion +static int tolua_get_cPacket_Login_m_ProtocolVersion(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ProtocolVersion'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_ProtocolVersion); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_ProtocolVersion of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_m_ProtocolVersion +static int tolua_set_cPacket_Login_m_ProtocolVersion(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ProtocolVersion'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_ProtocolVersion = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_Username of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_m_Username +static int tolua_get_cPacket_Login_m_Username(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Username'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->m_Username); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_Username of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_m_Username +static int tolua_set_cPacket_Login_m_Username(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Username'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_Username = ((AString) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_LevelType of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_m_LevelType +static int tolua_get_cPacket_Login_m_LevelType(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_LevelType'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->m_LevelType); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_LevelType of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_m_LevelType +static int tolua_set_cPacket_Login_m_LevelType(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_LevelType'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_LevelType = ((AString) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_ServerMode of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_m_ServerMode +static int tolua_get_cPacket_Login_m_ServerMode(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ServerMode'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_ServerMode); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_ServerMode of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_m_ServerMode +static int tolua_set_cPacket_Login_m_ServerMode(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ServerMode'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_ServerMode = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_Difficulty of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_m_Difficulty +static int tolua_get_cPacket_Login_m_Difficulty(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Difficulty'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_Difficulty); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_Difficulty of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_m_Difficulty +static int tolua_set_cPacket_Login_m_Difficulty(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Difficulty'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_Difficulty = ((char) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_WorldHeight of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_unsigned_m_WorldHeight +static int tolua_get_cPacket_Login_unsigned_m_WorldHeight(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_WorldHeight'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_WorldHeight); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_WorldHeight of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_unsigned_m_WorldHeight +static int tolua_set_cPacket_Login_unsigned_m_WorldHeight(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_WorldHeight'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_WorldHeight = ((unsigned char) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_MaxPlayers of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_unsigned_m_MaxPlayers +static int tolua_get_cPacket_Login_unsigned_m_MaxPlayers(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_MaxPlayers'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_MaxPlayers); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_MaxPlayers of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_unsigned_m_MaxPlayers +static int tolua_set_cPacket_Login_unsigned_m_MaxPlayers(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_MaxPlayers'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_MaxPlayers = ((unsigned char) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPacket_BlockDig_new00 +static int tolua_AllToLua_cPacket_BlockDig_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cPacket_BlockDig",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + cPacket_BlockDig* tolua_ret = (cPacket_BlockDig*) Mtolua_new((cPacket_BlockDig)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPacket_BlockDig"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPacket_BlockDig_new00_local +static int tolua_AllToLua_cPacket_BlockDig_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cPacket_BlockDig",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + cPacket_BlockDig* tolua_ret = (cPacket_BlockDig*) Mtolua_new((cPacket_BlockDig)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPacket_BlockDig"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Clone of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPacket_BlockDig_Clone00 +static int tolua_AllToLua_cPacket_BlockDig_Clone00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cPacket_BlockDig",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cPacket_BlockDig* self = (const cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clone'", NULL); +#endif + { + cPacket* tolua_ret = (cPacket*) self->Clone(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPacket"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Clone'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_Status of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockDig_m_Status +static int tolua_get_cPacket_BlockDig_m_Status(lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Status'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_Status); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_Status of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockDig_m_Status +static int tolua_set_cPacket_BlockDig_m_Status(lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Status'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_Status = ((char) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_PosX of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockDig_m_PosX +static int tolua_get_cPacket_BlockDig_m_PosX(lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosX'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_PosX); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_PosX of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockDig_m_PosX +static int tolua_set_cPacket_BlockDig_m_PosX(lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosX'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_PosX = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_PosY of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockDig_m_PosY +static int tolua_get_cPacket_BlockDig_m_PosY(lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosY'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_PosY); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_PosY of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockDig_m_PosY +static int tolua_set_cPacket_BlockDig_m_PosY(lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosY'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_PosY = ((char) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_PosZ of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockDig_m_PosZ +static int tolua_get_cPacket_BlockDig_m_PosZ(lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosZ'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_PosZ); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_PosZ of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockDig_m_PosZ +static int tolua_set_cPacket_BlockDig_m_PosZ(lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosZ'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_PosZ = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_Direction of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockDig_m_Direction +static int tolua_get_cPacket_BlockDig_m_Direction(lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Direction'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_Direction); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_Direction of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockDig_m_Direction +static int tolua_set_cPacket_BlockDig_m_Direction(lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Direction'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_Direction = ((char) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + + class Lua__cPacket_BlockDig : public cPacket_BlockDig, public ToluaBase { +public: + cPacket* Clone( void )const { + if (push_method("Clone", tolua_AllToLua_cPacket_BlockDig_Clone00)) { + ToluaBase::dbcall(lua_state, 1, 1); + cPacket* tolua_ret = ( cPacket* )tolua_tousertype(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( cPacket* ) cPacket_BlockDig:: Clone(); + }; + }; + + cPacket* cPacket_BlockDig__Clone( void ) { + return ( cPacket* )cPacket_BlockDig::Clone(); + }; + Lua__cPacket_BlockDig( void ): cPacket_BlockDig(){}; +}; + +/* method: tolua__set_instance of class Lua__cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPacket_BlockDig_tolua__set_instance00 +static int tolua_AllToLua_Lua__cPacket_BlockDig_tolua__set_instance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPacket_BlockDig",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPacket_BlockDig* self = (Lua__cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); + lua_State* L = tolua_S; + lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); +#endif + { + self->tolua__set_instance(L,lo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPacket_BlockDig__Clone of class Lua__cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPacket_BlockDig_cPacket_BlockDig__Clone00 +static int tolua_AllToLua_Lua__cPacket_BlockDig_cPacket_BlockDig__Clone00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPacket_BlockDig",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPacket_BlockDig* self = (Lua__cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPacket_BlockDig__Clone'", NULL); +#endif + { + cPacket* tolua_ret = (cPacket*) self->cPacket_BlockDig__Clone(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPacket"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPacket_BlockDig__Clone'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Lua__cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPacket_BlockDig_new00 +static int tolua_AllToLua_Lua__cPacket_BlockDig_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cPacket_BlockDig",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + Lua__cPacket_BlockDig* tolua_ret = (Lua__cPacket_BlockDig*) Mtolua_new((Lua__cPacket_BlockDig)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPacket_BlockDig"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Lua__cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPacket_BlockDig_new00_local +static int tolua_AllToLua_Lua__cPacket_BlockDig_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cPacket_BlockDig",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + Lua__cPacket_BlockDig* tolua_ret = (Lua__cPacket_BlockDig*) Mtolua_new((Lua__cPacket_BlockDig)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPacket_BlockDig"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + +/* function to release collected object via destructor */ +#ifdef __cplusplus + +static int tolua_collect_Lua__cPacket_BlockDig (lua_State* tolua_S) +{ + Lua__cPacket_BlockDig* self = (Lua__cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); + delete self; + return 0; +} +#endif + +/* get function: m_PosX of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_PosX +static int tolua_get_cPacket_BlockPlace_m_PosX(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosX'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_PosX); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_PosX of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_PosX +static int tolua_set_cPacket_BlockPlace_m_PosX(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosX'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_PosX = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_PosY of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_unsigned_m_PosY +static int tolua_get_cPacket_BlockPlace_unsigned_m_PosY(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosY'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_PosY); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_PosY of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_unsigned_m_PosY +static int tolua_set_cPacket_BlockPlace_unsigned_m_PosY(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosY'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_PosY = ((unsigned char) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_PosZ of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_PosZ +static int tolua_get_cPacket_BlockPlace_m_PosZ(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosZ'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_PosZ); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_PosZ of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_PosZ +static int tolua_set_cPacket_BlockPlace_m_PosZ(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosZ'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_PosZ = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_Direction of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_Direction +static int tolua_get_cPacket_BlockPlace_m_Direction(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Direction'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_Direction); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_Direction of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_Direction +static int tolua_set_cPacket_BlockPlace_m_Direction(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Direction'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_Direction = ((char) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_ItemType of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_ItemType +static int tolua_get_cPacket_BlockPlace_m_ItemType(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemType'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_ItemType); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_ItemType of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_ItemType +static int tolua_set_cPacket_BlockPlace_m_ItemType(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemType'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_ItemType = ((short) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_Count of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_Count +static int tolua_get_cPacket_BlockPlace_m_Count(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Count'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_Count); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_Count of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_Count +static int tolua_set_cPacket_BlockPlace_m_Count(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Count'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_Count = ((char) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_Uses of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_Uses +static int tolua_get_cPacket_BlockPlace_m_Uses(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Uses'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_Uses); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_Uses of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_Uses +static int tolua_set_cPacket_BlockPlace_m_Uses(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Uses'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_Uses = ((short) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: FillBlocks of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_FillBlocks00 +static int tolua_AllToLua_cLuaChunk_FillBlocks00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + char a_BlockID = ((char) tolua_tonumber(tolua_S,2,0)); + unsigned char a_BlockMeta = ((unsigned char) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'FillBlocks'", NULL); +#endif + { + self->FillBlocks(a_BlockID,a_BlockMeta); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'FillBlocks'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetBlock of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetBlock00 +static int tolua_AllToLua_cLuaChunk_SetBlock00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnoobj(tolua_S,7,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); + char a_BlockID = ((char) tolua_tonumber(tolua_S,5,0)); + unsigned char a_BlockMeta = ((unsigned char) tolua_tonumber(tolua_S,6,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBlock'", NULL); +#endif + { + self->SetBlock(a_X,a_Y,a_Z,a_BlockID,a_BlockMeta); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetBlock'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBlock of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_GetBlock00 +static int tolua_AllToLua_cLuaChunk_GetBlock00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlock'", NULL); +#endif + { + char tolua_ret = (char) self->GetBlock(a_X,a_Y,a_Z); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetBlock'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBlockMeta of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_GetBlockMeta00 +static int tolua_AllToLua_cLuaChunk_GetBlockMeta00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockMeta'", NULL); +#endif + { + char tolua_ret = (char) self->GetBlockMeta(a_X,a_Y,a_Z); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetBlockMeta'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetBiome of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetBiome00 +static int tolua_AllToLua_cLuaChunk_SetBiome00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,3,0)); + int a_BiomeID = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBiome'", NULL); +#endif + { + self->SetBiome(a_X,a_Z,a_BiomeID); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetBiome'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBiome of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_GetBiome00 +static int tolua_AllToLua_cLuaChunk_GetBiome00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBiome'", NULL); +#endif + { + int tolua_ret = (int) self->GetBiome(a_X,a_Z); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetBiome'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetHeight of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetHeight00 +static int tolua_AllToLua_cLuaChunk_SetHeight00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Height = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetHeight'", NULL); +#endif + { + self->SetHeight(a_X,a_Z,a_Height); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetHeight'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetHeight of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_GetHeight00 +static int tolua_AllToLua_cLuaChunk_GetHeight00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHeight'", NULL); +#endif + { + int tolua_ret = (int) self->GetHeight(a_X,a_Z); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetHeight'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetUseDefaultBiomes of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetUseDefaultBiomes00 +static int tolua_AllToLua_cLuaChunk_SetUseDefaultBiomes00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isboolean(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + bool a_bUseDefaultBiomes = ((bool) tolua_toboolean(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetUseDefaultBiomes'", NULL); +#endif + { + self->SetUseDefaultBiomes(a_bUseDefaultBiomes); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetUseDefaultBiomes'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsUsingDefaultBiomes of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_IsUsingDefaultBiomes00 +static int tolua_AllToLua_cLuaChunk_IsUsingDefaultBiomes00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsUsingDefaultBiomes'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsUsingDefaultBiomes(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsUsingDefaultBiomes'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetUseDefaultComposition of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetUseDefaultComposition00 +static int tolua_AllToLua_cLuaChunk_SetUseDefaultComposition00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isboolean(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + bool a_bUseDefaultComposition = ((bool) tolua_toboolean(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetUseDefaultComposition'", NULL); +#endif + { + self->SetUseDefaultComposition(a_bUseDefaultComposition); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetUseDefaultComposition'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsUsingDefaultComposition of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_IsUsingDefaultComposition00 +static int tolua_AllToLua_cLuaChunk_IsUsingDefaultComposition00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsUsingDefaultComposition'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsUsingDefaultComposition(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsUsingDefaultComposition'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetUseDefaultStructures of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetUseDefaultStructures00 +static int tolua_AllToLua_cLuaChunk_SetUseDefaultStructures00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isboolean(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + bool a_bUseDefaultStructures = ((bool) tolua_toboolean(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetUseDefaultStructures'", NULL); +#endif + { + self->SetUseDefaultStructures(a_bUseDefaultStructures); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetUseDefaultStructures'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsUsingDefaultStructures of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_IsUsingDefaultStructures00 +static int tolua_AllToLua_cLuaChunk_IsUsingDefaultStructures00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsUsingDefaultStructures'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsUsingDefaultStructures(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsUsingDefaultStructures'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetUseDefaultFinish of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetUseDefaultFinish00 +static int tolua_AllToLua_cLuaChunk_SetUseDefaultFinish00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isboolean(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + bool a_bUseDefaultFinish = ((bool) tolua_toboolean(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetUseDefaultFinish'", NULL); +#endif + { + self->SetUseDefaultFinish(a_bUseDefaultFinish); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetUseDefaultFinish'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsUsingDefaultFinish of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_IsUsingDefaultFinish00 +static int tolua_AllToLua_cLuaChunk_IsUsingDefaultFinish00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsUsingDefaultFinish'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsUsingDefaultFinish(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsUsingDefaultFinish'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cCraftingGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_new00 +static int tolua_AllToLua_cCraftingGrid_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cCraftingGrid",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + int a_Width = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Height = ((int) tolua_tonumber(tolua_S,3,0)); + { + cCraftingGrid* tolua_ret = (cCraftingGrid*) Mtolua_new((cCraftingGrid)(a_Width,a_Height)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCraftingGrid"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cCraftingGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_new00_local +static int tolua_AllToLua_cCraftingGrid_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cCraftingGrid",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + int a_Width = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Height = ((int) tolua_tonumber(tolua_S,3,0)); + { + cCraftingGrid* tolua_ret = (cCraftingGrid*) Mtolua_new((cCraftingGrid)(a_Width,a_Height)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCraftingGrid"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetWidth of class cCraftingGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_GetWidth00 +static int tolua_AllToLua_cCraftingGrid_GetWidth00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cCraftingGrid",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cCraftingGrid* self = (const cCraftingGrid*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWidth'", NULL); +#endif + { + int tolua_ret = (int) self->GetWidth(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetWidth'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetHeight of class cCraftingGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_GetHeight00 +static int tolua_AllToLua_cCraftingGrid_GetHeight00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cCraftingGrid",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cCraftingGrid* self = (const cCraftingGrid*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHeight'", NULL); +#endif + { + int tolua_ret = (int) self->GetHeight(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetHeight'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetItem of class cCraftingGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_GetItem00 +static int tolua_AllToLua_cCraftingGrid_GetItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cCraftingGrid",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cCraftingGrid* self = (const cCraftingGrid*) tolua_tousertype(tolua_S,1,0); + int x = ((int) tolua_tonumber(tolua_S,2,0)); + int y = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetItem'", NULL); +#endif + { + cItem& tolua_ret = (cItem&) self->GetItem(x,y); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetItem of class cCraftingGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_SetItem00 +static int tolua_AllToLua_cCraftingGrid_SetItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingGrid",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnoobj(tolua_S,7,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0); + int x = ((int) tolua_tonumber(tolua_S,2,0)); + int y = ((int) tolua_tonumber(tolua_S,3,0)); + ENUM_ITEM_ID a_ItemType = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,4,0)); + int a_ItemCount = ((int) tolua_tonumber(tolua_S,5,0)); + short a_ItemHealth = ((short) tolua_tonumber(tolua_S,6,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetItem'", NULL); +#endif + { + self->SetItem(x,y,a_ItemType,a_ItemCount,a_ItemHealth); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetItem of class cCraftingGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_SetItem01 +static int tolua_AllToLua_cCraftingGrid_SetItem01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingGrid",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + (tolua_isvaluenil(tolua_S,4,&tolua_err) || !tolua_isusertype(tolua_S,4,"const cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0); + int x = ((int) tolua_tonumber(tolua_S,2,0)); + int y = ((int) tolua_tonumber(tolua_S,3,0)); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetItem'", NULL); +#endif + { + self->SetItem(x,y,*a_Item); + } + } + return 0; +tolua_lerror: + return tolua_AllToLua_cCraftingGrid_SetItem00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Clear of class cCraftingGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_Clear00 +static int tolua_AllToLua_cCraftingGrid_Clear00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingGrid",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL); +#endif + { + self->Clear(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: ConsumeGrid of class cCraftingGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_ConsumeGrid00 +static int tolua_AllToLua_cCraftingGrid_ConsumeGrid00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingGrid",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cCraftingGrid",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0); + const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ConsumeGrid'", NULL); +#endif + { + self->ConsumeGrid(*a_Grid); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'ConsumeGrid'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Dump of class cCraftingGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_Dump00 +static int tolua_AllToLua_cCraftingGrid_Dump00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingGrid",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Dump'", NULL); +#endif + { + self->Dump(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Dump'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Clear of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_Clear00 +static int tolua_AllToLua_cCraftingRecipe_Clear00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL); +#endif + { + self->Clear(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetIngredientsWidth of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_GetIngredientsWidth00 +static int tolua_AllToLua_cCraftingRecipe_GetIngredientsWidth00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cCraftingRecipe* self = (const cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetIngredientsWidth'", NULL); +#endif + { + int tolua_ret = (int) self->GetIngredientsWidth(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetIngredientsWidth'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetIngredientsHeight of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_GetIngredientsHeight00 +static int tolua_AllToLua_cCraftingRecipe_GetIngredientsHeight00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cCraftingRecipe* self = (const cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetIngredientsHeight'", NULL); +#endif + { + int tolua_ret = (int) self->GetIngredientsHeight(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetIngredientsHeight'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetIngredient of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_GetIngredient00 +static int tolua_AllToLua_cCraftingRecipe_GetIngredient00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cCraftingRecipe",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cCraftingRecipe* self = (const cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); + int x = ((int) tolua_tonumber(tolua_S,2,0)); + int y = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetIngredient'", NULL); +#endif + { + cItem& tolua_ret = (cItem&) self->GetIngredient(x,y); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetIngredient'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetResult of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_GetResult00 +static int tolua_AllToLua_cCraftingRecipe_GetResult00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cCraftingRecipe* self = (const cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetResult'", NULL); +#endif + { + const cItem& tolua_ret = (const cItem&) self->GetResult(); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetResult'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetResult of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_SetResult00 +static int tolua_AllToLua_cCraftingRecipe_SetResult00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); + ENUM_ITEM_ID a_ItemType = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,0)); + int a_ItemCount = ((int) tolua_tonumber(tolua_S,3,0)); + short a_ItemHealth = ((short) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetResult'", NULL); +#endif + { + self->SetResult(a_ItemType,a_ItemCount,a_ItemHealth); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetResult'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetResult of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_SetResult01 +static int tolua_AllToLua_cCraftingRecipe_SetResult01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetResult'", NULL); +#endif + { + self->SetResult(*a_Item); + } + } + return 0; +tolua_lerror: + return tolua_AllToLua_cCraftingRecipe_SetResult00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetIngredient of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_SetIngredient00 +static int tolua_AllToLua_cCraftingRecipe_SetIngredient00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnoobj(tolua_S,7,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); + int x = ((int) tolua_tonumber(tolua_S,2,0)); + int y = ((int) tolua_tonumber(tolua_S,3,0)); + ENUM_ITEM_ID a_ItemType = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,4,0)); + int a_ItemCount = ((int) tolua_tonumber(tolua_S,5,0)); + short a_ItemHealth = ((short) tolua_tonumber(tolua_S,6,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetIngredient'", NULL); +#endif + { + self->SetIngredient(x,y,a_ItemType,a_ItemCount,a_ItemHealth); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetIngredient'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetIngredient of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_SetIngredient01 +static int tolua_AllToLua_cCraftingRecipe_SetIngredient01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + (tolua_isvaluenil(tolua_S,4,&tolua_err) || !tolua_isusertype(tolua_S,4,"const cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); + int x = ((int) tolua_tonumber(tolua_S,2,0)); + int y = ((int) tolua_tonumber(tolua_S,3,0)); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetIngredient'", NULL); +#endif + { + self->SetIngredient(x,y,*a_Item); + } + } + return 0; +tolua_lerror: + return tolua_AllToLua_cCraftingRecipe_SetIngredient00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: ConsumeIngredients of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_ConsumeIngredients00 +static int tolua_AllToLua_cCraftingRecipe_ConsumeIngredients00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cCraftingGrid",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); + cCraftingGrid* a_CraftingGrid = ((cCraftingGrid*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ConsumeIngredients'", NULL); +#endif + { + self->ConsumeIngredients(*a_CraftingGrid); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'ConsumeIngredients'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Dump of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_Dump00 +static int tolua_AllToLua_cCraftingRecipe_Dump00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Dump'", NULL); +#endif + { + self->Dump(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Dump'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Get of class cLuaItems */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Get00 +static int tolua_AllToLua_cLuaItems_Get00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); + int a_Idx = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Get'", NULL); +#endif + { + cItem& tolua_ret = (cItem&) self->Get(a_Idx); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Get'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Set of class cLuaItems */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Set00 +static int tolua_AllToLua_cLuaItems_Set00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); + int a_Idx = ((int) tolua_tonumber(tolua_S,2,0)); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Set'", NULL); +#endif + { + self->Set(a_Idx,*a_Item); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Set'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Add of class cLuaItems */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Add00 +static int tolua_AllToLua_cLuaItems_Add00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Add'", NULL); +#endif + { + self->Add(*a_Item); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Add'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Delete of class cLuaItems */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Delete00 +static int tolua_AllToLua_cLuaItems_Delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); + int a_Idx = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Delete'", NULL); +#endif + { + self->Delete(a_Idx); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Clear of class cLuaItems */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Clear00 +static int tolua_AllToLua_cLuaItems_Clear00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL); +#endif + { + self->Clear(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Size of class cLuaItems */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Size00 +static int tolua_AllToLua_cLuaItems_Size00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Size'", NULL); +#endif + { + int tolua_ret = (int) self->Size(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Size'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Add of class cLuaItems */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Add01 +static int tolua_AllToLua_cLuaItems_Add01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); + ENUM_ITEM_ID a_ItemType = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,0)); + char a_ItemCount = ((char) tolua_tonumber(tolua_S,3,0)); + short a_ItemHealth = ((short) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Add'", NULL); +#endif + { + self->Add(a_ItemType,a_ItemCount,a_ItemHealth); + } + } + return 0; +tolua_lerror: + return tolua_AllToLua_cLuaItems_Add00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Set of class cLuaItems */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Set01 +static int tolua_AllToLua_cLuaItems_Set01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else + { + cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); + int a_Idx = ((int) tolua_tonumber(tolua_S,2,0)); + ENUM_ITEM_ID a_ItemType = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,3,0)); + char a_ItemCount = ((char) tolua_tonumber(tolua_S,4,0)); + short a_ItemHealth = ((short) tolua_tonumber(tolua_S,5,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Set'", NULL); +#endif + { + self->Set(a_Idx,a_ItemType,a_ItemCount,a_ItemHealth); + } + } + return 0; +tolua_lerror: + return tolua_AllToLua_cLuaItems_Set00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* Open function */ +TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) +{ + tolua_open(tolua_S); + tolua_reg_types(tolua_S); + tolua_module(tolua_S,NULL,1); + tolua_beginmodule(tolua_S,NULL); + tolua_cclass(tolua_S,"cTorch","cTorch","",NULL); + tolua_beginmodule(tolua_S,"cTorch"); + tolua_function(tolua_S,"DirectionToMetaData",tolua_AllToLua_cTorch_DirectionToMetaData00); + tolua_function(tolua_S,"MetaDataToDirection",tolua_AllToLua_cTorch_MetaDataToDirection00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cStairs","cStairs","",NULL); + tolua_beginmodule(tolua_S,"cStairs"); + tolua_function(tolua_S,"RotationToMetaData",tolua_AllToLua_cStairs_RotationToMetaData00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cStep","cStep","",NULL); + tolua_beginmodule(tolua_S,"cStep"); + tolua_function(tolua_S,"DirectionToMetaData",tolua_AllToLua_cStep_DirectionToMetaData00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cLadder","cLadder","",NULL); + tolua_beginmodule(tolua_S,"cLadder"); + tolua_function(tolua_S,"DirectionToMetaData",tolua_AllToLua_cLadder_DirectionToMetaData00); + tolua_function(tolua_S,"MetaDataToDirection",tolua_AllToLua_cLadder_MetaDataToDirection00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cIniFile","cIniFile","",tolua_collect_cIniFile); + #else + tolua_cclass(tolua_S,"cIniFile","cIniFile","",NULL); + #endif + tolua_beginmodule(tolua_S,"cIniFile"); + tolua_constant(tolua_S,"noID",cIniFile::noID); + tolua_function(tolua_S,"new",tolua_AllToLua_cIniFile_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cIniFile_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cIniFile_new00_local); + tolua_function(tolua_S,"CaseSensitive",tolua_AllToLua_cIniFile_CaseSensitive00); + tolua_function(tolua_S,"CaseInsensitive",tolua_AllToLua_cIniFile_CaseInsensitive00); + tolua_function(tolua_S,"Path",tolua_AllToLua_cIniFile_Path00); + tolua_function(tolua_S,"Path",tolua_AllToLua_cIniFile_Path01); + tolua_function(tolua_S,"SetPath",tolua_AllToLua_cIniFile_SetPath00); + tolua_function(tolua_S,"ReadFile",tolua_AllToLua_cIniFile_ReadFile00); + tolua_function(tolua_S,"WriteFile",tolua_AllToLua_cIniFile_WriteFile00); + tolua_function(tolua_S,"Erase",tolua_AllToLua_cIniFile_Erase00); + tolua_function(tolua_S,"Clear",tolua_AllToLua_cIniFile_Clear00); + tolua_function(tolua_S,"Reset",tolua_AllToLua_cIniFile_Reset00); + tolua_function(tolua_S,"FindKey",tolua_AllToLua_cIniFile_FindKey00); + tolua_function(tolua_S,"FindValue",tolua_AllToLua_cIniFile_FindValue00); + tolua_function(tolua_S,"NumKeys",tolua_AllToLua_cIniFile_NumKeys00); + tolua_function(tolua_S,"GetNumKeys",tolua_AllToLua_cIniFile_GetNumKeys00); + tolua_function(tolua_S,"AddKeyName",tolua_AllToLua_cIniFile_AddKeyName00); + tolua_function(tolua_S,"KeyName",tolua_AllToLua_cIniFile_KeyName00); + tolua_function(tolua_S,"GetKeyName",tolua_AllToLua_cIniFile_GetKeyName00); + tolua_function(tolua_S,"NumValues",tolua_AllToLua_cIniFile_NumValues00); + tolua_function(tolua_S,"GetNumValues",tolua_AllToLua_cIniFile_GetNumValues00); + tolua_function(tolua_S,"NumValues",tolua_AllToLua_cIniFile_NumValues01); + tolua_function(tolua_S,"GetNumValues",tolua_AllToLua_cIniFile_GetNumValues01); + tolua_function(tolua_S,"ValueName",tolua_AllToLua_cIniFile_ValueName00); + tolua_function(tolua_S,"GetValueName",tolua_AllToLua_cIniFile_GetValueName00); + tolua_function(tolua_S,"ValueName",tolua_AllToLua_cIniFile_ValueName01); + tolua_function(tolua_S,"GetValueName",tolua_AllToLua_cIniFile_GetValueName01); + tolua_function(tolua_S,"GetValue",tolua_AllToLua_cIniFile_GetValue00); + tolua_function(tolua_S,"GetValue",tolua_AllToLua_cIniFile_GetValue01); + tolua_function(tolua_S,"GetValue",tolua_AllToLua_cIniFile_GetValue02); + tolua_function(tolua_S,"GetValue",tolua_AllToLua_cIniFile_GetValue03); + tolua_function(tolua_S,"GetValueF",tolua_AllToLua_cIniFile_GetValueF00); + tolua_function(tolua_S,"GetValueI",tolua_AllToLua_cIniFile_GetValueI00); + tolua_function(tolua_S,"GetValueB",tolua_AllToLua_cIniFile_GetValueB00); + tolua_function(tolua_S,"GetValueSet",tolua_AllToLua_cIniFile_GetValueSet00); + tolua_function(tolua_S,"GetValueSet",tolua_AllToLua_cIniFile_GetValueSet01); + tolua_function(tolua_S,"GetValueSetF",tolua_AllToLua_cIniFile_GetValueSetF00); + tolua_function(tolua_S,"GetValueSetI",tolua_AllToLua_cIniFile_GetValueSetI00); + tolua_function(tolua_S,"GetValueSetB",tolua_AllToLua_cIniFile_GetValueSetB00); + tolua_function(tolua_S,"SetValue",tolua_AllToLua_cIniFile_SetValue00); + tolua_function(tolua_S,"SetValue",tolua_AllToLua_cIniFile_SetValue01); + tolua_function(tolua_S,"SetValueI",tolua_AllToLua_cIniFile_SetValueI00); + tolua_function(tolua_S,"SetValueB",tolua_AllToLua_cIniFile_SetValueB00); + tolua_function(tolua_S,"SetValueF",tolua_AllToLua_cIniFile_SetValueF00); + tolua_function(tolua_S,"DeleteValueByID",tolua_AllToLua_cIniFile_DeleteValueByID00); + tolua_function(tolua_S,"DeleteValue",tolua_AllToLua_cIniFile_DeleteValue00); + tolua_function(tolua_S,"DeleteKey",tolua_AllToLua_cIniFile_DeleteKey00); + tolua_function(tolua_S,"NumHeaderComments",tolua_AllToLua_cIniFile_NumHeaderComments00); + tolua_function(tolua_S,"HeaderComment",tolua_AllToLua_cIniFile_HeaderComment00); + tolua_function(tolua_S,"HeaderComment",tolua_AllToLua_cIniFile_HeaderComment01); + tolua_function(tolua_S,"DeleteHeaderComment",tolua_AllToLua_cIniFile_DeleteHeaderComment00); + tolua_function(tolua_S,"DeleteHeaderComments",tolua_AllToLua_cIniFile_DeleteHeaderComments00); + tolua_function(tolua_S,"NumKeyComments",tolua_AllToLua_cIniFile_NumKeyComments00); + tolua_function(tolua_S,"NumKeyComments",tolua_AllToLua_cIniFile_NumKeyComments01); + tolua_function(tolua_S,"KeyComment",tolua_AllToLua_cIniFile_KeyComment00); + tolua_function(tolua_S,"KeyComment",tolua_AllToLua_cIniFile_KeyComment01); + tolua_function(tolua_S,"KeyComment",tolua_AllToLua_cIniFile_KeyComment02); + tolua_function(tolua_S,"KeyComment",tolua_AllToLua_cIniFile_KeyComment03); + tolua_function(tolua_S,"DeleteKeyComment",tolua_AllToLua_cIniFile_DeleteKeyComment00); + tolua_function(tolua_S,"DeleteKeyComment",tolua_AllToLua_cIniFile_DeleteKeyComment01); + tolua_function(tolua_S,"DeleteKeyComments",tolua_AllToLua_cIniFile_DeleteKeyComments00); + tolua_function(tolua_S,"DeleteKeyComments",tolua_AllToLua_cIniFile_DeleteKeyComments01); + tolua_endmodule(tolua_S); + tolua_constant(tolua_S,"E_BLOCK_AIR",E_BLOCK_AIR); + tolua_constant(tolua_S,"E_BLOCK_STONE",E_BLOCK_STONE); + tolua_constant(tolua_S,"E_BLOCK_GRASS",E_BLOCK_GRASS); + tolua_constant(tolua_S,"E_BLOCK_DIRT",E_BLOCK_DIRT); + tolua_constant(tolua_S,"E_BLOCK_COBBLESTONE",E_BLOCK_COBBLESTONE); + tolua_constant(tolua_S,"E_BLOCK_PLANKS",E_BLOCK_PLANKS); + tolua_constant(tolua_S,"E_BLOCK_WOOD",E_BLOCK_WOOD); + tolua_constant(tolua_S,"E_BLOCK_SAPLING",E_BLOCK_SAPLING); + tolua_constant(tolua_S,"E_BLOCK_BEDROCK",E_BLOCK_BEDROCK); + tolua_constant(tolua_S,"E_BLOCK_WATER",E_BLOCK_WATER); + tolua_constant(tolua_S,"E_BLOCK_STATIONARY_WATER",E_BLOCK_STATIONARY_WATER); + tolua_constant(tolua_S,"E_BLOCK_LAVA",E_BLOCK_LAVA); + tolua_constant(tolua_S,"E_BLOCK_STATIONARY_LAVA",E_BLOCK_STATIONARY_LAVA); + tolua_constant(tolua_S,"E_BLOCK_SAND",E_BLOCK_SAND); + tolua_constant(tolua_S,"E_BLOCK_GRAVEL",E_BLOCK_GRAVEL); + tolua_constant(tolua_S,"E_BLOCK_GOLD_ORE",E_BLOCK_GOLD_ORE); + tolua_constant(tolua_S,"E_BLOCK_IRON_ORE",E_BLOCK_IRON_ORE); + tolua_constant(tolua_S,"E_BLOCK_COAL_ORE",E_BLOCK_COAL_ORE); + tolua_constant(tolua_S,"E_BLOCK_LOG",E_BLOCK_LOG); + tolua_constant(tolua_S,"E_BLOCK_LEAVES",E_BLOCK_LEAVES); + tolua_constant(tolua_S,"E_BLOCK_SPONGE",E_BLOCK_SPONGE); + tolua_constant(tolua_S,"E_BLOCK_GLASS",E_BLOCK_GLASS); + tolua_constant(tolua_S,"E_BLOCK_LAPIS_ORE",E_BLOCK_LAPIS_ORE); + tolua_constant(tolua_S,"E_BLOCK_LAPIS_BLOCK",E_BLOCK_LAPIS_BLOCK); + tolua_constant(tolua_S,"E_BLOCK_DISPENSER",E_BLOCK_DISPENSER); + tolua_constant(tolua_S,"E_BLOCK_SANDSTONE",E_BLOCK_SANDSTONE); + tolua_constant(tolua_S,"E_BLOCK_NOTE_BLOCK",E_BLOCK_NOTE_BLOCK); + tolua_constant(tolua_S,"E_BLOCK_BED",E_BLOCK_BED); + tolua_constant(tolua_S,"E_BLOCK_POWERED_RAIL",E_BLOCK_POWERED_RAIL); + tolua_constant(tolua_S,"E_BLOCK_DETECTOR_RAIL",E_BLOCK_DETECTOR_RAIL); + tolua_constant(tolua_S,"E_BLOCK_STICKY_PISTON",E_BLOCK_STICKY_PISTON); + tolua_constant(tolua_S,"E_BLOCK_COBWEB",E_BLOCK_COBWEB); + tolua_constant(tolua_S,"E_BLOCK_TALL_GRASS",E_BLOCK_TALL_GRASS); + tolua_constant(tolua_S,"E_BLOCK_DEAD_BUSH",E_BLOCK_DEAD_BUSH); + tolua_constant(tolua_S,"E_BLOCK_PISTON",E_BLOCK_PISTON); + tolua_constant(tolua_S,"E_BLOCK_PISTON_EXTENSION",E_BLOCK_PISTON_EXTENSION); + tolua_constant(tolua_S,"E_BLOCK_WHITE_CLOTH",E_BLOCK_WHITE_CLOTH); + tolua_constant(tolua_S,"E_BLOCK_WOOL",E_BLOCK_WOOL); + tolua_constant(tolua_S,"E_BLOCK_PISTON_MOVED_BLOCK",E_BLOCK_PISTON_MOVED_BLOCK); + tolua_constant(tolua_S,"E_BLOCK_YELLOW_FLOWER",E_BLOCK_YELLOW_FLOWER); + tolua_constant(tolua_S,"E_BLOCK_RED_ROSE",E_BLOCK_RED_ROSE); + tolua_constant(tolua_S,"E_BLOCK_BROWN_MUSHROOM",E_BLOCK_BROWN_MUSHROOM); + tolua_constant(tolua_S,"E_BLOCK_RED_MUSHROOM",E_BLOCK_RED_MUSHROOM); + tolua_constant(tolua_S,"E_BLOCK_GOLD_BLOCK",E_BLOCK_GOLD_BLOCK); + tolua_constant(tolua_S,"E_BLOCK_IRON_BLOCK",E_BLOCK_IRON_BLOCK); + tolua_constant(tolua_S,"E_BLOCK_DOUBLE_STONE_SLAB",E_BLOCK_DOUBLE_STONE_SLAB); + tolua_constant(tolua_S,"E_BLOCK_DOUBLE_STEP",E_BLOCK_DOUBLE_STEP); + tolua_constant(tolua_S,"E_BLOCK_STONE_SLAB",E_BLOCK_STONE_SLAB); + tolua_constant(tolua_S,"E_BLOCK_STEP",E_BLOCK_STEP); + tolua_constant(tolua_S,"E_BLOCK_BRICK",E_BLOCK_BRICK); + tolua_constant(tolua_S,"E_BLOCK_TNT",E_BLOCK_TNT); + tolua_constant(tolua_S,"E_BLOCK_BOOKCASE",E_BLOCK_BOOKCASE); + tolua_constant(tolua_S,"E_BLOCK_MOSSY_COBBLESTONE",E_BLOCK_MOSSY_COBBLESTONE); + tolua_constant(tolua_S,"E_BLOCK_OBSIDIAN",E_BLOCK_OBSIDIAN); + tolua_constant(tolua_S,"E_BLOCK_TORCH",E_BLOCK_TORCH); + tolua_constant(tolua_S,"E_BLOCK_FIRE",E_BLOCK_FIRE); + tolua_constant(tolua_S,"E_BLOCK_MOB_SPAWNER",E_BLOCK_MOB_SPAWNER); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_STAIRS",E_BLOCK_WOODEN_STAIRS); + tolua_constant(tolua_S,"E_BLOCK_CHEST",E_BLOCK_CHEST); + tolua_constant(tolua_S,"E_BLOCK_REDSTONE_WIRE",E_BLOCK_REDSTONE_WIRE); + tolua_constant(tolua_S,"E_BLOCK_DIAMOND_ORE",E_BLOCK_DIAMOND_ORE); + tolua_constant(tolua_S,"E_BLOCK_DIAMOND_BLOCK",E_BLOCK_DIAMOND_BLOCK); + tolua_constant(tolua_S,"E_BLOCK_CRAFTING_TABLE",E_BLOCK_CRAFTING_TABLE); + tolua_constant(tolua_S,"E_BLOCK_WORKBENCH",E_BLOCK_WORKBENCH); + tolua_constant(tolua_S,"E_BLOCK_CROPS",E_BLOCK_CROPS); + tolua_constant(tolua_S,"E_BLOCK_SOIL",E_BLOCK_SOIL); + tolua_constant(tolua_S,"E_BLOCK_FARMLAND",E_BLOCK_FARMLAND); + tolua_constant(tolua_S,"E_BLOCK_FURNACE",E_BLOCK_FURNACE); + tolua_constant(tolua_S,"E_BLOCK_LIT_FURNACE",E_BLOCK_LIT_FURNACE); + tolua_constant(tolua_S,"E_BLOCK_BURNING_FURNACE",E_BLOCK_BURNING_FURNACE); + tolua_constant(tolua_S,"E_BLOCK_SIGN_POST",E_BLOCK_SIGN_POST); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOOR",E_BLOCK_WOODEN_DOOR); + tolua_constant(tolua_S,"E_BLOCK_LADDER",E_BLOCK_LADDER); + tolua_constant(tolua_S,"E_BLOCK_RAIL",E_BLOCK_RAIL); + tolua_constant(tolua_S,"E_BLOCK_MINECART_TRACKS",E_BLOCK_MINECART_TRACKS); + tolua_constant(tolua_S,"E_BLOCK_COBBLESTONE_STAIRS",E_BLOCK_COBBLESTONE_STAIRS); + tolua_constant(tolua_S,"E_BLOCK_WALLSIGN",E_BLOCK_WALLSIGN); + tolua_constant(tolua_S,"E_BLOCK_LEVER",E_BLOCK_LEVER); + tolua_constant(tolua_S,"E_BLOCK_STONE_PRESSURE_PLATE",E_BLOCK_STONE_PRESSURE_PLATE); + tolua_constant(tolua_S,"E_BLOCK_IRON_DOOR",E_BLOCK_IRON_DOOR); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_PRESSURE_PLATE",E_BLOCK_WOODEN_PRESSURE_PLATE); + tolua_constant(tolua_S,"E_BLOCK_REDSTONE_ORE",E_BLOCK_REDSTONE_ORE); + tolua_constant(tolua_S,"E_BLOCK_REDSTONE_ORE_GLOWING",E_BLOCK_REDSTONE_ORE_GLOWING); + tolua_constant(tolua_S,"E_BLOCK_REDSTONE_TORCH_OFF",E_BLOCK_REDSTONE_TORCH_OFF); + tolua_constant(tolua_S,"E_BLOCK_REDSTONE_TORCH_ON",E_BLOCK_REDSTONE_TORCH_ON); + tolua_constant(tolua_S,"E_BLOCK_STONE_BUTTON",E_BLOCK_STONE_BUTTON); + tolua_constant(tolua_S,"E_BLOCK_SNOW",E_BLOCK_SNOW); + tolua_constant(tolua_S,"E_BLOCK_ICE",E_BLOCK_ICE); + tolua_constant(tolua_S,"E_BLOCK_SNOW_BLOCK",E_BLOCK_SNOW_BLOCK); + tolua_constant(tolua_S,"E_BLOCK_CACTUS",E_BLOCK_CACTUS); + tolua_constant(tolua_S,"E_BLOCK_CLAY",E_BLOCK_CLAY); + tolua_constant(tolua_S,"E_BLOCK_SUGARCANE",E_BLOCK_SUGARCANE); + tolua_constant(tolua_S,"E_BLOCK_REEDS",E_BLOCK_REEDS); + tolua_constant(tolua_S,"E_BLOCK_JUKEBOX",E_BLOCK_JUKEBOX); + tolua_constant(tolua_S,"E_BLOCK_FENCE",E_BLOCK_FENCE); + tolua_constant(tolua_S,"E_BLOCK_PUMPKIN",E_BLOCK_PUMPKIN); + tolua_constant(tolua_S,"E_BLOCK_BLOODSTONE",E_BLOCK_BLOODSTONE); + tolua_constant(tolua_S,"E_BLOCK_NETHERRACK",E_BLOCK_NETHERRACK); + tolua_constant(tolua_S,"E_BLOCK_SOULSAND",E_BLOCK_SOULSAND); + tolua_constant(tolua_S,"E_BLOCK_GLOWSTONE",E_BLOCK_GLOWSTONE); + tolua_constant(tolua_S,"E_BLOCK_PORT",E_BLOCK_PORT); + tolua_constant(tolua_S,"E_BLOCK_NETHER_PORTAL",E_BLOCK_NETHER_PORTAL); + tolua_constant(tolua_S,"E_BLOCK_JACK_O_LANTERN",E_BLOCK_JACK_O_LANTERN); + tolua_constant(tolua_S,"E_BLOCK_CAKE",E_BLOCK_CAKE); + tolua_constant(tolua_S,"E_BLOCK_REDSTONE_REPEATER_OFF",E_BLOCK_REDSTONE_REPEATER_OFF); + tolua_constant(tolua_S,"E_BLOCK_REDSTONE_REPEATER_ON",E_BLOCK_REDSTONE_REPEATER_ON); + tolua_constant(tolua_S,"E_BLOCK_LOCKED_CHEST",E_BLOCK_LOCKED_CHEST); + tolua_constant(tolua_S,"E_BLOCK_TRAPDOOR",E_BLOCK_TRAPDOOR); + tolua_constant(tolua_S,"E_BLOCK_SILVERFISH_EGG",E_BLOCK_SILVERFISH_EGG); + tolua_constant(tolua_S,"E_BLOCK_STONE_BRICKS",E_BLOCK_STONE_BRICKS); + tolua_constant(tolua_S,"E_BLOCK_HUGE_BROWN_MUSHROOM",E_BLOCK_HUGE_BROWN_MUSHROOM); + tolua_constant(tolua_S,"E_BLOCK_HUGE_RED_MUSHROOM",E_BLOCK_HUGE_RED_MUSHROOM); + tolua_constant(tolua_S,"E_BLOCK_IRON_BAR",E_BLOCK_IRON_BAR); + tolua_constant(tolua_S,"E_BLOCK_GLASS_PLANE",E_BLOCK_GLASS_PLANE); + tolua_constant(tolua_S,"E_BLOCK_MELON",E_BLOCK_MELON); + tolua_constant(tolua_S,"E_BLOCK_PUMPKIN_STEM",E_BLOCK_PUMPKIN_STEM); + tolua_constant(tolua_S,"E_BLOCK_MELON_STEM",E_BLOCK_MELON_STEM); + tolua_constant(tolua_S,"E_BLOCK_VINES",E_BLOCK_VINES); + tolua_constant(tolua_S,"E_BLOCK_FENCE_GATE",E_BLOCK_FENCE_GATE); + tolua_constant(tolua_S,"E_BLOCK_BRICK_STAIRS",E_BLOCK_BRICK_STAIRS); + tolua_constant(tolua_S,"E_BLOCK_STONE_BRICK_STAIRS",E_BLOCK_STONE_BRICK_STAIRS); + tolua_constant(tolua_S,"E_BLOCK_MYCELIUM",E_BLOCK_MYCELIUM); + tolua_constant(tolua_S,"E_BLOCK_LILY_PAD",E_BLOCK_LILY_PAD); + tolua_constant(tolua_S,"E_BLOCK_NETHER_BRICK",E_BLOCK_NETHER_BRICK); + tolua_constant(tolua_S,"E_BLOCK_NETHER_BRICK_FENCE",E_BLOCK_NETHER_BRICK_FENCE); + tolua_constant(tolua_S,"E_BLOCK_NETHER_BRICK_STAIRS",E_BLOCK_NETHER_BRICK_STAIRS); + tolua_constant(tolua_S,"E_BLOCK_NETHER_WART",E_BLOCK_NETHER_WART); + tolua_constant(tolua_S,"E_BLOCK_ENCHANTMENT_TABLE",E_BLOCK_ENCHANTMENT_TABLE); + tolua_constant(tolua_S,"E_BLOCK_BREWING_STAND",E_BLOCK_BREWING_STAND); + tolua_constant(tolua_S,"E_BLOCK_CAULDRON",E_BLOCK_CAULDRON); + tolua_constant(tolua_S,"E_BLOCK_END_PORTAL",E_BLOCK_END_PORTAL); + tolua_constant(tolua_S,"E_BLOCK_END_PORTAL_FRAME",E_BLOCK_END_PORTAL_FRAME); + tolua_constant(tolua_S,"E_BLOCK_END_STONE",E_BLOCK_END_STONE); + tolua_constant(tolua_S,"E_BLOCK_DRAGON_EGG",E_BLOCK_DRAGON_EGG); + tolua_constant(tolua_S,"E_BLOCK_REDSTONE_LAMP_OFF",E_BLOCK_REDSTONE_LAMP_OFF); + tolua_constant(tolua_S,"E_BLOCK_REDSTONE_LAMP_ON",E_BLOCK_REDSTONE_LAMP_ON); + tolua_constant(tolua_S,"E_BLOCK_DOUBLE_WOODEN_SLAB",E_BLOCK_DOUBLE_WOODEN_SLAB); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_SLAB",E_BLOCK_WOODEN_SLAB); + tolua_constant(tolua_S,"E_BLOCK_COCA_PLANT",E_BLOCK_COCA_PLANT); + tolua_constant(tolua_S,"E_BLOCK_SANDSTONE_STAIRS",E_BLOCK_SANDSTONE_STAIRS); + tolua_constant(tolua_S,"E_BLOCK_EMERALD_ORE",E_BLOCK_EMERALD_ORE); + tolua_constant(tolua_S,"E_BLOCK_ENDER_CHEST",E_BLOCK_ENDER_CHEST); + tolua_constant(tolua_S,"E_BLOCK_TRIPWIRE_HOOK",E_BLOCK_TRIPWIRE_HOOK); + tolua_constant(tolua_S,"E_BLOCK_TRIPWIRE",E_BLOCK_TRIPWIRE); + tolua_constant(tolua_S,"E_BLOCK_EMERALD_BLOCK",E_BLOCK_EMERALD_BLOCK); + tolua_constant(tolua_S,"E_BLOCK_",E_BLOCK_); + tolua_constant(tolua_S,"E_ITEM_EMPTY",E_ITEM_EMPTY); + tolua_constant(tolua_S,"E_ITEM_STONE",E_ITEM_STONE); + tolua_constant(tolua_S,"E_ITEM_GRASS",E_ITEM_GRASS); + tolua_constant(tolua_S,"E_ITEM_DIRT",E_ITEM_DIRT); + tolua_constant(tolua_S,"E_ITEM_COBBLESTONE",E_ITEM_COBBLESTONE); + tolua_constant(tolua_S,"E_ITEM_PLANKS",E_ITEM_PLANKS); + tolua_constant(tolua_S,"E_ITEM_WOOD",E_ITEM_WOOD); + tolua_constant(tolua_S,"E_ITEM_SAPLING",E_ITEM_SAPLING); + tolua_constant(tolua_S,"E_ITEM_BEDROCK",E_ITEM_BEDROCK); + tolua_constant(tolua_S,"E_ITEM_WATER",E_ITEM_WATER); + tolua_constant(tolua_S,"E_ITEM_STATIONARY_WATER",E_ITEM_STATIONARY_WATER); + tolua_constant(tolua_S,"E_ITEM_LAVA",E_ITEM_LAVA); + tolua_constant(tolua_S,"E_ITEM_STATIONARY_LAVA",E_ITEM_STATIONARY_LAVA); + tolua_constant(tolua_S,"E_ITEM_SAND",E_ITEM_SAND); + tolua_constant(tolua_S,"E_ITEM_GRAVEL",E_ITEM_GRAVEL); + tolua_constant(tolua_S,"E_ITEM_GOLD_ORE",E_ITEM_GOLD_ORE); + tolua_constant(tolua_S,"E_ITEM_IRON_ORE",E_ITEM_IRON_ORE); + tolua_constant(tolua_S,"E_ITEM_COAL_ORE",E_ITEM_COAL_ORE); + tolua_constant(tolua_S,"E_ITEM_LOG",E_ITEM_LOG); + tolua_constant(tolua_S,"E_ITEM_LEAVES",E_ITEM_LEAVES); + tolua_constant(tolua_S,"E_ITEM_SPONGE",E_ITEM_SPONGE); + tolua_constant(tolua_S,"E_ITEM_GLASS",E_ITEM_GLASS); + tolua_constant(tolua_S,"E_ITEM_LAPIS_ORE",E_ITEM_LAPIS_ORE); + tolua_constant(tolua_S,"E_ITEM_LAPIS_BLOCK",E_ITEM_LAPIS_BLOCK); + tolua_constant(tolua_S,"E_ITEM_DISPENSER",E_ITEM_DISPENSER); + tolua_constant(tolua_S,"E_ITEM_SANDSTONE",E_ITEM_SANDSTONE); + tolua_constant(tolua_S,"E_ITEM_NOTE_ITEM",E_ITEM_NOTE_ITEM); + tolua_constant(tolua_S,"E_ITEM_POWERED_RAIL",E_ITEM_POWERED_RAIL); + tolua_constant(tolua_S,"E_ITEM_DETECTOR_RAIL",E_ITEM_DETECTOR_RAIL); + tolua_constant(tolua_S,"E_ITEM_STICKY_PISTON",E_ITEM_STICKY_PISTON); + tolua_constant(tolua_S,"E_ITEM_COBWEB",E_ITEM_COBWEB); + tolua_constant(tolua_S,"E_ITEM_TALL_GRASS",E_ITEM_TALL_GRASS); + tolua_constant(tolua_S,"E_ITEM_DEAD_BRUSH",E_ITEM_DEAD_BRUSH); + tolua_constant(tolua_S,"E_ITEM_PISTON",E_ITEM_PISTON); + tolua_constant(tolua_S,"E_ITEM_PISTON_EXTENSION",E_ITEM_PISTON_EXTENSION); + tolua_constant(tolua_S,"E_ITEM_WHITE_CLOTH",E_ITEM_WHITE_CLOTH); + tolua_constant(tolua_S,"E_ITEM_PISTON_MOVED_BLOCK",E_ITEM_PISTON_MOVED_BLOCK); + tolua_constant(tolua_S,"E_ITEM_YELLOW_FLOWER",E_ITEM_YELLOW_FLOWER); + tolua_constant(tolua_S,"E_ITEM_RED_ROSE",E_ITEM_RED_ROSE); + tolua_constant(tolua_S,"E_ITEM_BROWN_MUSHROOM",E_ITEM_BROWN_MUSHROOM); + tolua_constant(tolua_S,"E_ITEM_RED_MUSHROOM",E_ITEM_RED_MUSHROOM); + tolua_constant(tolua_S,"E_ITEM_GOLD_BLOCK",E_ITEM_GOLD_BLOCK); + tolua_constant(tolua_S,"E_ITEM_IRON_BLOCK",E_ITEM_IRON_BLOCK); + tolua_constant(tolua_S,"E_ITEM_DOUBLE_STONE_SLAB",E_ITEM_DOUBLE_STONE_SLAB); + tolua_constant(tolua_S,"E_ITEM_DOUBLE_STEP",E_ITEM_DOUBLE_STEP); + tolua_constant(tolua_S,"E_ITEM_STONE_SLAB",E_ITEM_STONE_SLAB); + tolua_constant(tolua_S,"E_ITEM_STEP",E_ITEM_STEP); + tolua_constant(tolua_S,"E_ITEM_BRICK",E_ITEM_BRICK); + tolua_constant(tolua_S,"E_ITEM_TNT",E_ITEM_TNT); + tolua_constant(tolua_S,"E_ITEM_BOOKCASE",E_ITEM_BOOKCASE); + tolua_constant(tolua_S,"E_ITEM_MOSSY_COBBLESTONE",E_ITEM_MOSSY_COBBLESTONE); + tolua_constant(tolua_S,"E_ITEM_OBSIDIAN",E_ITEM_OBSIDIAN); + tolua_constant(tolua_S,"E_ITEM_TORCH",E_ITEM_TORCH); + tolua_constant(tolua_S,"E_ITEM_FIRE",E_ITEM_FIRE); + tolua_constant(tolua_S,"E_ITEM_MOB_SPAWNER",E_ITEM_MOB_SPAWNER); + tolua_constant(tolua_S,"E_ITEM_WOODEN_STAIRS",E_ITEM_WOODEN_STAIRS); + tolua_constant(tolua_S,"E_ITEM_CHEST",E_ITEM_CHEST); + tolua_constant(tolua_S,"E_ITEM_REDSTONE_WIRE",E_ITEM_REDSTONE_WIRE); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_ORE",E_ITEM_DIAMOND_ORE); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_BLOCK",E_ITEM_DIAMOND_BLOCK); + tolua_constant(tolua_S,"E_ITEM_WORKBENCH",E_ITEM_WORKBENCH); + tolua_constant(tolua_S,"E_ITEM_CROPS",E_ITEM_CROPS); + tolua_constant(tolua_S,"E_ITEM_SOIL",E_ITEM_SOIL); + tolua_constant(tolua_S,"E_ITEM_FURNACE",E_ITEM_FURNACE); + tolua_constant(tolua_S,"E_ITEM_BURNING_FURNACE",E_ITEM_BURNING_FURNACE); + tolua_constant(tolua_S,"E_ITEM_SIGN_POST",E_ITEM_SIGN_POST); + tolua_constant(tolua_S,"E_ITEM_LADDER",E_ITEM_LADDER); + tolua_constant(tolua_S,"E_ITEM_MINECART_TRACKS",E_ITEM_MINECART_TRACKS); + tolua_constant(tolua_S,"E_ITEM_COBBLESTONE_STAIRS",E_ITEM_COBBLESTONE_STAIRS); + tolua_constant(tolua_S,"E_ITEM_WALLSIGN",E_ITEM_WALLSIGN); + tolua_constant(tolua_S,"E_ITEM_LEVER",E_ITEM_LEVER); + tolua_constant(tolua_S,"E_ITEM_STONE_PRESSURE_PLATE",E_ITEM_STONE_PRESSURE_PLATE); + tolua_constant(tolua_S,"E_ITEM_WOODEN_PRESSURE_PLATE",E_ITEM_WOODEN_PRESSURE_PLATE); + tolua_constant(tolua_S,"E_ITEM_REDSTONE_ORE",E_ITEM_REDSTONE_ORE); + tolua_constant(tolua_S,"E_ITEM_REDSTONE_ORE_GLOWING",E_ITEM_REDSTONE_ORE_GLOWING); + tolua_constant(tolua_S,"E_ITEM_REDSTONE_TORCH_ON",E_ITEM_REDSTONE_TORCH_ON); + tolua_constant(tolua_S,"E_ITEM_REDSTONE_TORCH_OFF",E_ITEM_REDSTONE_TORCH_OFF); + tolua_constant(tolua_S,"E_ITEM_STONE_BUTTON",E_ITEM_STONE_BUTTON); + tolua_constant(tolua_S,"E_ITEM_SNOW",E_ITEM_SNOW); + tolua_constant(tolua_S,"E_ITEM_ICE",E_ITEM_ICE); + tolua_constant(tolua_S,"E_ITEM_SNOW_BLOCK",E_ITEM_SNOW_BLOCK); + tolua_constant(tolua_S,"E_ITEM_CACTUS",E_ITEM_CACTUS); + tolua_constant(tolua_S,"E_ITEM_REEDS",E_ITEM_REEDS); + tolua_constant(tolua_S,"E_ITEM_JUKEBOX",E_ITEM_JUKEBOX); + tolua_constant(tolua_S,"E_ITEM_FENCE",E_ITEM_FENCE); + tolua_constant(tolua_S,"E_ITEM_PUMPKIN",E_ITEM_PUMPKIN); + tolua_constant(tolua_S,"E_ITEM_BLOODSTONE",E_ITEM_BLOODSTONE); + tolua_constant(tolua_S,"E_ITEM_SOULSAND",E_ITEM_SOULSAND); + tolua_constant(tolua_S,"E_ITEM_GLOWSTONE",E_ITEM_GLOWSTONE); + tolua_constant(tolua_S,"E_ITEM_PORT",E_ITEM_PORT); + tolua_constant(tolua_S,"E_ITEM_JACK_O_LANTERN",E_ITEM_JACK_O_LANTERN); + tolua_constant(tolua_S,"E_ITEM_REDSTONE_REPEATER_OFF",E_ITEM_REDSTONE_REPEATER_OFF); + tolua_constant(tolua_S,"E_ITEM_REDSTONE_REPEATER_ON",E_ITEM_REDSTONE_REPEATER_ON); + tolua_constant(tolua_S,"E_ITEM_LOCKED_CHEST",E_ITEM_LOCKED_CHEST); + tolua_constant(tolua_S,"E_ITEM_TRAPDOOR",E_ITEM_TRAPDOOR); + tolua_constant(tolua_S,"E_ITEM_SILVERFISH_EGG",E_ITEM_SILVERFISH_EGG); + tolua_constant(tolua_S,"E_ITEM_STONE_BRICKS",E_ITEM_STONE_BRICKS); + tolua_constant(tolua_S,"E_ITEM_HUGE_BROWN_MUSHROOM",E_ITEM_HUGE_BROWN_MUSHROOM); + tolua_constant(tolua_S,"E_ITEM_HUGE_RED_MUSHROOM",E_ITEM_HUGE_RED_MUSHROOM); + tolua_constant(tolua_S,"E_ITEM_IRON_BAR",E_ITEM_IRON_BAR); + tolua_constant(tolua_S,"E_ITEM_GLASS_PLANE",E_ITEM_GLASS_PLANE); + tolua_constant(tolua_S,"E_ITEM_MELON",E_ITEM_MELON); + tolua_constant(tolua_S,"E_ITEM_PUMPKIN_STEM",E_ITEM_PUMPKIN_STEM); + tolua_constant(tolua_S,"E_ITEM_MELON_STEM",E_ITEM_MELON_STEM); + tolua_constant(tolua_S,"E_ITEM_VINES",E_ITEM_VINES); + tolua_constant(tolua_S,"E_ITEM_FENCE_GATE",E_ITEM_FENCE_GATE); + tolua_constant(tolua_S,"E_ITEM_BRICK_STAIRS",E_ITEM_BRICK_STAIRS); + tolua_constant(tolua_S,"E_ITEM_STONE_BRICK_STAIRS",E_ITEM_STONE_BRICK_STAIRS); + tolua_constant(tolua_S,"E_ITEM_MYCELIUM",E_ITEM_MYCELIUM); + tolua_constant(tolua_S,"E_ITEM_LILY_PAD",E_ITEM_LILY_PAD); + tolua_constant(tolua_S,"E_ITEM_NETHER_BRICK",E_ITEM_NETHER_BRICK); + tolua_constant(tolua_S,"E_ITEM_NETHER_BRICK_FENCE",E_ITEM_NETHER_BRICK_FENCE); + tolua_constant(tolua_S,"E_ITEM_NETHER_BRICK_STAIRS",E_ITEM_NETHER_BRICK_STAIRS); + tolua_constant(tolua_S,"E_ITEM_ENCHANTMENT_TABLE",E_ITEM_ENCHANTMENT_TABLE); + tolua_constant(tolua_S,"E_ITEM_END_PORTAL",E_ITEM_END_PORTAL); + tolua_constant(tolua_S,"E_ITEM_END_PORTAL_FRAME",E_ITEM_END_PORTAL_FRAME); + tolua_constant(tolua_S,"E_ITEM_END_STONE",E_ITEM_END_STONE); + tolua_constant(tolua_S,"E_ITEM_DOUBLE_WOODEN_SLAB",E_ITEM_DOUBLE_WOODEN_SLAB); + tolua_constant(tolua_S,"E_ITEM_WOODEN_SLAB",E_ITEM_WOODEN_SLAB); + tolua_constant(tolua_S,"E_ITEM_COCA_PLANT",E_ITEM_COCA_PLANT); + tolua_constant(tolua_S,"E_ITEM_SANDSTONE_STAIRS",E_ITEM_SANDSTONE_STAIRS); + tolua_constant(tolua_S,"E_ITEM_EMERALD_ORE",E_ITEM_EMERALD_ORE); + tolua_constant(tolua_S,"E_ITEM_ENDER_CHEST",E_ITEM_ENDER_CHEST); + tolua_constant(tolua_S,"E_ITEM_TRIPWIRE_HOOK",E_ITEM_TRIPWIRE_HOOK); + tolua_constant(tolua_S,"E_ITEM_TRIPWIRE",E_ITEM_TRIPWIRE); + tolua_constant(tolua_S,"E_ITEM_EMERALD_BLOCK",E_ITEM_EMERALD_BLOCK); + tolua_constant(tolua_S,"E_ITEM_IRON_SHOVEL",E_ITEM_IRON_SHOVEL); + tolua_constant(tolua_S,"E_ITEM_IRON_PICKAXE",E_ITEM_IRON_PICKAXE); + tolua_constant(tolua_S,"E_ITEM_IRON_AXE",E_ITEM_IRON_AXE); + tolua_constant(tolua_S,"E_ITEM_FLINT_AND_STEEL",E_ITEM_FLINT_AND_STEEL); + tolua_constant(tolua_S,"E_ITEM_RED_APPLE",E_ITEM_RED_APPLE); + tolua_constant(tolua_S,"E_ITEM_APPLE",E_ITEM_APPLE); + tolua_constant(tolua_S,"E_ITEM_BOW",E_ITEM_BOW); + tolua_constant(tolua_S,"E_ITEM_ARROW",E_ITEM_ARROW); + tolua_constant(tolua_S,"E_ITEM_COAL",E_ITEM_COAL); + tolua_constant(tolua_S,"E_ITEM_DIAMOND",E_ITEM_DIAMOND); + tolua_constant(tolua_S,"E_ITEM_IRON",E_ITEM_IRON); + tolua_constant(tolua_S,"E_ITEM_GOLD",E_ITEM_GOLD); + tolua_constant(tolua_S,"E_ITEM_IRON_SWORD",E_ITEM_IRON_SWORD); + tolua_constant(tolua_S,"E_ITEM_WOODEN_SWORD",E_ITEM_WOODEN_SWORD); + tolua_constant(tolua_S,"E_ITEM_WOODEN_SHOVEL",E_ITEM_WOODEN_SHOVEL); + tolua_constant(tolua_S,"E_ITEM_WOODEN_PICKAXE",E_ITEM_WOODEN_PICKAXE); + tolua_constant(tolua_S,"E_ITEM_WOODEN_AXE",E_ITEM_WOODEN_AXE); + tolua_constant(tolua_S,"E_ITEM_STONE_SWORD",E_ITEM_STONE_SWORD); + tolua_constant(tolua_S,"E_ITEM_STONE_SHOVEL",E_ITEM_STONE_SHOVEL); + tolua_constant(tolua_S,"E_ITEM_STONE_PICKAXE",E_ITEM_STONE_PICKAXE); + tolua_constant(tolua_S,"E_ITEM_STONE_AXE",E_ITEM_STONE_AXE); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_SWORD",E_ITEM_DIAMOND_SWORD); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_SHOVEL",E_ITEM_DIAMOND_SHOVEL); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_PICKAXE",E_ITEM_DIAMOND_PICKAXE); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_AXE",E_ITEM_DIAMOND_AXE); + tolua_constant(tolua_S,"E_ITEM_STICK",E_ITEM_STICK); + tolua_constant(tolua_S,"E_ITEM_BOWL",E_ITEM_BOWL); + tolua_constant(tolua_S,"E_ITEM_MUSHROOM_SOUP",E_ITEM_MUSHROOM_SOUP); + tolua_constant(tolua_S,"E_ITEM_GOLD_SWORD",E_ITEM_GOLD_SWORD); + tolua_constant(tolua_S,"E_ITEM_GOLD_SHOVEL",E_ITEM_GOLD_SHOVEL); + tolua_constant(tolua_S,"E_ITEM_GOLD_PICKAXE",E_ITEM_GOLD_PICKAXE); + tolua_constant(tolua_S,"E_ITEM_GOLD_AXE",E_ITEM_GOLD_AXE); + tolua_constant(tolua_S,"E_ITEM_STRING",E_ITEM_STRING); + tolua_constant(tolua_S,"E_ITEM_FEATHER",E_ITEM_FEATHER); + tolua_constant(tolua_S,"E_ITEM_GUNPOWDER",E_ITEM_GUNPOWDER); + tolua_constant(tolua_S,"E_ITEM_WOODEN_HOE",E_ITEM_WOODEN_HOE); + tolua_constant(tolua_S,"E_ITEM_STONE_HOE",E_ITEM_STONE_HOE); + tolua_constant(tolua_S,"E_ITEM_IRON_HOE",E_ITEM_IRON_HOE); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_HOE",E_ITEM_DIAMOND_HOE); + tolua_constant(tolua_S,"E_ITEM_GOLD_HOE",E_ITEM_GOLD_HOE); + tolua_constant(tolua_S,"E_ITEM_SEEDS",E_ITEM_SEEDS); + tolua_constant(tolua_S,"E_ITEM_WHEAT",E_ITEM_WHEAT); + tolua_constant(tolua_S,"E_ITEM_BREAD",E_ITEM_BREAD); + tolua_constant(tolua_S,"E_ITEM_LEATHER_CAP",E_ITEM_LEATHER_CAP); + tolua_constant(tolua_S,"E_ITEM_LEATHER_TUNIC",E_ITEM_LEATHER_TUNIC); + tolua_constant(tolua_S,"E_ITEM_LEATHER_PANTS",E_ITEM_LEATHER_PANTS); + tolua_constant(tolua_S,"E_ITEM_LEATHER_BOOTS",E_ITEM_LEATHER_BOOTS); + tolua_constant(tolua_S,"E_ITEM_CHAIN_HELMET",E_ITEM_CHAIN_HELMET); + tolua_constant(tolua_S,"E_ITEM_CHAIN_CHESTPLATE",E_ITEM_CHAIN_CHESTPLATE); + tolua_constant(tolua_S,"E_ITEM_CHAIN_LEGGINGS",E_ITEM_CHAIN_LEGGINGS); + tolua_constant(tolua_S,"E_ITEM_CHAIN_BOOTS",E_ITEM_CHAIN_BOOTS); + tolua_constant(tolua_S,"E_ITEM_IRON_HELMET",E_ITEM_IRON_HELMET); + tolua_constant(tolua_S,"E_ITEM_IRON_CHESTPLATE",E_ITEM_IRON_CHESTPLATE); + tolua_constant(tolua_S,"E_ITEM_IRON_LEGGINGS",E_ITEM_IRON_LEGGINGS); + tolua_constant(tolua_S,"E_ITEM_IRON_BOOTS",E_ITEM_IRON_BOOTS); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_HELMET",E_ITEM_DIAMOND_HELMET); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_CHESTPLATE",E_ITEM_DIAMOND_CHESTPLATE); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_LEGGINGS",E_ITEM_DIAMOND_LEGGINGS); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_BOOTS",E_ITEM_DIAMOND_BOOTS); + tolua_constant(tolua_S,"E_ITEM_GOLD_HELMET",E_ITEM_GOLD_HELMET); + tolua_constant(tolua_S,"E_ITEM_GOLD_CHESTPLATE",E_ITEM_GOLD_CHESTPLATE); + tolua_constant(tolua_S,"E_ITEM_GOLD_LEGGINGS",E_ITEM_GOLD_LEGGINGS); + tolua_constant(tolua_S,"E_ITEM_GOLD_BOOTS",E_ITEM_GOLD_BOOTS); + tolua_constant(tolua_S,"E_ITEM_FLINT",E_ITEM_FLINT); + tolua_constant(tolua_S,"E_ITEM_RAW_MEAT",E_ITEM_RAW_MEAT); + tolua_constant(tolua_S,"E_ITEM_COOKED_MEAT",E_ITEM_COOKED_MEAT); + tolua_constant(tolua_S,"E_ITEM_PAINTINGS",E_ITEM_PAINTINGS); + tolua_constant(tolua_S,"E_ITEM_GOLDEN_APPLE",E_ITEM_GOLDEN_APPLE); + tolua_constant(tolua_S,"E_ITEM_SIGN",E_ITEM_SIGN); + tolua_constant(tolua_S,"E_ITEM_WOODEN_DOOR",E_ITEM_WOODEN_DOOR); + tolua_constant(tolua_S,"E_ITEM_BUCKET",E_ITEM_BUCKET); + tolua_constant(tolua_S,"E_ITEM_WATER_BUCKET",E_ITEM_WATER_BUCKET); + tolua_constant(tolua_S,"E_ITEM_LAVA_BUCKET",E_ITEM_LAVA_BUCKET); + tolua_constant(tolua_S,"E_ITEM_MINECART",E_ITEM_MINECART); + tolua_constant(tolua_S,"E_ITEM_SADDLE",E_ITEM_SADDLE); + tolua_constant(tolua_S,"E_ITEM_IRON_DOOR",E_ITEM_IRON_DOOR); + tolua_constant(tolua_S,"E_ITEM_REDSTONE_DUST",E_ITEM_REDSTONE_DUST); + tolua_constant(tolua_S,"E_ITEM_SNOWBALL",E_ITEM_SNOWBALL); + tolua_constant(tolua_S,"E_ITEM_BOAT",E_ITEM_BOAT); + tolua_constant(tolua_S,"E_ITEM_LEATHER",E_ITEM_LEATHER); + tolua_constant(tolua_S,"E_ITEM_MILK",E_ITEM_MILK); + tolua_constant(tolua_S,"E_ITEM_CLAY_BRICK",E_ITEM_CLAY_BRICK); + tolua_constant(tolua_S,"E_ITEM_CLAY",E_ITEM_CLAY); + tolua_constant(tolua_S,"E_ITEM_SUGARCANE",E_ITEM_SUGARCANE); + tolua_constant(tolua_S,"E_ITEM_SUGAR_CANE",E_ITEM_SUGAR_CANE); + tolua_constant(tolua_S,"E_ITEM_PAPER",E_ITEM_PAPER); + tolua_constant(tolua_S,"E_ITEM_BOOK",E_ITEM_BOOK); + tolua_constant(tolua_S,"E_ITEM_SLIMEBALL",E_ITEM_SLIMEBALL); + tolua_constant(tolua_S,"E_ITEM_CHEST_MINECART",E_ITEM_CHEST_MINECART); + tolua_constant(tolua_S,"E_ITEM_FURNACE_MINECART",E_ITEM_FURNACE_MINECART); + tolua_constant(tolua_S,"E_ITEM_EGG",E_ITEM_EGG); + tolua_constant(tolua_S,"E_ITEM_COMPASS",E_ITEM_COMPASS); + tolua_constant(tolua_S,"E_ITEM_FISHING_ROD",E_ITEM_FISHING_ROD); + tolua_constant(tolua_S,"E_ITEM_CLOCK",E_ITEM_CLOCK); + tolua_constant(tolua_S,"E_ITEM_GLOWSTONE_DUST",E_ITEM_GLOWSTONE_DUST); + tolua_constant(tolua_S,"E_ITEM_RAW_FISH",E_ITEM_RAW_FISH); + tolua_constant(tolua_S,"E_ITEM_COOKED_FISH",E_ITEM_COOKED_FISH); + tolua_constant(tolua_S,"E_ITEM_DYE",E_ITEM_DYE); + tolua_constant(tolua_S,"E_ITEM_BONE",E_ITEM_BONE); + tolua_constant(tolua_S,"E_ITEM_SUGAR",E_ITEM_SUGAR); + tolua_constant(tolua_S,"E_ITEM_CAKE",E_ITEM_CAKE); + tolua_constant(tolua_S,"E_ITEM_BED",E_ITEM_BED); + tolua_constant(tolua_S,"E_ITEM_REDSTONE_REPEATER",E_ITEM_REDSTONE_REPEATER); + tolua_constant(tolua_S,"E_ITEM_COOKIE",E_ITEM_COOKIE); + tolua_constant(tolua_S,"E_ITEM_MAP",E_ITEM_MAP); + tolua_constant(tolua_S,"E_ITEM_SHEARS",E_ITEM_SHEARS); + tolua_constant(tolua_S,"E_ITEM_MELON_SLICE",E_ITEM_MELON_SLICE); + tolua_constant(tolua_S,"E_ITEM_PUMPKIN_SEEDS",E_ITEM_PUMPKIN_SEEDS); + tolua_constant(tolua_S,"E_ITEM_MELON_SEEDS",E_ITEM_MELON_SEEDS); + tolua_constant(tolua_S,"E_ITEM_RAW_BEEF",E_ITEM_RAW_BEEF); + tolua_constant(tolua_S,"E_ITEM_STEAK",E_ITEM_STEAK); + tolua_constant(tolua_S,"E_ITEM_RAW_CHICKEN",E_ITEM_RAW_CHICKEN); + tolua_constant(tolua_S,"E_ITEM_COOKED_CHICKEN",E_ITEM_COOKED_CHICKEN); + tolua_constant(tolua_S,"E_ITEM_ROTTEN_FLESH",E_ITEM_ROTTEN_FLESH); + tolua_constant(tolua_S,"E_ITEM_ENDER_PEARL",E_ITEM_ENDER_PEARL); + tolua_constant(tolua_S,"E_ITEM_BLAZE_ROD",E_ITEM_BLAZE_ROD); + tolua_constant(tolua_S,"E_ITEM_GHAST_TEAR",E_ITEM_GHAST_TEAR); + tolua_constant(tolua_S,"E_ITEM_GOLD_NUGGET",E_ITEM_GOLD_NUGGET); + tolua_constant(tolua_S,"E_ITEM_NETHER_WART",E_ITEM_NETHER_WART); + tolua_constant(tolua_S,"E_ITEM_POTIONS",E_ITEM_POTIONS); + tolua_constant(tolua_S,"E_ITEM_GLASS_BOTTLE",E_ITEM_GLASS_BOTTLE); + tolua_constant(tolua_S,"E_ITEM_SPIDER_EYE",E_ITEM_SPIDER_EYE); + tolua_constant(tolua_S,"E_ITEM_FERMENTED_SPIDER_EYE",E_ITEM_FERMENTED_SPIDER_EYE); + tolua_constant(tolua_S,"E_ITEM_BLAZE_POWDER",E_ITEM_BLAZE_POWDER); + tolua_constant(tolua_S,"E_ITEM_MAGMA_CREAM",E_ITEM_MAGMA_CREAM); + tolua_constant(tolua_S,"E_ITEM_BREWING_STAND",E_ITEM_BREWING_STAND); + tolua_constant(tolua_S,"E_ITEM_CAULDRON",E_ITEM_CAULDRON); + tolua_constant(tolua_S,"E_ITEM_EYE_OF_ENDER",E_ITEM_EYE_OF_ENDER); + tolua_constant(tolua_S,"E_ITEM_GLISTERING_MELON",E_ITEM_GLISTERING_MELON); + tolua_constant(tolua_S,"E_ITEM_SPAWN_EGG",E_ITEM_SPAWN_EGG); + tolua_constant(tolua_S,"E_ITEM_BOTTLE_O_ENCHANTING",E_ITEM_BOTTLE_O_ENCHANTING); + tolua_constant(tolua_S,"E_ITEM_FIRE_CHARGE",E_ITEM_FIRE_CHARGE); + tolua_constant(tolua_S,"E_ITEM_BOOK_AND_QUILL",E_ITEM_BOOK_AND_QUILL); + tolua_constant(tolua_S,"E_ITEM_WRITTEN_BOOK",E_ITEM_WRITTEN_BOOK); + tolua_constant(tolua_S,"E_ITEM_EMERALD",E_ITEM_EMERALD); + tolua_constant(tolua_S,"E_ITEM_13_DISC",E_ITEM_13_DISC); + tolua_constant(tolua_S,"E_ITEM_CAT_DISC",E_ITEM_CAT_DISC); + tolua_constant(tolua_S,"E_ITEM_BLOCKS_DISC",E_ITEM_BLOCKS_DISC); + tolua_constant(tolua_S,"E_ITEM_CHIRP_DISC",E_ITEM_CHIRP_DISC); + tolua_constant(tolua_S,"E_ITEM_FAR_DISC",E_ITEM_FAR_DISC); + tolua_constant(tolua_S,"E_ITEM_MALL_DISC",E_ITEM_MALL_DISC); + tolua_constant(tolua_S,"E_ITEM_MELLOHI_DISC",E_ITEM_MELLOHI_DISC); + tolua_constant(tolua_S,"E_ITEM_STAL_DISC",E_ITEM_STAL_DISC); + tolua_constant(tolua_S,"E_ITEM_STRAD_DISC",E_ITEM_STRAD_DISC); + tolua_constant(tolua_S,"E_ITEM_WARD_DISC",E_ITEM_WARD_DISC); + tolua_constant(tolua_S,"E_ITEM_11_DISC",E_ITEM_11_DISC); + tolua_constant(tolua_S,"E_META_PLANKS_APPLE",E_META_PLANKS_APPLE); + tolua_constant(tolua_S,"E_META_PLANKS_CONIFER",E_META_PLANKS_CONIFER); + tolua_constant(tolua_S,"E_META_PLANKS_BIRCH",E_META_PLANKS_BIRCH); + tolua_constant(tolua_S,"E_META_PLANKS_JUNGLE",E_META_PLANKS_JUNGLE); + tolua_constant(tolua_S,"E_META_LOG_APPLE",E_META_LOG_APPLE); + tolua_constant(tolua_S,"E_META_LOG_CONIFER",E_META_LOG_CONIFER); + tolua_constant(tolua_S,"E_META_LOG_BIRCH",E_META_LOG_BIRCH); + tolua_constant(tolua_S,"E_META_LOG_JUNGLE",E_META_LOG_JUNGLE); + tolua_constant(tolua_S,"E_META_LEAVES_APPLE",E_META_LEAVES_APPLE); + tolua_constant(tolua_S,"E_META_LEAVES_CONIFER",E_META_LEAVES_CONIFER); + tolua_constant(tolua_S,"E_META_LEAVES_BIRCH",E_META_LEAVES_BIRCH); + tolua_constant(tolua_S,"E_META_LEAVES_JUNGLE",E_META_LEAVES_JUNGLE); + tolua_constant(tolua_S,"E_META_SAPLING_APPLE",E_META_SAPLING_APPLE); + tolua_constant(tolua_S,"E_META_SAPLING_CONIFER",E_META_SAPLING_CONIFER); + tolua_constant(tolua_S,"E_META_SAPLING_BIRCH",E_META_SAPLING_BIRCH); + tolua_constant(tolua_S,"E_META_SAPLING_JUNGLE",E_META_SAPLING_JUNGLE); + tolua_constant(tolua_S,"E_META_TALL_GRASS_DEAD_SHRUB",E_META_TALL_GRASS_DEAD_SHRUB); + tolua_constant(tolua_S,"E_META_TALL_GRASS_GRASS",E_META_TALL_GRASS_GRASS); + tolua_constant(tolua_S,"E_META_TALL_GRASS_FERN",E_META_TALL_GRASS_FERN); + tolua_constant(tolua_S,"E_META_SANDSTONE_NORMAL",E_META_SANDSTONE_NORMAL); + tolua_constant(tolua_S,"E_META_SANDSTONE_ORNAMENT",E_META_SANDSTONE_ORNAMENT); + tolua_constant(tolua_S,"E_META_SANDSTONE_SMOOTH",E_META_SANDSTONE_SMOOTH); + tolua_constant(tolua_S,"E_META_WOOL_WHITE",E_META_WOOL_WHITE); + tolua_constant(tolua_S,"E_META_WOOL_ORANGE",E_META_WOOL_ORANGE); + tolua_constant(tolua_S,"E_META_WOOL_MAGENTA",E_META_WOOL_MAGENTA); + tolua_constant(tolua_S,"E_META_WOOL_LIGHTBLUE",E_META_WOOL_LIGHTBLUE); + tolua_constant(tolua_S,"E_META_WOOL_YELLOW",E_META_WOOL_YELLOW); + tolua_constant(tolua_S,"E_META_WOOL_LIGHTGREEN",E_META_WOOL_LIGHTGREEN); + tolua_constant(tolua_S,"E_META_WOOL_PINK",E_META_WOOL_PINK); + tolua_constant(tolua_S,"E_META_WOOL_GRAY",E_META_WOOL_GRAY); + tolua_constant(tolua_S,"E_META_WOOL_LIGHTGRAY",E_META_WOOL_LIGHTGRAY); + tolua_constant(tolua_S,"E_META_WOOL_CYAN",E_META_WOOL_CYAN); + tolua_constant(tolua_S,"E_META_WOOL_PURPLE",E_META_WOOL_PURPLE); + tolua_constant(tolua_S,"E_META_WOOL_BLUE",E_META_WOOL_BLUE); + tolua_constant(tolua_S,"E_META_WOOL_BROWN",E_META_WOOL_BROWN); + tolua_constant(tolua_S,"E_META_WOOL_GREEN",E_META_WOOL_GREEN); + tolua_constant(tolua_S,"E_META_WOOL_RED",E_META_WOOL_RED); + tolua_constant(tolua_S,"E_META_WOOL_BLACK",E_META_WOOL_BLACK); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_STONE",E_META_DOUBLE_STEP_STONE); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_SANDSTONE",E_META_DOUBLE_STEP_SANDSTONE); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_WOODEN",E_META_DOUBLE_STEP_WOODEN); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_COBBLESTONE",E_META_DOUBLE_STEP_COBBLESTONE); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_BRICK",E_META_DOUBLE_STEP_BRICK); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_STONE_BRICK",E_META_DOUBLE_STEP_STONE_BRICK); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_STONE_SECRET",E_META_DOUBLE_STEP_STONE_SECRET); + tolua_constant(tolua_S,"E_META_STEP_STONE",E_META_STEP_STONE); + tolua_constant(tolua_S,"E_META_STEP_SANDSTONE",E_META_STEP_SANDSTONE); + tolua_constant(tolua_S,"E_META_STEP_PLANKS",E_META_STEP_PLANKS); + tolua_constant(tolua_S,"E_META_STEP_COBBLESTONE",E_META_STEP_COBBLESTONE); + tolua_constant(tolua_S,"E_META_STEP_BRICK",E_META_STEP_BRICK); + tolua_constant(tolua_S,"E_META_STEP_STONE_BRICK",E_META_STEP_STONE_BRICK); + tolua_constant(tolua_S,"E_META_STEP_STONE_SECRET",E_META_STEP_STONE_SECRET); + tolua_constant(tolua_S,"E_META_SILVERFISH_EGG_STONE",E_META_SILVERFISH_EGG_STONE); + tolua_constant(tolua_S,"E_META_SILVERFISH_EGG_COBBLESTONE",E_META_SILVERFISH_EGG_COBBLESTONE); + tolua_constant(tolua_S,"E_META_SILVERFISH_EGG_STONE_BRICK",E_META_SILVERFISH_EGG_STONE_BRICK); + tolua_constant(tolua_S,"E_META_STONE_BRICK_NORMAL",E_META_STONE_BRICK_NORMAL); + tolua_constant(tolua_S,"E_META_STONE_BRICK_MOSSY",E_META_STONE_BRICK_MOSSY); + tolua_constant(tolua_S,"E_META_STONE_BRICK_CRACKED",E_META_STONE_BRICK_CRACKED); + tolua_constant(tolua_S,"E_META_STONE_BRICK_ORNAMENT",E_META_STONE_BRICK_ORNAMENT); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_APPLE",E_BLOCK_WOODEN_DOUBLE_STEP_APPLE); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_CONIFER",E_BLOCK_WOODEN_DOUBLE_STEP_CONIFER); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_BIRCH",E_BLOCK_WOODEN_DOUBLE_STEP_BIRCH); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_JUNGLE",E_BLOCK_WOODEN_DOUBLE_STEP_JUNGLE); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_APPLE",E_BLOCK_WOODEN_STEP_APPLE); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_CONIFER",E_BLOCK_WOODEN_STEP_CONIFER); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_BIRCH",E_BLOCK_WOODEN_STEP_BIRCH); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_JUNGLE",E_BLOCK_WOODEN_STEP_JUNGLE); + tolua_constant(tolua_S,"E_META_COAL_NORMAL",E_META_COAL_NORMAL); + tolua_constant(tolua_S,"E_META_COAL_CHARCOAL",E_META_COAL_CHARCOAL); + tolua_constant(tolua_S,"E_META_GOLDEN_APPLE_NORMAL",E_META_GOLDEN_APPLE_NORMAL); + tolua_constant(tolua_S,"E_META_GOLDEN_APPLE_ENCHANTED",E_META_GOLDEN_APPLE_ENCHANTED); + tolua_constant(tolua_S,"E_META_DYE_BLACK",E_META_DYE_BLACK); + tolua_constant(tolua_S,"E_META_DYE_RED",E_META_DYE_RED); + tolua_constant(tolua_S,"E_META_DYE_GREEN",E_META_DYE_GREEN); + tolua_constant(tolua_S,"E_META_DYE_BROWN",E_META_DYE_BROWN); + tolua_constant(tolua_S,"E_META_DYE_BLUE",E_META_DYE_BLUE); + tolua_constant(tolua_S,"E_META_DYE_PURPLE",E_META_DYE_PURPLE); + tolua_constant(tolua_S,"E_META_DYE_CYAN",E_META_DYE_CYAN); + tolua_constant(tolua_S,"E_META_DYE_LIGHTGRAY",E_META_DYE_LIGHTGRAY); + tolua_constant(tolua_S,"E_META_DYE_GRAY",E_META_DYE_GRAY); + tolua_constant(tolua_S,"E_META_DYE_PINK",E_META_DYE_PINK); + tolua_constant(tolua_S,"E_META_DYE_LIGHTGREEN",E_META_DYE_LIGHTGREEN); + tolua_constant(tolua_S,"E_META_DYE_YELLOW",E_META_DYE_YELLOW); + tolua_constant(tolua_S,"E_META_DYE_LIGHTBLUE",E_META_DYE_LIGHTBLUE); + tolua_constant(tolua_S,"E_META_DYE_MAGENTA",E_META_DYE_MAGENTA); + tolua_constant(tolua_S,"E_META_DYE_ORANGE",E_META_DYE_ORANGE); + tolua_constant(tolua_S,"E_META_DYE_WHITE",E_META_DYE_WHITE); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_CREEPER",E_META_SPAWN_EGG_CREEPER); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SKELETON",E_META_SPAWN_EGG_SKELETON); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SPIDER",E_META_SPAWN_EGG_SPIDER); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_ZOMBIE",E_META_SPAWN_EGG_ZOMBIE); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SLIME",E_META_SPAWN_EGG_SLIME); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_GHAST",E_META_SPAWN_EGG_GHAST); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_ZOMBIE_PIGMAN",E_META_SPAWN_EGG_ZOMBIE_PIGMAN); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_ENDERMAN",E_META_SPAWN_EGG_ENDERMAN); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_CAVE_SPIDER",E_META_SPAWN_EGG_CAVE_SPIDER); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SILVERFISH",E_META_SPAWN_EGG_SILVERFISH); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_BLAZE",E_META_SPAWN_EGG_BLAZE); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_MAGMA_CUBE",E_META_SPAWN_EGG_MAGMA_CUBE); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_GIANT",E_META_SPAWN_EGG_GIANT); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_ENDER_DRAGON",E_META_SPAWN_EGG_ENDER_DRAGON); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_PIG",E_META_SPAWN_EGG_PIG); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SHEEP",E_META_SPAWN_EGG_SHEEP); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_COW",E_META_SPAWN_EGG_COW); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_CHICKEN",E_META_SPAWN_EGG_CHICKEN); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SQUID",E_META_SPAWN_EGG_SQUID); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_WOLF",E_META_SPAWN_EGG_WOLF); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_MOOSHROOM",E_META_SPAWN_EGG_MOOSHROOM); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_OCELOT",E_META_SPAWN_EGG_OCELOT); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_VILLAGER",E_META_SPAWN_EGG_VILLAGER); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SNOW_GOLEM",E_META_SPAWN_EGG_SNOW_GOLEM); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_IRON_GOLEM",E_META_SPAWN_EGG_IRON_GOLEM); + tolua_function(tolua_S,"BlockStringToType",tolua_AllToLua_BlockStringToType00); + tolua_function(tolua_S,"StringToItem",tolua_AllToLua_StringToItem00); + tolua_constant(tolua_S,"E_KEEP_ALIVE",E_KEEP_ALIVE); + tolua_constant(tolua_S,"E_LOGIN",E_LOGIN); + tolua_constant(tolua_S,"E_HANDSHAKE",E_HANDSHAKE); + tolua_constant(tolua_S,"E_CHAT",E_CHAT); + tolua_constant(tolua_S,"E_UPDATE_TIME",E_UPDATE_TIME); + tolua_constant(tolua_S,"E_ENTITY_EQUIPMENT",E_ENTITY_EQUIPMENT); + tolua_constant(tolua_S,"E_USE_ENTITY",E_USE_ENTITY); + tolua_constant(tolua_S,"E_UPDATE_HEALTH",E_UPDATE_HEALTH); + tolua_constant(tolua_S,"E_RESPAWN",E_RESPAWN); + tolua_constant(tolua_S,"E_FLYING",E_FLYING); + tolua_constant(tolua_S,"E_PLAYERPOS",E_PLAYERPOS); + tolua_constant(tolua_S,"E_PLAYERLOOK",E_PLAYERLOOK); + tolua_constant(tolua_S,"E_PLAYERMOVELOOK",E_PLAYERMOVELOOK); + tolua_constant(tolua_S,"E_BLOCK_DIG",E_BLOCK_DIG); + tolua_constant(tolua_S,"E_BLOCK_PLACE",E_BLOCK_PLACE); + tolua_constant(tolua_S,"E_ITEM_SWITCH",E_ITEM_SWITCH); + tolua_constant(tolua_S,"E_ADD_TO_INV",E_ADD_TO_INV); + tolua_constant(tolua_S,"E_ANIMATION",E_ANIMATION); + tolua_constant(tolua_S,"E_PACKET_13",E_PACKET_13); + tolua_constant(tolua_S,"E_NAMED_ENTITY_SPAWN",E_NAMED_ENTITY_SPAWN); + tolua_constant(tolua_S,"E_PICKUP_SPAWN",E_PICKUP_SPAWN); + tolua_constant(tolua_S,"E_COLLECT_ITEM",E_COLLECT_ITEM); + tolua_constant(tolua_S,"E_ADD_VEHICLE",E_ADD_VEHICLE); + tolua_constant(tolua_S,"E_SPAWN_MOB",E_SPAWN_MOB); + tolua_constant(tolua_S,"E_DESTROY_ENT",E_DESTROY_ENT); + tolua_constant(tolua_S,"E_ENTITY",E_ENTITY); + tolua_constant(tolua_S,"E_REL_ENT_MOVE",E_REL_ENT_MOVE); + tolua_constant(tolua_S,"E_ENT_LOOK",E_ENT_LOOK); + tolua_constant(tolua_S,"E_REL_ENT_MOVE_LOOK",E_REL_ENT_MOVE_LOOK); + tolua_constant(tolua_S,"E_ENT_TELEPORT",E_ENT_TELEPORT); + tolua_constant(tolua_S,"E_ENT_HEAD_LOOK",E_ENT_HEAD_LOOK); + tolua_constant(tolua_S,"E_ENT_STATUS",E_ENT_STATUS); + tolua_constant(tolua_S,"E_METADATA",E_METADATA); + tolua_constant(tolua_S,"E_PRE_CHUNK",E_PRE_CHUNK); + tolua_constant(tolua_S,"E_MAP_CHUNK",E_MAP_CHUNK); + tolua_constant(tolua_S,"E_MULTI_BLOCK",E_MULTI_BLOCK); + tolua_constant(tolua_S,"E_BLOCK_CHANGE",E_BLOCK_CHANGE); + tolua_constant(tolua_S,"E_BLOCK_ACTION",E_BLOCK_ACTION); + tolua_constant(tolua_S,"E_EXPLOSION",E_EXPLOSION); + tolua_constant(tolua_S,"E_SOUND_EFFECT",E_SOUND_EFFECT); + tolua_constant(tolua_S,"E_NEW_INVALID_STATE",E_NEW_INVALID_STATE); + tolua_constant(tolua_S,"E_THUNDERBOLT",E_THUNDERBOLT); + tolua_constant(tolua_S,"E_WINDOW_OPEN",E_WINDOW_OPEN); + tolua_constant(tolua_S,"E_WINDOW_CLOSE",E_WINDOW_CLOSE); + tolua_constant(tolua_S,"E_WINDOW_CLICK",E_WINDOW_CLICK); + tolua_constant(tolua_S,"E_INVENTORY_SLOT",E_INVENTORY_SLOT); + tolua_constant(tolua_S,"E_INVENTORY_WHOLE",E_INVENTORY_WHOLE); + tolua_constant(tolua_S,"E_INVENTORY_PROGRESS",E_INVENTORY_PROGRESS); + tolua_constant(tolua_S,"E_CREATIVE_INVENTORY_ACTION",E_CREATIVE_INVENTORY_ACTION); + tolua_constant(tolua_S,"E_UPDATE_SIGN",E_UPDATE_SIGN); + tolua_constant(tolua_S,"E_PLAYER_LIST_ITEM",E_PLAYER_LIST_ITEM); + tolua_constant(tolua_S,"E_PLAYER_ABILITIES",E_PLAYER_ABILITIES); + tolua_constant(tolua_S,"E_PING",E_PING); + tolua_constant(tolua_S,"E_DISCONNECT",E_DISCONNECT); + tolua_array(tolua_S,"g_BlockLightValue",tolua_get_AllToLua_g_BlockLightValue,tolua_set_AllToLua_g_BlockLightValue); + tolua_array(tolua_S,"g_BlockSpreadLightFalloff",tolua_get_AllToLua_g_BlockSpreadLightFalloff,tolua_set_AllToLua_g_BlockSpreadLightFalloff); + tolua_array(tolua_S,"g_BlockTransparent",tolua_get_AllToLua_g_BlockTransparent,tolua_set_AllToLua_g_BlockTransparent); + tolua_array(tolua_S,"g_BlockOneHitDig",tolua_get_AllToLua_g_BlockOneHitDig,tolua_set_AllToLua_g_BlockOneHitDig); + tolua_function(tolua_S,"IsValidBlock",tolua_AllToLua_IsValidBlock00); + tolua_function(tolua_S,"IsValidItem",tolua_AllToLua_IsValidItem00); + tolua_function(tolua_S,"AddDirection",tolua_AllToLua_AddDirection00); + tolua_module(tolua_S,"ItemCategory",0); + tolua_beginmodule(tolua_S,"ItemCategory"); + tolua_function(tolua_S,"IsPickaxe",tolua_AllToLua_ItemCategory_IsPickaxe00); + tolua_function(tolua_S,"IsAxe",tolua_AllToLua_ItemCategory_IsAxe00); + tolua_function(tolua_S,"IsSword",tolua_AllToLua_ItemCategory_IsSword00); + tolua_function(tolua_S,"IsHoe",tolua_AllToLua_ItemCategory_IsHoe00); + tolua_function(tolua_S,"IsShovel",tolua_AllToLua_ItemCategory_IsShovel00); + tolua_function(tolua_S,"IsTool",tolua_AllToLua_ItemCategory_IsTool00); + tolua_endmodule(tolua_S); + tolua_constant(tolua_S,"eGameMode_Survival",eGameMode_Survival); + tolua_constant(tolua_S,"eGameMode_Creative",eGameMode_Creative); + tolua_constant(tolua_S,"eWeather_Sunny",eWeather_Sunny); + tolua_constant(tolua_S,"eWeather_Rain",eWeather_Rain); + tolua_constant(tolua_S,"eWeather_ThunderStorm",eWeather_ThunderStorm); + tolua_function(tolua_S,"GetTime",tolua_AllToLua_GetTime00); + tolua_function(tolua_S,"GetChar",tolua_AllToLua_GetChar00); + tolua_cclass(tolua_S,"cStringMap","cStringMap","",NULL); + tolua_beginmodule(tolua_S,"cStringMap"); + tolua_function(tolua_S,"clear",tolua_AllToLua_cStringMap_clear00); + tolua_function(tolua_S,"size",tolua_AllToLua_cStringMap_size00); + tolua_function(tolua_S,"get",tolua_AllToLua_cStringMap_get00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cChatColor","cChatColor","",NULL); + tolua_beginmodule(tolua_S,"cChatColor"); + tolua_variable(tolua_S,"Color",tolua_get_cChatColor_Color,NULL); + tolua_variable(tolua_S,"Delimiter",tolua_get_cChatColor_Delimiter,NULL); + tolua_variable(tolua_S,"Black",tolua_get_cChatColor_Black,NULL); + tolua_variable(tolua_S,"Navy",tolua_get_cChatColor_Navy,NULL); + tolua_variable(tolua_S,"Green",tolua_get_cChatColor_Green,NULL); + tolua_variable(tolua_S,"Blue",tolua_get_cChatColor_Blue,NULL); + tolua_variable(tolua_S,"Red",tolua_get_cChatColor_Red,NULL); + tolua_variable(tolua_S,"Purple",tolua_get_cChatColor_Purple,NULL); + tolua_variable(tolua_S,"Gold",tolua_get_cChatColor_Gold,NULL); + tolua_variable(tolua_S,"LightGray",tolua_get_cChatColor_LightGray,NULL); + tolua_variable(tolua_S,"Gray",tolua_get_cChatColor_Gray,NULL); + tolua_variable(tolua_S,"DarkPurple",tolua_get_cChatColor_DarkPurple,NULL); + tolua_variable(tolua_S,"LightGreen",tolua_get_cChatColor_LightGreen,NULL); + tolua_variable(tolua_S,"LightBlue",tolua_get_cChatColor_LightBlue,NULL); + tolua_variable(tolua_S,"Rose",tolua_get_cChatColor_Rose,NULL); + tolua_variable(tolua_S,"LightPurple",tolua_get_cChatColor_LightPurple,NULL); + tolua_variable(tolua_S,"Yellow",tolua_get_cChatColor_Yellow,NULL); + tolua_variable(tolua_S,"White",tolua_get_cChatColor_White,NULL); + tolua_variable(tolua_S,"Random",tolua_get_cChatColor_Random,NULL); + tolua_variable(tolua_S,"Bold",tolua_get_cChatColor_Bold,NULL); + tolua_variable(tolua_S,"Strikethrough",tolua_get_cChatColor_Strikethrough,NULL); + tolua_variable(tolua_S,"Underlined",tolua_get_cChatColor_Underlined,NULL); + tolua_variable(tolua_S,"Italic",tolua_get_cChatColor_Italic,NULL); + tolua_variable(tolua_S,"Plain",tolua_get_cChatColor_Plain,NULL); + tolua_function(tolua_S,"MakeColor",tolua_AllToLua_cChatColor_MakeColor00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cClientHandle","cClientHandle","",NULL); + tolua_beginmodule(tolua_S,"cClientHandle"); + tolua_function(tolua_S,"GetPlayer",tolua_AllToLua_cClientHandle_GetPlayer00); + tolua_function(tolua_S,"Kick",tolua_AllToLua_cClientHandle_Kick00); + tolua_function(tolua_S,"GetUsername",tolua_AllToLua_cClientHandle_GetUsername00); + tolua_function(tolua_S,"GetPing",tolua_AllToLua_cClientHandle_GetPing00); + tolua_function(tolua_S,"SetViewDistance",tolua_AllToLua_cClientHandle_SetViewDistance00); + tolua_function(tolua_S,"GetViewDistance",tolua_AllToLua_cClientHandle_GetViewDistance00); + tolua_function(tolua_S,"GetUniqueID",tolua_AllToLua_cClientHandle_GetUniqueID00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cEntity","cEntity","",tolua_collect_cEntity); + #else + tolua_cclass(tolua_S,"cEntity","cEntity","",NULL); + #endif + tolua_beginmodule(tolua_S,"cEntity"); + tolua_function(tolua_S,"delete",tolua_AllToLua_cEntity_delete00); + tolua_function(tolua_S,"Initialize",tolua_AllToLua_cEntity_Initialize00); + tolua_constant(tolua_S,"eEntityType_Entity",cEntity::eEntityType_Entity); + tolua_constant(tolua_S,"eEntityType_Player",cEntity::eEntityType_Player); + tolua_constant(tolua_S,"eEntityType_Pickup",cEntity::eEntityType_Pickup); + tolua_function(tolua_S,"GetEntityType",tolua_AllToLua_cEntity_GetEntityType00); + tolua_function(tolua_S,"IsA",tolua_AllToLua_cEntity_IsA00); + tolua_function(tolua_S,"GetClass",tolua_AllToLua_cEntity_GetClass00); + tolua_function(tolua_S,"GetWorld",tolua_AllToLua_cEntity_GetWorld00); + tolua_function(tolua_S,"GetPosition",tolua_AllToLua_cEntity_GetPosition00); + tolua_function(tolua_S,"GetPosX",tolua_AllToLua_cEntity_GetPosX00); + tolua_function(tolua_S,"GetPosY",tolua_AllToLua_cEntity_GetPosY00); + tolua_function(tolua_S,"GetPosZ",tolua_AllToLua_cEntity_GetPosZ00); + tolua_function(tolua_S,"GetRot",tolua_AllToLua_cEntity_GetRot00); + tolua_function(tolua_S,"GetRotation",tolua_AllToLua_cEntity_GetRotation00); + tolua_function(tolua_S,"GetPitch",tolua_AllToLua_cEntity_GetPitch00); + tolua_function(tolua_S,"GetRoll",tolua_AllToLua_cEntity_GetRoll00); + tolua_function(tolua_S,"GetLookVector",tolua_AllToLua_cEntity_GetLookVector00); + tolua_function(tolua_S,"GetChunkX",tolua_AllToLua_cEntity_GetChunkX00); + tolua_function(tolua_S,"GetChunkY",tolua_AllToLua_cEntity_GetChunkY00); + tolua_function(tolua_S,"GetChunkZ",tolua_AllToLua_cEntity_GetChunkZ00); + tolua_function(tolua_S,"SetPosX",tolua_AllToLua_cEntity_SetPosX00); + tolua_function(tolua_S,"SetPosY",tolua_AllToLua_cEntity_SetPosY00); + tolua_function(tolua_S,"SetPosZ",tolua_AllToLua_cEntity_SetPosZ00); + tolua_function(tolua_S,"SetPosition",tolua_AllToLua_cEntity_SetPosition00); + tolua_function(tolua_S,"SetPosition",tolua_AllToLua_cEntity_SetPosition01); + tolua_function(tolua_S,"SetRot",tolua_AllToLua_cEntity_SetRot00); + tolua_function(tolua_S,"SetRotation",tolua_AllToLua_cEntity_SetRotation00); + tolua_function(tolua_S,"SetPitch",tolua_AllToLua_cEntity_SetPitch00); + tolua_function(tolua_S,"SetRoll",tolua_AllToLua_cEntity_SetRoll00); + tolua_function(tolua_S,"GetUniqueID",tolua_AllToLua_cEntity_GetUniqueID00); + tolua_function(tolua_S,"IsDestroyed",tolua_AllToLua_cEntity_IsDestroyed00); + tolua_function(tolua_S,"Destroy",tolua_AllToLua_cEntity_Destroy00); + tolua_function(tolua_S,"Tick",tolua_AllToLua_cEntity_Tick00); + tolua_function(tolua_S,"SpawnOn",tolua_AllToLua_cEntity_SpawnOn00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"Lua__cEntity","Lua__cEntity","cEntity",tolua_collect_Lua__cEntity); + #else + tolua_cclass(tolua_S,"Lua__cEntity","Lua__cEntity","cEntity",NULL); + #endif + tolua_beginmodule(tolua_S,"Lua__cEntity"); + tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cEntity_tolua__set_instance00); + tolua_function(tolua_S,"cEntity__Initialize",tolua_AllToLua_Lua__cEntity_cEntity__Initialize00); + tolua_function(tolua_S,"cEntity__GetEntityType",tolua_AllToLua_Lua__cEntity_cEntity__GetEntityType00); + tolua_function(tolua_S,"cEntity__IsA",tolua_AllToLua_Lua__cEntity_cEntity__IsA00); + tolua_function(tolua_S,"cEntity__GetClass",tolua_AllToLua_Lua__cEntity_cEntity__GetClass00); + tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cEntity_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cEntity_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cEntity_new00_local); + tolua_function(tolua_S,"delete",tolua_AllToLua_Lua__cEntity_delete00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"TakeDamageInfo","TakeDamageInfo","",NULL); + tolua_beginmodule(tolua_S,"TakeDamageInfo"); + tolua_variable(tolua_S,"Damage",tolua_get_TakeDamageInfo_Damage,tolua_set_TakeDamageInfo_Damage); + tolua_variable(tolua_S,"Instigator",tolua_get_TakeDamageInfo_Instigator_ptr,tolua_set_TakeDamageInfo_Instigator_ptr); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cPawn","cPawn","cEntity",NULL); + tolua_beginmodule(tolua_S,"cPawn"); + tolua_function(tolua_S,"TeleportToEntity",tolua_AllToLua_cPawn_TeleportToEntity00); + tolua_function(tolua_S,"TeleportTo",tolua_AllToLua_cPawn_TeleportTo00); + tolua_function(tolua_S,"Heal",tolua_AllToLua_cPawn_Heal00); + tolua_function(tolua_S,"TakeDamage",tolua_AllToLua_cPawn_TakeDamage00); + tolua_function(tolua_S,"KilledBy",tolua_AllToLua_cPawn_KilledBy00); + tolua_function(tolua_S,"GetHealth",tolua_AllToLua_cPawn_GetHealth00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"Lua__cPawn","Lua__cPawn","cPawn",NULL); + tolua_beginmodule(tolua_S,"Lua__cPawn"); + tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPawn_tolua__set_instance00); + tolua_function(tolua_S,"cPawn__TeleportToEntity",tolua_AllToLua_Lua__cPawn_cPawn__TeleportToEntity00); + tolua_function(tolua_S,"cPawn__TeleportTo",tolua_AllToLua_Lua__cPawn_cPawn__TeleportTo00); + tolua_function(tolua_S,"cPawn__TakeDamage",tolua_AllToLua_Lua__cPawn_cPawn__TakeDamage00); + tolua_function(tolua_S,"cPawn__KilledBy",tolua_AllToLua_Lua__cPawn_cPawn__KilledBy00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cPlayer","cPlayer","cPawn",NULL); + tolua_beginmodule(tolua_S,"cPlayer"); + tolua_function(tolua_S,"Initialize",tolua_AllToLua_cPlayer_Initialize00); + tolua_function(tolua_S,"GetEyeHeight",tolua_AllToLua_cPlayer_GetEyeHeight00); + tolua_function(tolua_S,"GetEyePosition",tolua_AllToLua_cPlayer_GetEyePosition00); + tolua_function(tolua_S,"GetFlying",tolua_AllToLua_cPlayer_GetFlying00); + tolua_function(tolua_S,"GetStance",tolua_AllToLua_cPlayer_GetStance00); + tolua_function(tolua_S,"GetInventory",tolua_AllToLua_cPlayer_GetInventory00); + tolua_function(tolua_S,"TeleportTo",tolua_AllToLua_cPlayer_TeleportTo00); + tolua_function(tolua_S,"GetGameMode",tolua_AllToLua_cPlayer_GetGameMode00); + tolua_function(tolua_S,"GetIP",tolua_AllToLua_cPlayer_GetIP00); + tolua_function(tolua_S,"GetLastBlockActionTime",tolua_AllToLua_cPlayer_GetLastBlockActionTime00); + tolua_function(tolua_S,"GetLastBlockActionCnt",tolua_AllToLua_cPlayer_GetLastBlockActionCnt00); + tolua_function(tolua_S,"SetLastBlockActionCnt",tolua_AllToLua_cPlayer_SetLastBlockActionCnt00); + tolua_function(tolua_S,"SetLastBlockActionTime",tolua_AllToLua_cPlayer_SetLastBlockActionTime00); + tolua_function(tolua_S,"SetGameMode",tolua_AllToLua_cPlayer_SetGameMode00); + tolua_function(tolua_S,"MoveTo",tolua_AllToLua_cPlayer_MoveTo00); + tolua_function(tolua_S,"GetClientHandle",tolua_AllToLua_cPlayer_GetClientHandle00); + tolua_function(tolua_S,"SendMessage",tolua_AllToLua_cPlayer_SendMessage00); + tolua_function(tolua_S,"GetName",tolua_AllToLua_cPlayer_GetName00); + tolua_function(tolua_S,"SetName",tolua_AllToLua_cPlayer_SetName00); + tolua_function(tolua_S,"AddToGroup",tolua_AllToLua_cPlayer_AddToGroup00); + tolua_function(tolua_S,"CanUseCommand",tolua_AllToLua_cPlayer_CanUseCommand00); + tolua_function(tolua_S,"HasPermission",tolua_AllToLua_cPlayer_HasPermission00); + tolua_function(tolua_S,"IsInGroup",tolua_AllToLua_cPlayer_IsInGroup00); + tolua_function(tolua_S,"GetColor",tolua_AllToLua_cPlayer_GetColor00); + tolua_function(tolua_S,"TossItem",tolua_AllToLua_cPlayer_TossItem00); + tolua_function(tolua_S,"Heal",tolua_AllToLua_cPlayer_Heal00); + tolua_function(tolua_S,"TakeDamage",tolua_AllToLua_cPlayer_TakeDamage00); + tolua_function(tolua_S,"KilledBy",tolua_AllToLua_cPlayer_KilledBy00); + tolua_function(tolua_S,"Respawn",tolua_AllToLua_cPlayer_Respawn00); + tolua_function(tolua_S,"SetVisible",tolua_AllToLua_cPlayer_SetVisible00); + tolua_function(tolua_S,"IsVisible",tolua_AllToLua_cPlayer_IsVisible00); + tolua_function(tolua_S,"MoveToWorld",tolua_AllToLua_cPlayer_MoveToWorld00); + tolua_function(tolua_S,"LoadPermissionsFromDisk",tolua_AllToLua_cPlayer_LoadPermissionsFromDisk00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"Lua__cPlayer","Lua__cPlayer","cPlayer",NULL); + tolua_beginmodule(tolua_S,"Lua__cPlayer"); + tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPlayer_tolua__set_instance00); + tolua_function(tolua_S,"cPlayer__Initialize",tolua_AllToLua_Lua__cPlayer_cPlayer__Initialize00); + tolua_function(tolua_S,"cPlayer__TeleportTo",tolua_AllToLua_Lua__cPlayer_cPlayer__TeleportTo00); + tolua_function(tolua_S,"cPlayer__MoveTo",tolua_AllToLua_Lua__cPlayer_cPlayer__MoveTo00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cPluginManager","cPluginManager","",NULL); + tolua_beginmodule(tolua_S,"cPluginManager"); + tolua_constant(tolua_S,"HOOK_TICK",cPluginManager::HOOK_TICK); + tolua_constant(tolua_S,"HOOK_CHAT",cPluginManager::HOOK_CHAT); + tolua_constant(tolua_S,"HOOK_COLLECT_ITEM",cPluginManager::HOOK_COLLECT_ITEM); + tolua_constant(tolua_S,"HOOK_BLOCK_DIG",cPluginManager::HOOK_BLOCK_DIG); + tolua_constant(tolua_S,"HOOK_BLOCK_PLACE",cPluginManager::HOOK_BLOCK_PLACE); + tolua_constant(tolua_S,"HOOK_DISCONNECT",cPluginManager::HOOK_DISCONNECT); + tolua_constant(tolua_S,"HOOK_HANDSHAKE",cPluginManager::HOOK_HANDSHAKE); + tolua_constant(tolua_S,"HOOK_LOGIN",cPluginManager::HOOK_LOGIN); + tolua_constant(tolua_S,"HOOK_PLAYER_SPAWN",cPluginManager::HOOK_PLAYER_SPAWN); + tolua_constant(tolua_S,"HOOK_PLAYER_JOIN",cPluginManager::HOOK_PLAYER_JOIN); + tolua_constant(tolua_S,"HOOK_PLAYER_MOVE",cPluginManager::HOOK_PLAYER_MOVE); + tolua_constant(tolua_S,"HOOK_TAKE_DAMAGE",cPluginManager::HOOK_TAKE_DAMAGE); + tolua_constant(tolua_S,"HOOK_KILLED",cPluginManager::HOOK_KILLED); + tolua_constant(tolua_S,"HOOK_CHUNK_GENERATED",cPluginManager::HOOK_CHUNK_GENERATED); + tolua_constant(tolua_S,"HOOK_CHUNK_GENERATING",cPluginManager::HOOK_CHUNK_GENERATING); + tolua_constant(tolua_S,"HOOK_BLOCK_TO_DROPS",cPluginManager::HOOK_BLOCK_TO_DROPS); + tolua_constant(tolua_S,"HOOK_PRE_CRAFTING",cPluginManager::HOOK_PRE_CRAFTING); + tolua_constant(tolua_S,"HOOK_CRAFTING_NO_RECIPE",cPluginManager::HOOK_CRAFTING_NO_RECIPE); + tolua_constant(tolua_S,"HOOK_POST_CRAFTING",cPluginManager::HOOK_POST_CRAFTING); + tolua_constant(tolua_S,"HOOK_BLOCK_TO_PICKUP",cPluginManager::HOOK_BLOCK_TO_PICKUP); + tolua_constant(tolua_S,"HOOK_WEATHER_CHANGE",cPluginManager::HOOK_WEATHER_CHANGE); + tolua_constant(tolua_S,"E_PLUGIN_TICK",cPluginManager::E_PLUGIN_TICK); + tolua_constant(tolua_S,"E_PLUGIN_CHAT",cPluginManager::E_PLUGIN_CHAT); + tolua_constant(tolua_S,"E_PLUGIN_COLLECT_ITEM",cPluginManager::E_PLUGIN_COLLECT_ITEM); + tolua_constant(tolua_S,"E_PLUGIN_BLOCK_DIG",cPluginManager::E_PLUGIN_BLOCK_DIG); + tolua_constant(tolua_S,"E_PLUGIN_BLOCK_PLACE",cPluginManager::E_PLUGIN_BLOCK_PLACE); + tolua_constant(tolua_S,"E_PLUGIN_DISCONNECT",cPluginManager::E_PLUGIN_DISCONNECT); + tolua_constant(tolua_S,"E_PLUGIN_HANDSHAKE",cPluginManager::E_PLUGIN_HANDSHAKE); + tolua_constant(tolua_S,"E_PLUGIN_LOGIN",cPluginManager::E_PLUGIN_LOGIN); + tolua_constant(tolua_S,"E_PLUGIN_PLAYER_SPAWN",cPluginManager::E_PLUGIN_PLAYER_SPAWN); + tolua_constant(tolua_S,"E_PLUGIN_PLAYER_JOIN",cPluginManager::E_PLUGIN_PLAYER_JOIN); + tolua_constant(tolua_S,"E_PLUGIN_PLAYER_MOVE",cPluginManager::E_PLUGIN_PLAYER_MOVE); + tolua_constant(tolua_S,"E_PLUGIN_TAKE_DAMAGE",cPluginManager::E_PLUGIN_TAKE_DAMAGE); + tolua_constant(tolua_S,"E_PLUGIN_KILLED",cPluginManager::E_PLUGIN_KILLED); + tolua_constant(tolua_S,"E_PLUGIN_CHUNK_GENERATED",cPluginManager::E_PLUGIN_CHUNK_GENERATED); + tolua_constant(tolua_S,"E_PLUGIN_CHUNK_GENERATING",cPluginManager::E_PLUGIN_CHUNK_GENERATING); + tolua_constant(tolua_S,"E_PLUGIN_BLOCK_TO_DROPS",cPluginManager::E_PLUGIN_BLOCK_TO_DROPS); + tolua_function(tolua_S,"GetPluginManager",tolua_AllToLua_cPluginManager_GetPluginManager00); + tolua_function(tolua_S,"GetPlugin",tolua_AllToLua_cPluginManager_GetPlugin00); + tolua_function(tolua_S,"ReloadPlugins",tolua_AllToLua_cPluginManager_ReloadPlugins00); + tolua_function(tolua_S,"AddPlugin",tolua_AllToLua_cPluginManager_AddPlugin00); + tolua_function(tolua_S,"AddHook",tolua_AllToLua_cPluginManager_AddHook00); + tolua_function(tolua_S,"GetNumPlugins",tolua_AllToLua_cPluginManager_GetNumPlugins00); + tolua_function(tolua_S,"RemovePlugin",tolua_AllToLua_cPluginManager_RemovePlugin00); + tolua_function(tolua_S,"RemoveLuaPlugin",tolua_AllToLua_cPluginManager_RemoveLuaPlugin00); + tolua_function(tolua_S,"GetLuaPlugin",tolua_AllToLua_cPluginManager_GetLuaPlugin00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cPlugin","cPlugin","",tolua_collect_cPlugin); + #else + tolua_cclass(tolua_S,"cPlugin","cPlugin","",NULL); + #endif + tolua_beginmodule(tolua_S,"cPlugin"); + tolua_function(tolua_S,"delete",tolua_AllToLua_cPlugin_delete00); + tolua_function(tolua_S,"OnDisable",tolua_AllToLua_cPlugin_OnDisable00); + tolua_function(tolua_S,"Initialize",tolua_AllToLua_cPlugin_Initialize00); + tolua_function(tolua_S,"Tick",tolua_AllToLua_cPlugin_Tick00); + tolua_function(tolua_S,"OnCollectItem",tolua_AllToLua_cPlugin_OnCollectItem00); + tolua_function(tolua_S,"OnDisconnect",tolua_AllToLua_cPlugin_OnDisconnect00); + tolua_function(tolua_S,"OnBlockPlace",tolua_AllToLua_cPlugin_OnBlockPlace00); + tolua_function(tolua_S,"OnBlockDig",tolua_AllToLua_cPlugin_OnBlockDig00); + tolua_function(tolua_S,"OnChat",tolua_AllToLua_cPlugin_OnChat00); + tolua_function(tolua_S,"OnLogin",tolua_AllToLua_cPlugin_OnLogin00); + tolua_function(tolua_S,"OnPlayerSpawn",tolua_AllToLua_cPlugin_OnPlayerSpawn00); + tolua_function(tolua_S,"OnPlayerJoin",tolua_AllToLua_cPlugin_OnPlayerJoin00); + tolua_function(tolua_S,"OnPlayerMove",tolua_AllToLua_cPlugin_OnPlayerMove00); + tolua_function(tolua_S,"OnTakeDamage",tolua_AllToLua_cPlugin_OnTakeDamage00); + tolua_function(tolua_S,"OnKilled",tolua_AllToLua_cPlugin_OnKilled00); + tolua_function(tolua_S,"OnChunkGenerated",tolua_AllToLua_cPlugin_OnChunkGenerated00); + tolua_function(tolua_S,"OnChunkGenerating",tolua_AllToLua_cPlugin_OnChunkGenerating00); + tolua_function(tolua_S,"OnPreCrafting",tolua_AllToLua_cPlugin_OnPreCrafting00); + tolua_function(tolua_S,"OnCraftingNoRecipe",tolua_AllToLua_cPlugin_OnCraftingNoRecipe00); + tolua_function(tolua_S,"OnPostCrafting",tolua_AllToLua_cPlugin_OnPostCrafting00); + tolua_function(tolua_S,"OnBlockToPickup",tolua_AllToLua_cPlugin_OnBlockToPickup00); + tolua_function(tolua_S,"GetName",tolua_AllToLua_cPlugin_GetName00); + tolua_function(tolua_S,"SetName",tolua_AllToLua_cPlugin_SetName00); + tolua_function(tolua_S,"GetVersion",tolua_AllToLua_cPlugin_GetVersion00); + tolua_function(tolua_S,"SetVersion",tolua_AllToLua_cPlugin_SetVersion00); + tolua_cclass(tolua_S,"CommandStruct","cPlugin::CommandStruct","",NULL); + tolua_beginmodule(tolua_S,"CommandStruct"); + tolua_variable(tolua_S,"Command",tolua_get_cPlugin__CommandStruct_Command,tolua_set_cPlugin__CommandStruct_Command); + tolua_variable(tolua_S,"Description",tolua_get_cPlugin__CommandStruct_Description,tolua_set_cPlugin__CommandStruct_Description); + tolua_variable(tolua_S,"Permission",tolua_get_cPlugin__CommandStruct_Permission,tolua_set_cPlugin__CommandStruct_Permission); + tolua_endmodule(tolua_S); + tolua_function(tolua_S,"AddCommand",tolua_AllToLua_cPlugin_AddCommand00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"Lua__cPlugin","Lua__cPlugin","cPlugin",tolua_collect_Lua__cPlugin); + #else + tolua_cclass(tolua_S,"Lua__cPlugin","Lua__cPlugin","cPlugin",NULL); + #endif + tolua_beginmodule(tolua_S,"Lua__cPlugin"); + tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPlugin_tolua__set_instance00); + tolua_function(tolua_S,"cPlugin__OnDisable",tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisable00); + tolua_function(tolua_S,"cPlugin__Tick",tolua_AllToLua_Lua__cPlugin_cPlugin__Tick00); + tolua_function(tolua_S,"cPlugin__OnCollectItem",tolua_AllToLua_Lua__cPlugin_cPlugin__OnCollectItem00); + tolua_function(tolua_S,"cPlugin__OnDisconnect",tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisconnect00); + tolua_function(tolua_S,"cPlugin__OnBlockPlace",tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockPlace00); + tolua_function(tolua_S,"cPlugin__OnBlockDig",tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockDig00); + tolua_function(tolua_S,"cPlugin__OnChat",tolua_AllToLua_Lua__cPlugin_cPlugin__OnChat00); + tolua_function(tolua_S,"cPlugin__OnLogin",tolua_AllToLua_Lua__cPlugin_cPlugin__OnLogin00); + tolua_function(tolua_S,"cPlugin__OnPlayerSpawn",tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerSpawn00); + tolua_function(tolua_S,"cPlugin__OnPlayerJoin",tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerJoin00); + tolua_function(tolua_S,"cPlugin__OnPlayerMove",tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerMove00); + tolua_function(tolua_S,"cPlugin__OnTakeDamage",tolua_AllToLua_Lua__cPlugin_cPlugin__OnTakeDamage00); + tolua_function(tolua_S,"cPlugin__OnKilled",tolua_AllToLua_Lua__cPlugin_cPlugin__OnKilled00); + tolua_function(tolua_S,"cPlugin__OnChunkGenerated",tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerated00); + tolua_function(tolua_S,"cPlugin__OnChunkGenerating",tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerating00); + tolua_function(tolua_S,"cPlugin__OnPreCrafting",tolua_AllToLua_Lua__cPlugin_cPlugin__OnPreCrafting00); + tolua_function(tolua_S,"cPlugin__OnCraftingNoRecipe",tolua_AllToLua_Lua__cPlugin_cPlugin__OnCraftingNoRecipe00); + tolua_function(tolua_S,"cPlugin__OnPostCrafting",tolua_AllToLua_Lua__cPlugin_cPlugin__OnPostCrafting00); + tolua_function(tolua_S,"cPlugin__OnBlockToPickup",tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockToPickup00); + tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cPlugin_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cPlugin_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cPlugin_new00_local); + tolua_function(tolua_S,"delete",tolua_AllToLua_Lua__cPlugin_delete00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cPlugin_NewLua","cPlugin_NewLua","cPlugin",NULL); + tolua_beginmodule(tolua_S,"cPlugin_NewLua"); + tolua_function(tolua_S,"OnDisable",tolua_AllToLua_cPlugin_NewLua_OnDisable00); + tolua_function(tolua_S,"Initialize",tolua_AllToLua_cPlugin_NewLua_Initialize00); + tolua_function(tolua_S,"Tick",tolua_AllToLua_cPlugin_NewLua_Tick00); + tolua_function(tolua_S,"CreateWebPlugin",tolua_AllToLua_cPlugin_NewLua_CreateWebPlugin00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"Lua__cPlugin_NewLua","Lua__cPlugin_NewLua","cPlugin_NewLua",NULL); + tolua_beginmodule(tolua_S,"Lua__cPlugin_NewLua"); + tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPlugin_NewLua_tolua__set_instance00); + tolua_function(tolua_S,"cPlugin_NewLua__OnDisable",tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__OnDisable00); + tolua_function(tolua_S,"cPlugin_NewLua__Initialize",tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Initialize00); + tolua_function(tolua_S,"cPlugin_NewLua__Tick",tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Tick00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cPlugin_Lua","cPlugin_Lua","",NULL); + tolua_beginmodule(tolua_S,"cPlugin_Lua"); + tolua_function(tolua_S,"GetFileName",tolua_AllToLua_cPlugin_Lua_GetFileName00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cServer","cServer","",NULL); + tolua_beginmodule(tolua_S,"cServer"); + tolua_function(tolua_S,"GetServer",tolua_AllToLua_cServer_GetServer00); + tolua_function(tolua_S,"ServerCommand",tolua_AllToLua_cServer_ServerCommand00); + tolua_function(tolua_S,"SendMessage",tolua_AllToLua_cServer_SendMessage00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cWorld","cWorld","",NULL); + tolua_beginmodule(tolua_S,"cWorld"); + tolua_function(tolua_S,"GetTime",tolua_AllToLua_cWorld_GetTime00); + tolua_function(tolua_S,"GetGameMode",tolua_AllToLua_cWorld_GetGameMode00); + tolua_function(tolua_S,"SetWorldTime",tolua_AllToLua_cWorld_SetWorldTime00); + tolua_function(tolua_S,"GetHeight",tolua_AllToLua_cWorld_GetHeight00); + tolua_function(tolua_S,"UnloadUnusedChunks",tolua_AllToLua_cWorld_UnloadUnusedChunks00); + tolua_function(tolua_S,"GetMaxPlayers",tolua_AllToLua_cWorld_GetMaxPlayers00); + tolua_function(tolua_S,"SetMaxPlayers",tolua_AllToLua_cWorld_SetMaxPlayers00); + tolua_function(tolua_S,"GetNumPlayers",tolua_AllToLua_cWorld_GetNumPlayers00); + tolua_function(tolua_S,"GetPlayer",tolua_AllToLua_cWorld_GetPlayer00); + tolua_function(tolua_S,"UpdateSign",tolua_AllToLua_cWorld_UpdateSign00); + tolua_function(tolua_S,"RegenerateChunk",tolua_AllToLua_cWorld_RegenerateChunk00); + tolua_function(tolua_S,"GenerateChunk",tolua_AllToLua_cWorld_GenerateChunk00); + tolua_function(tolua_S,"SetBlock",tolua_AllToLua_cWorld_SetBlock00); + tolua_function(tolua_S,"FastSetBlock",tolua_AllToLua_cWorld_FastSetBlock00); + tolua_function(tolua_S,"GetBlock",tolua_AllToLua_cWorld_GetBlock00); + tolua_function(tolua_S,"GetBlock",tolua_AllToLua_cWorld_GetBlock01); + tolua_function(tolua_S,"GetBlockMeta",tolua_AllToLua_cWorld_GetBlockMeta00); + tolua_function(tolua_S,"GetBlockMeta",tolua_AllToLua_cWorld_GetBlockMeta01); + tolua_function(tolua_S,"SetBlockMeta",tolua_AllToLua_cWorld_SetBlockMeta00); + tolua_function(tolua_S,"SetBlockMeta",tolua_AllToLua_cWorld_SetBlockMeta01); + tolua_function(tolua_S,"GetBlockSkyLight",tolua_AllToLua_cWorld_GetBlockSkyLight00); + tolua_function(tolua_S,"GetBlockTypeMeta",tolua_AllToLua_cWorld_GetBlockTypeMeta00); + tolua_function(tolua_S,"DigBlock",tolua_AllToLua_cWorld_DigBlock00); + tolua_function(tolua_S,"SendBlockTo",tolua_AllToLua_cWorld_SendBlockTo00); + tolua_function(tolua_S,"GetSpawnX",tolua_AllToLua_cWorld_GetSpawnX00); + tolua_function(tolua_S,"GetSpawnY",tolua_AllToLua_cWorld_GetSpawnY00); + tolua_function(tolua_S,"GetSpawnZ",tolua_AllToLua_cWorld_GetSpawnZ00); + tolua_function(tolua_S,"GetBlockEntity",tolua_AllToLua_cWorld_GetBlockEntity00); + tolua_function(tolua_S,"GrowTree",tolua_AllToLua_cWorld_GrowTree00); + tolua_function(tolua_S,"GrowTreeFromSapling",tolua_AllToLua_cWorld_GrowTreeFromSapling00); + tolua_function(tolua_S,"GrowTreeByBiome",tolua_AllToLua_cWorld_GrowTreeByBiome00); + tolua_function(tolua_S,"GrowPlant",tolua_AllToLua_cWorld_GrowPlant00); + tolua_function(tolua_S,"GrowMelonPumpkin",tolua_AllToLua_cWorld_GrowMelonPumpkin00); + tolua_function(tolua_S,"GetBiomeAt",tolua_AllToLua_cWorld_GetBiomeAt00); + tolua_function(tolua_S,"GetName",tolua_AllToLua_cWorld_GetName00); + tolua_function(tolua_S,"SaveAllChunks",tolua_AllToLua_cWorld_SaveAllChunks00); + tolua_function(tolua_S,"GetNumChunks",tolua_AllToLua_cWorld_GetNumChunks00); + tolua_function(tolua_S,"GetGeneratorQueueLength",tolua_AllToLua_cWorld_GetGeneratorQueueLength00); + tolua_function(tolua_S,"GetLightingQueueLength",tolua_AllToLua_cWorld_GetLightingQueueLength00); + tolua_function(tolua_S,"GetStorageLoadQueueLength",tolua_AllToLua_cWorld_GetStorageLoadQueueLength00); + tolua_function(tolua_S,"GetStorageSaveQueueLength",tolua_AllToLua_cWorld_GetStorageSaveQueueLength00); + tolua_function(tolua_S,"CastThunderbolt",tolua_AllToLua_cWorld_CastThunderbolt00); + tolua_function(tolua_S,"SetWeather",tolua_AllToLua_cWorld_SetWeather00); + tolua_function(tolua_S,"ChangeWeather",tolua_AllToLua_cWorld_ChangeWeather00); + tolua_function(tolua_S,"GetWeather",tolua_AllToLua_cWorld_GetWeather00); + tolua_function(tolua_S,"SetNextBlockTick",tolua_AllToLua_cWorld_SetNextBlockTick00); + tolua_function(tolua_S,"GetMaxSugarcaneHeight",tolua_AllToLua_cWorld_GetMaxSugarcaneHeight00); + tolua_function(tolua_S,"GetMaxCactusHeight",tolua_AllToLua_cWorld_GetMaxCactusHeight00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cInventory","cInventory","",NULL); + tolua_beginmodule(tolua_S,"cInventory"); + tolua_function(tolua_S,"Clear",tolua_AllToLua_cInventory_Clear00); + tolua_function(tolua_S,"AddItem",tolua_AllToLua_cInventory_AddItem00); + tolua_function(tolua_S,"RemoveItem",tolua_AllToLua_cInventory_RemoveItem00); + tolua_function(tolua_S,"GetSlot",tolua_AllToLua_cInventory_GetSlot00); + tolua_function(tolua_S,"GetFromHotBar",tolua_AllToLua_cInventory_GetFromHotBar00); + tolua_function(tolua_S,"GetEquippedItem",tolua_AllToLua_cInventory_GetEquippedItem00); + tolua_function(tolua_S,"SetEquippedSlot",tolua_AllToLua_cInventory_SetEquippedSlot00); + tolua_function(tolua_S,"GetEquippedSlot",tolua_AllToLua_cInventory_GetEquippedSlot00); + tolua_function(tolua_S,"SendSlot",tolua_AllToLua_cInventory_SendSlot00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cItem","cItem","",tolua_collect_cItem); + #else + tolua_cclass(tolua_S,"cItem","cItem","",NULL); + #endif + tolua_beginmodule(tolua_S,"cItem"); + tolua_function(tolua_S,"new",tolua_AllToLua_cItem_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cItem_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cItem_new00_local); + tolua_function(tolua_S,"Empty",tolua_AllToLua_cItem_Empty00); + tolua_function(tolua_S,"Clear",tolua_AllToLua_cItem_Clear00); + tolua_function(tolua_S,"IsEmpty",tolua_AllToLua_cItem_IsEmpty00); + tolua_function(tolua_S,"Equals",tolua_AllToLua_cItem_Equals00); + tolua_function(tolua_S,"GetMaxDuration",tolua_AllToLua_cItem_GetMaxDuration00); + tolua_function(tolua_S,"DamageItem",tolua_AllToLua_cItem_DamageItem00); + tolua_function(tolua_S,"HasDuration",tolua_AllToLua_cItem_HasDuration00); + tolua_function(tolua_S,"GetJson",tolua_AllToLua_cItem_GetJson00); + tolua_function(tolua_S,"FromJson",tolua_AllToLua_cItem_FromJson00); + tolua_function(tolua_S,"IsEnchantable",tolua_AllToLua_cItem_IsEnchantable00); + tolua_variable(tolua_S,"m_ItemID",tolua_get_cItem_m_ItemID,tolua_set_cItem_m_ItemID); + tolua_variable(tolua_S,"m_ItemCount",tolua_get_cItem_m_ItemCount,tolua_set_cItem_m_ItemCount); + tolua_variable(tolua_S,"m_ItemHealth",tolua_get_cItem_m_ItemHealth,tolua_set_cItem_m_ItemHealth); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"HTTPFormData","HTTPFormData","",NULL); + tolua_beginmodule(tolua_S,"HTTPFormData"); + tolua_variable(tolua_S,"Name",tolua_get_HTTPFormData_Name,tolua_set_HTTPFormData_Name); + tolua_variable(tolua_S,"Value",tolua_get_HTTPFormData_Value,tolua_set_HTTPFormData_Value); + tolua_variable(tolua_S,"Type",tolua_get_HTTPFormData_Type,tolua_set_HTTPFormData_Type); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"HTTPRequest","HTTPRequest","",NULL); + tolua_beginmodule(tolua_S,"HTTPRequest"); + tolua_variable(tolua_S,"Method",tolua_get_HTTPRequest_Method,tolua_set_HTTPRequest_Method); + tolua_variable(tolua_S,"Path",tolua_get_HTTPRequest_Path,tolua_set_HTTPRequest_Path); + tolua_variable(tolua_S,"Username",tolua_get_HTTPRequest_Username,tolua_set_HTTPRequest_Username); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cWebPlugin","cWebPlugin","",tolua_collect_cWebPlugin); + #else + tolua_cclass(tolua_S,"cWebPlugin","cWebPlugin","",NULL); + #endif + tolua_beginmodule(tolua_S,"cWebPlugin"); + tolua_function(tolua_S,"delete",tolua_AllToLua_cWebPlugin_delete00); + tolua_function(tolua_S,"SetName",tolua_AllToLua_cWebPlugin_SetName00); + tolua_function(tolua_S,"GetName",tolua_AllToLua_cWebPlugin_GetName00); + tolua_function(tolua_S,"HandleRequest",tolua_AllToLua_cWebPlugin_HandleRequest00); + tolua_function(tolua_S,"Initialize",tolua_AllToLua_cWebPlugin_Initialize00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"Lua__cWebPlugin","Lua__cWebPlugin","cWebPlugin",tolua_collect_Lua__cWebPlugin); + #else + tolua_cclass(tolua_S,"Lua__cWebPlugin","Lua__cWebPlugin","cWebPlugin",NULL); + #endif + tolua_beginmodule(tolua_S,"Lua__cWebPlugin"); + tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cWebPlugin_tolua__set_instance00); + tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cWebPlugin_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cWebPlugin_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cWebPlugin_new00_local); + tolua_function(tolua_S,"delete",tolua_AllToLua_Lua__cWebPlugin_delete00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cWebPlugin_Lua","cWebPlugin_Lua","cWebPlugin",NULL); + tolua_beginmodule(tolua_S,"cWebPlugin_Lua"); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cPickup","cPickup","cEntity",tolua_collect_cPickup); + #else + tolua_cclass(tolua_S,"cPickup","cPickup","cEntity",NULL); + #endif + tolua_beginmodule(tolua_S,"cPickup"); + tolua_function(tolua_S,"new",tolua_AllToLua_cPickup_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cPickup_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cPickup_new00_local); + tolua_function(tolua_S,"new",tolua_AllToLua_cPickup_new01); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cPickup_new01_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cPickup_new01_local); + tolua_function(tolua_S,"delete",tolua_AllToLua_cPickup_delete00); + tolua_function(tolua_S,"GetItem",tolua_AllToLua_cPickup_GetItem00); + tolua_function(tolua_S,"CollectedBy",tolua_AllToLua_cPickup_CollectedBy00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"Lua__cPickup","Lua__cPickup","cPickup",tolua_collect_Lua__cPickup); + #else + tolua_cclass(tolua_S,"Lua__cPickup","Lua__cPickup","cPickup",NULL); + #endif + tolua_beginmodule(tolua_S,"Lua__cPickup"); + tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPickup_tolua__set_instance00); + tolua_function(tolua_S,"cPickup__CollectedBy",tolua_AllToLua_Lua__cPickup_cPickup__CollectedBy00); + tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cPickup_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cPickup_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cPickup_new00_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cPickup_new01); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cPickup_new01_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cPickup_new01_local); + tolua_function(tolua_S,"delete",tolua_AllToLua_Lua__cPickup_delete00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cRoot","cRoot","",NULL); + tolua_beginmodule(tolua_S,"cRoot"); + tolua_function(tolua_S,"Get",tolua_AllToLua_cRoot_Get00); + tolua_function(tolua_S,"GetServer",tolua_AllToLua_cRoot_GetServer00); + tolua_function(tolua_S,"GetDefaultWorld",tolua_AllToLua_cRoot_GetDefaultWorld00); + tolua_function(tolua_S,"GetWorld",tolua_AllToLua_cRoot_GetWorld00); + tolua_function(tolua_S,"GetGroupManager",tolua_AllToLua_cRoot_GetGroupManager00); + tolua_function(tolua_S,"GetCraftingRecipes",tolua_AllToLua_cRoot_GetCraftingRecipes00); + tolua_function(tolua_S,"GetFurnaceRecipe",tolua_AllToLua_cRoot_GetFurnaceRecipe00); + tolua_function(tolua_S,"GetWebAdmin",tolua_AllToLua_cRoot_GetWebAdmin00); + tolua_function(tolua_S,"GetPluginManager",tolua_AllToLua_cRoot_GetPluginManager00); + tolua_function(tolua_S,"ServerCommand",tolua_AllToLua_cRoot_ServerCommand00); + tolua_function(tolua_S,"GetTotalChunkCount",tolua_AllToLua_cRoot_GetTotalChunkCount00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cTCPLink","cTCPLink","",tolua_collect_cTCPLink); + #else + tolua_cclass(tolua_S,"cTCPLink","cTCPLink","",NULL); + #endif + tolua_beginmodule(tolua_S,"cTCPLink"); + tolua_function(tolua_S,"delete",tolua_AllToLua_cTCPLink_delete00); + tolua_function(tolua_S,"Connect",tolua_AllToLua_cTCPLink_Connect00); + tolua_function(tolua_S,"Send",tolua_AllToLua_cTCPLink_Send00); + tolua_function(tolua_S,"SendMessage",tolua_AllToLua_cTCPLink_SendMessage00); + tolua_function(tolua_S,"CloseSocket",tolua_AllToLua_cTCPLink_CloseSocket00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"Lua__cTCPLink","Lua__cTCPLink","cTCPLink",tolua_collect_Lua__cTCPLink); + #else + tolua_cclass(tolua_S,"Lua__cTCPLink","Lua__cTCPLink","cTCPLink",NULL); + #endif + tolua_beginmodule(tolua_S,"Lua__cTCPLink"); + tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cTCPLink_tolua__set_instance00); + tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cTCPLink_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cTCPLink_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cTCPLink_new00_local); + tolua_function(tolua_S,"delete",tolua_AllToLua_Lua__cTCPLink_delete00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"Vector3f","Vector3f","",tolua_collect_Vector3f); + #else + tolua_cclass(tolua_S,"Vector3f","Vector3f","",NULL); + #endif + tolua_beginmodule(tolua_S,"Vector3f"); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new00_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new01); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new01_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new01_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new02); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new02_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new02_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new03); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new03_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new03_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new04); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new04_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new04_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new05); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new05_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new05_local); + tolua_function(tolua_S,"Set",tolua_AllToLua_Vector3f_Set00); + tolua_function(tolua_S,"Normalize",tolua_AllToLua_Vector3f_Normalize00); + tolua_function(tolua_S,"NormalizeCopy",tolua_AllToLua_Vector3f_NormalizeCopy00); + tolua_function(tolua_S,"NormalizeCopy",tolua_AllToLua_Vector3f_NormalizeCopy01); + tolua_function(tolua_S,"Length",tolua_AllToLua_Vector3f_Length00); + tolua_function(tolua_S,"SqrLength",tolua_AllToLua_Vector3f_SqrLength00); + tolua_function(tolua_S,"Dot",tolua_AllToLua_Vector3f_Dot00); + tolua_function(tolua_S,"Cross",tolua_AllToLua_Vector3f_Cross00); + tolua_function(tolua_S,"Equals",tolua_AllToLua_Vector3f_Equals00); + tolua_function(tolua_S,".add",tolua_AllToLua_Vector3f__add00); + tolua_function(tolua_S,".add",tolua_AllToLua_Vector3f__add01); + tolua_function(tolua_S,".sub",tolua_AllToLua_Vector3f__sub00); + tolua_function(tolua_S,".sub",tolua_AllToLua_Vector3f__sub01); + tolua_function(tolua_S,".mul",tolua_AllToLua_Vector3f__mul00); + tolua_function(tolua_S,".mul",tolua_AllToLua_Vector3f__mul01); + tolua_variable(tolua_S,"x",tolua_get_Vector3f_x,tolua_set_Vector3f_x); + tolua_variable(tolua_S,"y",tolua_get_Vector3f_y,tolua_set_Vector3f_y); + tolua_variable(tolua_S,"z",tolua_get_Vector3f_z,tolua_set_Vector3f_z); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"Vector3d","Vector3d","",tolua_collect_Vector3d); + #else + tolua_cclass(tolua_S,"Vector3d","Vector3d","",NULL); + #endif + tolua_beginmodule(tolua_S,"Vector3d"); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3d_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3d_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3d_new00_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3d_new01); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3d_new01_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3d_new01_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3d_new02); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3d_new02_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3d_new02_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3d_new03); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3d_new03_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3d_new03_local); + tolua_function(tolua_S,"Set",tolua_AllToLua_Vector3d_Set00); + tolua_function(tolua_S,"Normalize",tolua_AllToLua_Vector3d_Normalize00); + tolua_function(tolua_S,"NormalizeCopy",tolua_AllToLua_Vector3d_NormalizeCopy00); + tolua_function(tolua_S,"NormalizeCopy",tolua_AllToLua_Vector3d_NormalizeCopy01); + tolua_function(tolua_S,"Length",tolua_AllToLua_Vector3d_Length00); + tolua_function(tolua_S,"SqrLength",tolua_AllToLua_Vector3d_SqrLength00); + tolua_function(tolua_S,"Dot",tolua_AllToLua_Vector3d_Dot00); + tolua_function(tolua_S,"Cross",tolua_AllToLua_Vector3d_Cross00); + tolua_function(tolua_S,"Equals",tolua_AllToLua_Vector3d_Equals00); + tolua_function(tolua_S,".add",tolua_AllToLua_Vector3d__add00); + tolua_function(tolua_S,".add",tolua_AllToLua_Vector3d__add01); + tolua_function(tolua_S,".sub",tolua_AllToLua_Vector3d__sub00); + tolua_function(tolua_S,".sub",tolua_AllToLua_Vector3d__sub01); + tolua_function(tolua_S,".mul",tolua_AllToLua_Vector3d__mul00); + tolua_function(tolua_S,".mul",tolua_AllToLua_Vector3d__mul01); + tolua_variable(tolua_S,"x",tolua_get_Vector3d_x,tolua_set_Vector3d_x); + tolua_variable(tolua_S,"y",tolua_get_Vector3d_y,tolua_set_Vector3d_y); + tolua_variable(tolua_S,"z",tolua_get_Vector3d_z,tolua_set_Vector3d_z); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"Vector3i","Vector3i","",tolua_collect_Vector3i); + #else + tolua_cclass(tolua_S,"Vector3i","Vector3i","",NULL); + #endif + tolua_beginmodule(tolua_S,"Vector3i"); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3i_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3i_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3i_new00_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3i_new01); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3i_new01_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3i_new01_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3i_new02); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3i_new02_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3i_new02_local); + tolua_function(tolua_S,"Set",tolua_AllToLua_Vector3i_Set00); + tolua_function(tolua_S,"Length",tolua_AllToLua_Vector3i_Length00); + tolua_function(tolua_S,"SqrLength",tolua_AllToLua_Vector3i_SqrLength00); + tolua_function(tolua_S,"Equals",tolua_AllToLua_Vector3i_Equals00); + tolua_function(tolua_S,"Equals",tolua_AllToLua_Vector3i_Equals01); + tolua_variable(tolua_S,"x",tolua_get_Vector3i_x,tolua_set_Vector3i_x); + tolua_variable(tolua_S,"y",tolua_get_Vector3i_y,tolua_set_Vector3i_y); + tolua_variable(tolua_S,"z",tolua_get_Vector3i_z,tolua_set_Vector3i_z); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cCuboid","cCuboid","",tolua_collect_cCuboid); + #else + tolua_cclass(tolua_S,"cCuboid","cCuboid","",NULL); + #endif + tolua_beginmodule(tolua_S,"cCuboid"); + tolua_function(tolua_S,"new",tolua_AllToLua_cCuboid_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cCuboid_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cCuboid_new00_local); + tolua_function(tolua_S,"new",tolua_AllToLua_cCuboid_new01); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cCuboid_new01_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cCuboid_new01_local); + tolua_function(tolua_S,"new",tolua_AllToLua_cCuboid_new02); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cCuboid_new02_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cCuboid_new02_local); + tolua_variable(tolua_S,"p1",tolua_get_cCuboid_p1,tolua_set_cCuboid_p1); + tolua_variable(tolua_S,"p2",tolua_get_cCuboid_p2,tolua_set_cCuboid_p2); + tolua_function(tolua_S,"Sort",tolua_AllToLua_cCuboid_Sort00); + tolua_function(tolua_S,"IsInside",tolua_AllToLua_cCuboid_IsInside00); + tolua_function(tolua_S,"IsInside",tolua_AllToLua_cCuboid_IsInside01); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cMCLogger","cMCLogger","",tolua_collect_cMCLogger); + #else + tolua_cclass(tolua_S,"cMCLogger","cMCLogger","",NULL); + #endif + tolua_beginmodule(tolua_S,"cMCLogger"); + tolua_function(tolua_S,"new",tolua_AllToLua_cMCLogger_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cMCLogger_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cMCLogger_new00_local); + tolua_function(tolua_S,"delete",tolua_AllToLua_cMCLogger_delete00); + tolua_function(tolua_S,"LogSimple",tolua_AllToLua_cMCLogger_LogSimple00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cTracer","cTracer","",tolua_collect_cTracer); + #else + tolua_cclass(tolua_S,"cTracer","cTracer","",NULL); + #endif + tolua_beginmodule(tolua_S,"cTracer"); + tolua_function(tolua_S,"new",tolua_AllToLua_cTracer_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cTracer_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cTracer_new00_local); + tolua_function(tolua_S,"delete",tolua_AllToLua_cTracer_delete00); + tolua_function(tolua_S,"Trace",tolua_AllToLua_cTracer_Trace00); + tolua_function(tolua_S,"SetValues",tolua_AllToLua_cTracer_SetValues00); + tolua_variable(tolua_S,"BlockHitPosition",tolua_get_cTracer_BlockHitPosition,tolua_set_cTracer_BlockHitPosition); + tolua_variable(tolua_S,"HitNormal",tolua_get_cTracer_HitNormal,tolua_set_cTracer_HitNormal); + tolua_variable(tolua_S,"RealHit",tolua_get_cTracer_RealHit,tolua_set_cTracer_RealHit); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cGroup","cGroup","",NULL); + tolua_beginmodule(tolua_S,"cGroup"); + tolua_function(tolua_S,"SetName",tolua_AllToLua_cGroup_SetName00); + tolua_function(tolua_S,"GetName",tolua_AllToLua_cGroup_GetName00); + tolua_function(tolua_S,"SetColor",tolua_AllToLua_cGroup_SetColor00); + tolua_function(tolua_S,"AddCommand",tolua_AllToLua_cGroup_AddCommand00); + tolua_function(tolua_S,"AddPermission",tolua_AllToLua_cGroup_AddPermission00); + tolua_function(tolua_S,"InheritFrom",tolua_AllToLua_cGroup_InheritFrom00); + tolua_function(tolua_S,"HasCommand",tolua_AllToLua_cGroup_HasCommand00); + tolua_function(tolua_S,"GetColor",tolua_AllToLua_cGroup_GetColor00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cPacket_Login","cPacket_Login","cPacket",NULL); + tolua_beginmodule(tolua_S,"cPacket_Login"); + tolua_variable(tolua_S,"m_ProtocolVersion",tolua_get_cPacket_Login_m_ProtocolVersion,tolua_set_cPacket_Login_m_ProtocolVersion); + tolua_variable(tolua_S,"m_Username",tolua_get_cPacket_Login_m_Username,tolua_set_cPacket_Login_m_Username); + tolua_variable(tolua_S,"m_LevelType",tolua_get_cPacket_Login_m_LevelType,tolua_set_cPacket_Login_m_LevelType); + tolua_variable(tolua_S,"m_ServerMode",tolua_get_cPacket_Login_m_ServerMode,tolua_set_cPacket_Login_m_ServerMode); + tolua_variable(tolua_S,"m_Difficulty",tolua_get_cPacket_Login_m_Difficulty,tolua_set_cPacket_Login_m_Difficulty); + tolua_variable(tolua_S,"m_WorldHeight",tolua_get_cPacket_Login_unsigned_m_WorldHeight,tolua_set_cPacket_Login_unsigned_m_WorldHeight); + tolua_variable(tolua_S,"m_MaxPlayers",tolua_get_cPacket_Login_unsigned_m_MaxPlayers,tolua_set_cPacket_Login_unsigned_m_MaxPlayers); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cPacket_BlockDig","cPacket_BlockDig","cPacket",tolua_collect_cPacket_BlockDig); + #else + tolua_cclass(tolua_S,"cPacket_BlockDig","cPacket_BlockDig","cPacket",NULL); + #endif + tolua_beginmodule(tolua_S,"cPacket_BlockDig"); + tolua_function(tolua_S,"new",tolua_AllToLua_cPacket_BlockDig_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cPacket_BlockDig_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cPacket_BlockDig_new00_local); + tolua_function(tolua_S,"Clone",tolua_AllToLua_cPacket_BlockDig_Clone00); + tolua_variable(tolua_S,"m_Status",tolua_get_cPacket_BlockDig_m_Status,tolua_set_cPacket_BlockDig_m_Status); + tolua_variable(tolua_S,"m_PosX",tolua_get_cPacket_BlockDig_m_PosX,tolua_set_cPacket_BlockDig_m_PosX); + tolua_variable(tolua_S,"m_PosY",tolua_get_cPacket_BlockDig_m_PosY,tolua_set_cPacket_BlockDig_m_PosY); + tolua_variable(tolua_S,"m_PosZ",tolua_get_cPacket_BlockDig_m_PosZ,tolua_set_cPacket_BlockDig_m_PosZ); + tolua_variable(tolua_S,"m_Direction",tolua_get_cPacket_BlockDig_m_Direction,tolua_set_cPacket_BlockDig_m_Direction); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"Lua__cPacket_BlockDig","Lua__cPacket_BlockDig","cPacket_BlockDig",tolua_collect_Lua__cPacket_BlockDig); + #else + tolua_cclass(tolua_S,"Lua__cPacket_BlockDig","Lua__cPacket_BlockDig","cPacket_BlockDig",NULL); + #endif + tolua_beginmodule(tolua_S,"Lua__cPacket_BlockDig"); + tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPacket_BlockDig_tolua__set_instance00); + tolua_function(tolua_S,"cPacket_BlockDig__Clone",tolua_AllToLua_Lua__cPacket_BlockDig_cPacket_BlockDig__Clone00); + tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cPacket_BlockDig_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cPacket_BlockDig_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cPacket_BlockDig_new00_local); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cPacket_BlockPlace","cPacket_BlockPlace","cPacket",NULL); + tolua_beginmodule(tolua_S,"cPacket_BlockPlace"); + tolua_variable(tolua_S,"m_PosX",tolua_get_cPacket_BlockPlace_m_PosX,tolua_set_cPacket_BlockPlace_m_PosX); + tolua_variable(tolua_S,"m_PosY",tolua_get_cPacket_BlockPlace_unsigned_m_PosY,tolua_set_cPacket_BlockPlace_unsigned_m_PosY); + tolua_variable(tolua_S,"m_PosZ",tolua_get_cPacket_BlockPlace_m_PosZ,tolua_set_cPacket_BlockPlace_m_PosZ); + tolua_variable(tolua_S,"m_Direction",tolua_get_cPacket_BlockPlace_m_Direction,tolua_set_cPacket_BlockPlace_m_Direction); + tolua_variable(tolua_S,"m_ItemType",tolua_get_cPacket_BlockPlace_m_ItemType,tolua_set_cPacket_BlockPlace_m_ItemType); + tolua_variable(tolua_S,"m_Count",tolua_get_cPacket_BlockPlace_m_Count,tolua_set_cPacket_BlockPlace_m_Count); + tolua_variable(tolua_S,"m_Uses",tolua_get_cPacket_BlockPlace_m_Uses,tolua_set_cPacket_BlockPlace_m_Uses); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cLuaChunk","cLuaChunk","",NULL); + tolua_beginmodule(tolua_S,"cLuaChunk"); + tolua_function(tolua_S,"FillBlocks",tolua_AllToLua_cLuaChunk_FillBlocks00); + tolua_function(tolua_S,"SetBlock",tolua_AllToLua_cLuaChunk_SetBlock00); + tolua_function(tolua_S,"GetBlock",tolua_AllToLua_cLuaChunk_GetBlock00); + tolua_function(tolua_S,"GetBlockMeta",tolua_AllToLua_cLuaChunk_GetBlockMeta00); + tolua_function(tolua_S,"SetBiome",tolua_AllToLua_cLuaChunk_SetBiome00); + tolua_function(tolua_S,"GetBiome",tolua_AllToLua_cLuaChunk_GetBiome00); + tolua_function(tolua_S,"SetHeight",tolua_AllToLua_cLuaChunk_SetHeight00); + tolua_function(tolua_S,"GetHeight",tolua_AllToLua_cLuaChunk_GetHeight00); + tolua_function(tolua_S,"SetUseDefaultBiomes",tolua_AllToLua_cLuaChunk_SetUseDefaultBiomes00); + tolua_function(tolua_S,"IsUsingDefaultBiomes",tolua_AllToLua_cLuaChunk_IsUsingDefaultBiomes00); + tolua_function(tolua_S,"SetUseDefaultComposition",tolua_AllToLua_cLuaChunk_SetUseDefaultComposition00); + tolua_function(tolua_S,"IsUsingDefaultComposition",tolua_AllToLua_cLuaChunk_IsUsingDefaultComposition00); + tolua_function(tolua_S,"SetUseDefaultStructures",tolua_AllToLua_cLuaChunk_SetUseDefaultStructures00); + tolua_function(tolua_S,"IsUsingDefaultStructures",tolua_AllToLua_cLuaChunk_IsUsingDefaultStructures00); + tolua_function(tolua_S,"SetUseDefaultFinish",tolua_AllToLua_cLuaChunk_SetUseDefaultFinish00); + tolua_function(tolua_S,"IsUsingDefaultFinish",tolua_AllToLua_cLuaChunk_IsUsingDefaultFinish00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cCraftingGrid","cCraftingGrid","",tolua_collect_cCraftingGrid); + #else + tolua_cclass(tolua_S,"cCraftingGrid","cCraftingGrid","",NULL); + #endif + tolua_beginmodule(tolua_S,"cCraftingGrid"); + tolua_function(tolua_S,"new",tolua_AllToLua_cCraftingGrid_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cCraftingGrid_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cCraftingGrid_new00_local); + tolua_function(tolua_S,"GetWidth",tolua_AllToLua_cCraftingGrid_GetWidth00); + tolua_function(tolua_S,"GetHeight",tolua_AllToLua_cCraftingGrid_GetHeight00); + tolua_function(tolua_S,"GetItem",tolua_AllToLua_cCraftingGrid_GetItem00); + tolua_function(tolua_S,"SetItem",tolua_AllToLua_cCraftingGrid_SetItem00); + tolua_function(tolua_S,"SetItem",tolua_AllToLua_cCraftingGrid_SetItem01); + tolua_function(tolua_S,"Clear",tolua_AllToLua_cCraftingGrid_Clear00); + tolua_function(tolua_S,"ConsumeGrid",tolua_AllToLua_cCraftingGrid_ConsumeGrid00); + tolua_function(tolua_S,"Dump",tolua_AllToLua_cCraftingGrid_Dump00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cCraftingRecipe","cCraftingRecipe","",NULL); + tolua_beginmodule(tolua_S,"cCraftingRecipe"); + tolua_function(tolua_S,"Clear",tolua_AllToLua_cCraftingRecipe_Clear00); + tolua_function(tolua_S,"GetIngredientsWidth",tolua_AllToLua_cCraftingRecipe_GetIngredientsWidth00); + tolua_function(tolua_S,"GetIngredientsHeight",tolua_AllToLua_cCraftingRecipe_GetIngredientsHeight00); + tolua_function(tolua_S,"GetIngredient",tolua_AllToLua_cCraftingRecipe_GetIngredient00); + tolua_function(tolua_S,"GetResult",tolua_AllToLua_cCraftingRecipe_GetResult00); + tolua_function(tolua_S,"SetResult",tolua_AllToLua_cCraftingRecipe_SetResult00); + tolua_function(tolua_S,"SetResult",tolua_AllToLua_cCraftingRecipe_SetResult01); + tolua_function(tolua_S,"SetIngredient",tolua_AllToLua_cCraftingRecipe_SetIngredient00); + tolua_function(tolua_S,"SetIngredient",tolua_AllToLua_cCraftingRecipe_SetIngredient01); + tolua_function(tolua_S,"ConsumeIngredients",tolua_AllToLua_cCraftingRecipe_ConsumeIngredients00); + tolua_function(tolua_S,"Dump",tolua_AllToLua_cCraftingRecipe_Dump00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cLuaItems","cLuaItems","",NULL); + tolua_beginmodule(tolua_S,"cLuaItems"); + tolua_function(tolua_S,"Get",tolua_AllToLua_cLuaItems_Get00); + tolua_function(tolua_S,"Set",tolua_AllToLua_cLuaItems_Set00); + tolua_function(tolua_S,"Add",tolua_AllToLua_cLuaItems_Add00); + tolua_function(tolua_S,"Delete",tolua_AllToLua_cLuaItems_Delete00); + tolua_function(tolua_S,"Clear",tolua_AllToLua_cLuaItems_Clear00); + tolua_function(tolua_S,"Size",tolua_AllToLua_cLuaItems_Size00); + tolua_function(tolua_S,"Add",tolua_AllToLua_cLuaItems_Add01); + tolua_function(tolua_S,"Set",tolua_AllToLua_cLuaItems_Set01); + tolua_endmodule(tolua_S); + tolua_endmodule(tolua_S); + return 1; +} + + +#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501 + TOLUA_API int luaopen_AllToLua (lua_State* tolua_S) { + return tolua_AllToLua_open(tolua_S); +}; +#endif + diff --git a/source/Bindings.h b/source/Bindings.h index 8bfe98708..ab12fc8fa 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,8 +1,8 @@ -/* -** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on Thu Jun 14 14:20:17 2012. -*/ - -/* Exported function */ -TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S); - +/* +** Lua binding: AllToLua +** Generated automatically by tolua++-1.0.92 on Thu Jun 14 14:20:17 2012. +*/ + +/* Exported function */ +TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S); + diff --git a/source/BioGen.cpp b/source/BioGen.cpp index e897e229d..8603a7452 100644 --- a/source/BioGen.cpp +++ b/source/BioGen.cpp @@ -1,293 +1,293 @@ - -// BioGen.cpp - -// Implements the various biome generators - -#include "Globals.h" -#include "BioGen.h" - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cBioGenConstant: - -void cBioGenConstant::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) -{ - for (int i = 0; i < ARRAYCOUNT(a_BiomeMap); i++) - { - a_BiomeMap[i] = m_Biome; - } -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cBioGenCache: - -cBioGenCache::cBioGenCache(cBiomeGen * a_BioGenToCache, int a_CacheSize) : - m_BioGenToCache(a_BioGenToCache), - m_CacheSize(a_CacheSize), - m_CacheOrder(new int[a_CacheSize]), - m_CacheData(new sCacheData[a_CacheSize]), - m_NumHits(0), - m_NumMisses(0), - m_TotalChain(0) -{ - for (int i = 0; i < m_CacheSize; i++) - { - m_CacheOrder[i] = i; - m_CacheData[i].m_ChunkX = 0x7fffffff; - m_CacheData[i].m_ChunkZ = 0x7fffffff; - } -} - - - - - -cBioGenCache::~cBioGenCache() -{ - delete m_CacheData; - delete m_CacheOrder; - delete m_BioGenToCache; -} - - - - - -void cBioGenCache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) -{ - if (((m_NumHits + m_NumMisses) % 1024) == 10) - { - LOGD("BioGenCache: %d hits, %d misses, saved %.2f %%", m_NumHits, m_NumMisses, 100.0 * m_NumHits / (m_NumHits + m_NumMisses)); - LOGD("BioGenCache: Avg cache chain length: %.2f", (float)m_TotalChain / m_NumHits); - } - - for (int i = 0; i < m_CacheSize; i++) - { - if ( - (m_CacheData[m_CacheOrder[i]].m_ChunkX != a_ChunkX) || - (m_CacheData[m_CacheOrder[i]].m_ChunkZ != a_ChunkZ) - ) - { - continue; - } - // Found it in the cache - int Idx = m_CacheOrder[i]; - - // Move to front: - for (int j = i; j > 0; j--) - { - m_CacheOrder[j] = m_CacheOrder[j - 1]; - } - m_CacheOrder[0] = Idx; - - // Use the cached data: - memcpy(a_BiomeMap, m_CacheData[Idx].m_BiomeMap, sizeof(a_BiomeMap)); - - m_NumHits++; - m_TotalChain += i; - return; - } // for i - cache - - // Not in the cache: - m_NumMisses++; - m_BioGenToCache->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap); - - // Insert it as the first item in the MRU order: - int Idx = m_CacheOrder[m_CacheSize - 1]; - for (int i = m_CacheSize - 1; i > 0; i--) - { - m_CacheOrder[i] = m_CacheOrder[i - 1]; - } // for i - m_CacheOrder[] - m_CacheOrder[0] = Idx; - memcpy(m_CacheData[Idx].m_BiomeMap, a_BiomeMap, sizeof(a_BiomeMap)); - m_CacheData[Idx].m_ChunkX = a_ChunkX; - m_CacheData[Idx].m_ChunkZ = a_ChunkZ; -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cBiomeGenList: - -void cBiomeGenList::InitializeBiomes(const AString & a_Biomes) -{ - AStringVector Split = StringSplit(a_Biomes, ","); - - // Convert each string in the list into biome: - for (AStringVector::const_iterator itr = Split.begin(); itr != Split.end(); ++itr) - { - EMCSBiome Biome = StringToBiome(*itr); - if (Biome != -1) - { - m_Biomes.push_back(Biome); - } - } // for itr - Split[] - if (!m_Biomes.empty()) - { - m_BiomesCount = (int)m_Biomes.size(); - return; - } - - // There were no biomes, add default biomes: - static EMCSBiome Biomes[] = - { - biOcean, - biPlains, - biDesert, - biExtremeHills, - biForest, - biTaiga, - biSwampland, - biRiver, - biFrozenOcean, - biFrozenRiver, - biIcePlains, - biIceMountains, - biMushroomIsland, - biMushroomShore, - biBeach, - biDesertHills, - biForestHills, - biTaigaHills, - biExtremeHillsEdge, - biJungle, - biJungleHills, - } ; - m_Biomes.reserve(ARRAYCOUNT(Biomes)); - for (int i = 0; i < ARRAYCOUNT(Biomes); i++) - { - m_Biomes.push_back(Biomes[i]); - } - m_BiomesCount = (int)m_Biomes.size(); -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cBioGenCheckerboard: - -void cBioGenCheckerboard::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) -{ - for (int z = 0; z < cChunkDef::Width; z++) - { - int Base = cChunkDef::Width * a_ChunkZ + z; - for (int x = 0; x < cChunkDef::Width; x++) - { - int Add = cChunkDef::Width * a_ChunkX + x; - a_BiomeMap[x + cChunkDef::Width * z] = m_Biomes[(Base / m_BiomeSize + Add / m_BiomeSize) % m_BiomesCount]; - } - } -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cBioGenVoronoi : - -void cBioGenVoronoi::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) -{ - int BaseZ = cChunkDef::Width * a_ChunkZ; - int BaseX = cChunkDef::Width * a_ChunkX; - for (int z = 0; z < cChunkDef::Width; z++) - { - int AbsoluteZ = BaseZ + z; - for (int x = 0; x < cChunkDef::Width; x++) - { - cChunkDef::SetBiome(a_BiomeMap, x, z, VoronoiBiome(BaseX + x, AbsoluteZ)); - } // for x - } // for z -} - - - - - -EMCSBiome cBioGenVoronoi::VoronoiBiome(int a_BlockX, int a_BlockZ) -{ - int CellX = a_BlockX / m_CellSize; - int CellZ = a_BlockZ / m_CellSize; - - // Note that Noise values need to be divided by 8 to gain a uniform modulo-2^n distribution - - // Get 5x5 neighboring cell seeds, compare distance to each. Return the biome in the minumim-distance cell - double MinDist = m_CellSize * m_CellSize; // There has to be a cell closer than this - EMCSBiome res = biPlains; // Will be overriden - for (int x = CellX - 2; x <= CellX + 2; x++) - { - int BaseX = x * m_CellSize; - for (int z = CellZ - 2; z < CellZ + 2; z++) - { - int OffsetX = (m_Noise.IntNoise3DInt(x, 16 * x + 32 * z, z) / 8) % m_CellSize; - int OffsetZ = (m_Noise.IntNoise3DInt(x, 32 * x - 16 * z, z) / 8) % m_CellSize; - int SeedX = BaseX + OffsetX; - int SeedZ = z * m_CellSize + OffsetZ; - - double Dist = sqrt((double)((SeedX - a_BlockX) * (SeedX - a_BlockX) + (SeedZ - a_BlockZ) * (SeedZ - a_BlockZ))); - if (Dist < MinDist) - { - MinDist = Dist; - res = m_Biomes[(m_Noise.IntNoise3DInt(x, x - z + 1000, z) / 8) % m_BiomesCount]; - } - } // for z - } // for x - - return res; -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cBioGenDistortedVoronoi: - -void cBioGenDistortedVoronoi::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) -{ - int BaseZ = cChunkDef::Width * a_ChunkZ; - int BaseX = cChunkDef::Width * a_ChunkX; - for (int z = 0; z < cChunkDef::Width; z++) - { - int AbsoluteZ = BaseZ + z; - for (int x = 0; x < cChunkDef::Width; x++) - { - int DistX, DistZ; - Distort(BaseX + x, AbsoluteZ, DistX, DistZ); - cChunkDef::SetBiome(a_BiomeMap, x, z, VoronoiBiome(DistX, DistZ)); - } // for x - } // for z -} - - - - - -void cBioGenDistortedVoronoi::Distort(int a_BlockX, int a_BlockZ, int & a_DistortedX, int & a_DistortedZ) -{ - double NoiseX = m_Noise.CubicNoise3D((float)a_BlockX / m_CellSize, (float)a_BlockZ / m_CellSize, 1000); - NoiseX += 0.5 * m_Noise.CubicNoise3D(2 * (float)a_BlockX / m_CellSize, 2 * (float)a_BlockZ / m_CellSize, 2000); - NoiseX += 0.08 * m_Noise.CubicNoise3D(16 * (float)a_BlockX / m_CellSize, 16 * (float)a_BlockZ / m_CellSize, 3000); - double NoiseZ = m_Noise.CubicNoise3D((float)a_BlockX / m_CellSize, (float)a_BlockZ / m_CellSize, 4000); - NoiseZ += 0.5 * m_Noise.CubicNoise3D(2 * (float)a_BlockX / m_CellSize, 2 * (float)a_BlockZ / m_CellSize, 5000); - NoiseZ += 0.08 * m_Noise.CubicNoise3D(16 * (float)a_BlockX / m_CellSize, 16 * (float)a_BlockZ / m_CellSize, 6000); - - a_DistortedX = a_BlockX + (int)(m_CellSize * 0.5 * NoiseX); - a_DistortedZ = a_BlockZ + (int)(m_CellSize * 0.5 * NoiseZ); -} - - - - - + +// BioGen.cpp + +// Implements the various biome generators + +#include "Globals.h" +#include "BioGen.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cBioGenConstant: + +void cBioGenConstant::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) +{ + for (int i = 0; i < ARRAYCOUNT(a_BiomeMap); i++) + { + a_BiomeMap[i] = m_Biome; + } +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cBioGenCache: + +cBioGenCache::cBioGenCache(cBiomeGen * a_BioGenToCache, int a_CacheSize) : + m_BioGenToCache(a_BioGenToCache), + m_CacheSize(a_CacheSize), + m_CacheOrder(new int[a_CacheSize]), + m_CacheData(new sCacheData[a_CacheSize]), + m_NumHits(0), + m_NumMisses(0), + m_TotalChain(0) +{ + for (int i = 0; i < m_CacheSize; i++) + { + m_CacheOrder[i] = i; + m_CacheData[i].m_ChunkX = 0x7fffffff; + m_CacheData[i].m_ChunkZ = 0x7fffffff; + } +} + + + + + +cBioGenCache::~cBioGenCache() +{ + delete m_CacheData; + delete m_CacheOrder; + delete m_BioGenToCache; +} + + + + + +void cBioGenCache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) +{ + if (((m_NumHits + m_NumMisses) % 1024) == 10) + { + LOGD("BioGenCache: %d hits, %d misses, saved %.2f %%", m_NumHits, m_NumMisses, 100.0 * m_NumHits / (m_NumHits + m_NumMisses)); + LOGD("BioGenCache: Avg cache chain length: %.2f", (float)m_TotalChain / m_NumHits); + } + + for (int i = 0; i < m_CacheSize; i++) + { + if ( + (m_CacheData[m_CacheOrder[i]].m_ChunkX != a_ChunkX) || + (m_CacheData[m_CacheOrder[i]].m_ChunkZ != a_ChunkZ) + ) + { + continue; + } + // Found it in the cache + int Idx = m_CacheOrder[i]; + + // Move to front: + for (int j = i; j > 0; j--) + { + m_CacheOrder[j] = m_CacheOrder[j - 1]; + } + m_CacheOrder[0] = Idx; + + // Use the cached data: + memcpy(a_BiomeMap, m_CacheData[Idx].m_BiomeMap, sizeof(a_BiomeMap)); + + m_NumHits++; + m_TotalChain += i; + return; + } // for i - cache + + // Not in the cache: + m_NumMisses++; + m_BioGenToCache->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap); + + // Insert it as the first item in the MRU order: + int Idx = m_CacheOrder[m_CacheSize - 1]; + for (int i = m_CacheSize - 1; i > 0; i--) + { + m_CacheOrder[i] = m_CacheOrder[i - 1]; + } // for i - m_CacheOrder[] + m_CacheOrder[0] = Idx; + memcpy(m_CacheData[Idx].m_BiomeMap, a_BiomeMap, sizeof(a_BiomeMap)); + m_CacheData[Idx].m_ChunkX = a_ChunkX; + m_CacheData[Idx].m_ChunkZ = a_ChunkZ; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cBiomeGenList: + +void cBiomeGenList::InitializeBiomes(const AString & a_Biomes) +{ + AStringVector Split = StringSplit(a_Biomes, ","); + + // Convert each string in the list into biome: + for (AStringVector::const_iterator itr = Split.begin(); itr != Split.end(); ++itr) + { + EMCSBiome Biome = StringToBiome(*itr); + if (Biome != -1) + { + m_Biomes.push_back(Biome); + } + } // for itr - Split[] + if (!m_Biomes.empty()) + { + m_BiomesCount = (int)m_Biomes.size(); + return; + } + + // There were no biomes, add default biomes: + static EMCSBiome Biomes[] = + { + biOcean, + biPlains, + biDesert, + biExtremeHills, + biForest, + biTaiga, + biSwampland, + biRiver, + biFrozenOcean, + biFrozenRiver, + biIcePlains, + biIceMountains, + biMushroomIsland, + biMushroomShore, + biBeach, + biDesertHills, + biForestHills, + biTaigaHills, + biExtremeHillsEdge, + biJungle, + biJungleHills, + } ; + m_Biomes.reserve(ARRAYCOUNT(Biomes)); + for (int i = 0; i < ARRAYCOUNT(Biomes); i++) + { + m_Biomes.push_back(Biomes[i]); + } + m_BiomesCount = (int)m_Biomes.size(); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cBioGenCheckerboard: + +void cBioGenCheckerboard::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) +{ + for (int z = 0; z < cChunkDef::Width; z++) + { + int Base = cChunkDef::Width * a_ChunkZ + z; + for (int x = 0; x < cChunkDef::Width; x++) + { + int Add = cChunkDef::Width * a_ChunkX + x; + a_BiomeMap[x + cChunkDef::Width * z] = m_Biomes[(Base / m_BiomeSize + Add / m_BiomeSize) % m_BiomesCount]; + } + } +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cBioGenVoronoi : + +void cBioGenVoronoi::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) +{ + int BaseZ = cChunkDef::Width * a_ChunkZ; + int BaseX = cChunkDef::Width * a_ChunkX; + for (int z = 0; z < cChunkDef::Width; z++) + { + int AbsoluteZ = BaseZ + z; + for (int x = 0; x < cChunkDef::Width; x++) + { + cChunkDef::SetBiome(a_BiomeMap, x, z, VoronoiBiome(BaseX + x, AbsoluteZ)); + } // for x + } // for z +} + + + + + +EMCSBiome cBioGenVoronoi::VoronoiBiome(int a_BlockX, int a_BlockZ) +{ + int CellX = a_BlockX / m_CellSize; + int CellZ = a_BlockZ / m_CellSize; + + // Note that Noise values need to be divided by 8 to gain a uniform modulo-2^n distribution + + // Get 5x5 neighboring cell seeds, compare distance to each. Return the biome in the minumim-distance cell + double MinDist = m_CellSize * m_CellSize; // There has to be a cell closer than this + EMCSBiome res = biPlains; // Will be overriden + for (int x = CellX - 2; x <= CellX + 2; x++) + { + int BaseX = x * m_CellSize; + for (int z = CellZ - 2; z < CellZ + 2; z++) + { + int OffsetX = (m_Noise.IntNoise3DInt(x, 16 * x + 32 * z, z) / 8) % m_CellSize; + int OffsetZ = (m_Noise.IntNoise3DInt(x, 32 * x - 16 * z, z) / 8) % m_CellSize; + int SeedX = BaseX + OffsetX; + int SeedZ = z * m_CellSize + OffsetZ; + + double Dist = sqrt((double)((SeedX - a_BlockX) * (SeedX - a_BlockX) + (SeedZ - a_BlockZ) * (SeedZ - a_BlockZ))); + if (Dist < MinDist) + { + MinDist = Dist; + res = m_Biomes[(m_Noise.IntNoise3DInt(x, x - z + 1000, z) / 8) % m_BiomesCount]; + } + } // for z + } // for x + + return res; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cBioGenDistortedVoronoi: + +void cBioGenDistortedVoronoi::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) +{ + int BaseZ = cChunkDef::Width * a_ChunkZ; + int BaseX = cChunkDef::Width * a_ChunkX; + for (int z = 0; z < cChunkDef::Width; z++) + { + int AbsoluteZ = BaseZ + z; + for (int x = 0; x < cChunkDef::Width; x++) + { + int DistX, DistZ; + Distort(BaseX + x, AbsoluteZ, DistX, DistZ); + cChunkDef::SetBiome(a_BiomeMap, x, z, VoronoiBiome(DistX, DistZ)); + } // for x + } // for z +} + + + + + +void cBioGenDistortedVoronoi::Distort(int a_BlockX, int a_BlockZ, int & a_DistortedX, int & a_DistortedZ) +{ + double NoiseX = m_Noise.CubicNoise3D((float)a_BlockX / m_CellSize, (float)a_BlockZ / m_CellSize, 1000); + NoiseX += 0.5 * m_Noise.CubicNoise3D(2 * (float)a_BlockX / m_CellSize, 2 * (float)a_BlockZ / m_CellSize, 2000); + NoiseX += 0.08 * m_Noise.CubicNoise3D(16 * (float)a_BlockX / m_CellSize, 16 * (float)a_BlockZ / m_CellSize, 3000); + double NoiseZ = m_Noise.CubicNoise3D((float)a_BlockX / m_CellSize, (float)a_BlockZ / m_CellSize, 4000); + NoiseZ += 0.5 * m_Noise.CubicNoise3D(2 * (float)a_BlockX / m_CellSize, 2 * (float)a_BlockZ / m_CellSize, 5000); + NoiseZ += 0.08 * m_Noise.CubicNoise3D(16 * (float)a_BlockX / m_CellSize, 16 * (float)a_BlockZ / m_CellSize, 6000); + + a_DistortedX = a_BlockX + (int)(m_CellSize * 0.5 * NoiseX); + a_DistortedZ = a_BlockZ + (int)(m_CellSize * 0.5 * NoiseZ); +} + + + + + diff --git a/source/BioGen.h b/source/BioGen.h index 9a119ef2e..8aaaeff4a 100644 --- a/source/BioGen.h +++ b/source/BioGen.h @@ -1,171 +1,171 @@ - -// BioGen.h - -/* -Interfaces to the various biome generators: - - cBioGenConstant - - cBioGenCheckerboard - - cBioGenDistortedVoronoi -*/ - - - - - -#pragma once - -#include "cChunkGenerator.h" -#include "cNoise.h" - - - - - -class cBioGenConstant : - public cBiomeGen -{ -public: - cBioGenConstant(EMCSBiome a_Biome) : m_Biome(a_Biome) {} - -protected: - - EMCSBiome m_Biome; - - // cBiomeGen override: - virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; -} ; - - - - - -/// A simple cache that stores N most recently generated chunks' biomes; N being settable upon creation -class cBioGenCache : - public cBiomeGen -{ -public: - cBioGenCache(cBiomeGen * a_BioGenToCache, int a_CacheSize); // Takes ownership of a_BioGenToCache - ~cBioGenCache(); - -protected: - - cBiomeGen * m_BioGenToCache; - - struct sCacheData - { - int m_ChunkX; - int m_ChunkZ; - cChunkDef::BiomeMap m_BiomeMap; - } ; - - // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data - int m_CacheSize; - int * m_CacheOrder; // MRU-ized order, indices into m_CacheData array - sCacheData * m_CacheData; // m_CacheData[m_CacheOrder[0]] is the most recently used - - // Cache statistics - int m_NumHits; - int m_NumMisses; - int m_TotalChain; // Number of cache items walked to get to a hit (only added for hits) - - virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; -} ; - - - - - -/// Base class for generators that use a list of available biomes. This class takes care of the list. -class cBiomeGenList : - public cBiomeGen -{ -protected: - cBiomeGenList(const AString & a_Biomes) - { - InitializeBiomes(a_Biomes); - } - - // List of biomes that the generator is allowed to generate: - typedef std::vector EMCSBiomes; - EMCSBiomes m_Biomes; - int m_BiomesCount; // Pulled out of m_Biomes for faster access - - void InitializeBiomes(const AString & a_Biomes); - -} ; - - - - - -class cBioGenCheckerboard : - public cBiomeGenList -{ -public: - cBioGenCheckerboard(int a_BiomeSize, const AString & a_Biomes) : - cBiomeGenList(a_Biomes), - m_BiomeSize((a_BiomeSize < 8) ? 8 : a_BiomeSize) - { - } - -protected: - - int m_BiomeSize; - - // cBiomeGen override: - virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; -} ; - - - - - -class cBioGenVoronoi : - public cBiomeGenList -{ -public: - cBioGenVoronoi(int a_Seed, int a_CellSize, const AString & a_Biomes) : - cBiomeGenList(a_Biomes), - m_CellSize((a_CellSize > 4) ? a_CellSize : 4), - m_Noise(a_Seed) - { - } - -protected: - - int m_CellSize; - - cNoise m_Noise; - - // cBiomeGen override: - virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; - - EMCSBiome VoronoiBiome(int a_BlockX, int a_BlockZ); -} ; - - - - - -class cBioGenDistortedVoronoi : - public cBioGenVoronoi -{ -public: - cBioGenDistortedVoronoi(int a_Seed, int a_CellSize, const AString & a_Biomes) : - cBioGenVoronoi(a_Seed, a_CellSize, a_Biomes) - { - } - -protected: - - // cBiomeGen override: - virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; - - /// Distorts the coords using a Perlin-like noise - void Distort(int a_BlockX, int a_BlockZ, int & a_DistortedX, int & a_DistortedZ); -} ; - - - - - + +// BioGen.h + +/* +Interfaces to the various biome generators: + - cBioGenConstant + - cBioGenCheckerboard + - cBioGenDistortedVoronoi +*/ + + + + + +#pragma once + +#include "cChunkGenerator.h" +#include "cNoise.h" + + + + + +class cBioGenConstant : + public cBiomeGen +{ +public: + cBioGenConstant(EMCSBiome a_Biome) : m_Biome(a_Biome) {} + +protected: + + EMCSBiome m_Biome; + + // cBiomeGen override: + virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; +} ; + + + + + +/// A simple cache that stores N most recently generated chunks' biomes; N being settable upon creation +class cBioGenCache : + public cBiomeGen +{ +public: + cBioGenCache(cBiomeGen * a_BioGenToCache, int a_CacheSize); // Takes ownership of a_BioGenToCache + ~cBioGenCache(); + +protected: + + cBiomeGen * m_BioGenToCache; + + struct sCacheData + { + int m_ChunkX; + int m_ChunkZ; + cChunkDef::BiomeMap m_BiomeMap; + } ; + + // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data + int m_CacheSize; + int * m_CacheOrder; // MRU-ized order, indices into m_CacheData array + sCacheData * m_CacheData; // m_CacheData[m_CacheOrder[0]] is the most recently used + + // Cache statistics + int m_NumHits; + int m_NumMisses; + int m_TotalChain; // Number of cache items walked to get to a hit (only added for hits) + + virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; +} ; + + + + + +/// Base class for generators that use a list of available biomes. This class takes care of the list. +class cBiomeGenList : + public cBiomeGen +{ +protected: + cBiomeGenList(const AString & a_Biomes) + { + InitializeBiomes(a_Biomes); + } + + // List of biomes that the generator is allowed to generate: + typedef std::vector EMCSBiomes; + EMCSBiomes m_Biomes; + int m_BiomesCount; // Pulled out of m_Biomes for faster access + + void InitializeBiomes(const AString & a_Biomes); + +} ; + + + + + +class cBioGenCheckerboard : + public cBiomeGenList +{ +public: + cBioGenCheckerboard(int a_BiomeSize, const AString & a_Biomes) : + cBiomeGenList(a_Biomes), + m_BiomeSize((a_BiomeSize < 8) ? 8 : a_BiomeSize) + { + } + +protected: + + int m_BiomeSize; + + // cBiomeGen override: + virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; +} ; + + + + + +class cBioGenVoronoi : + public cBiomeGenList +{ +public: + cBioGenVoronoi(int a_Seed, int a_CellSize, const AString & a_Biomes) : + cBiomeGenList(a_Biomes), + m_CellSize((a_CellSize > 4) ? a_CellSize : 4), + m_Noise(a_Seed) + { + } + +protected: + + int m_CellSize; + + cNoise m_Noise; + + // cBiomeGen override: + virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; + + EMCSBiome VoronoiBiome(int a_BlockX, int a_BlockZ); +} ; + + + + + +class cBioGenDistortedVoronoi : + public cBioGenVoronoi +{ +public: + cBioGenDistortedVoronoi(int a_Seed, int a_CellSize, const AString & a_Biomes) : + cBioGenVoronoi(a_Seed, a_CellSize, a_Biomes) + { + } + +protected: + + // cBiomeGen override: + virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; + + /// Distorts the coords using a Perlin-like noise + void Distort(int a_BlockX, int a_BlockZ, int & a_DistortedX, int & a_DistortedZ); +} ; + + + + + diff --git a/source/BlockID.cpp b/source/BlockID.cpp index 7588fee77..269bc2f3c 100644 --- a/source/BlockID.cpp +++ b/source/BlockID.cpp @@ -1,325 +1,325 @@ - -// BlockID.cpp - -// Implements the helper functions for converting Block ID string to int etc. - -#include "Globals.h" -#include "BlockID.h" -#include "../iniFile/iniFile.h" -#include "cItem.h" - - - - - -NIBBLETYPE g_BlockLightValue[256]; -NIBBLETYPE g_BlockSpreadLightFalloff[256]; -bool g_BlockTransparent[256]; -bool g_BlockOneHitDig[256]; -bool g_BlockPistonBreakable[256]; -bool g_BlockIsSnowable[256]; - - - - - -class cBlockIDMap -{ -public: - cBlockIDMap(void) : m_Ini("items.ini") - { - m_Ini.ReadFile(); - } - - int Resolve(const AString & a_ItemName) - { - return m_Ini.GetValueI("Items", a_ItemName, -1); - } - - AString ResolveString(const AString & a_ItemName) - { - return m_Ini.GetValue("Items", a_ItemName, ""); - } - -protected: - cIniFile m_Ini; -} ; - - - - - -static cBlockIDMap gsBlockIDMap; - - - - - -int BlockStringToType(const AString & a_BlockTypeString) -{ - int res = atoi(a_BlockTypeString.c_str()); - if ((res != 0) || (a_BlockTypeString.compare("0") == 0)) - { - // It was a valid number, return that - return res; - } - - return gsBlockIDMap.Resolve(TrimString(a_BlockTypeString)); -} - - - - -bool StringToItem(const AString & a_ItemTypeString, cItem & a_Item) -{ - AString Resolved = TrimString(gsBlockIDMap.ResolveString(TrimString(a_ItemTypeString))); - AString txt = (!Resolved.empty()) ? Resolved : a_ItemTypeString; - AStringVector Split = StringSplit(txt, ":"); - if (Split.size() == 1) - { - Split = StringSplit(txt, "^"); - } - if (Split.empty()) - { - return false; - } - a_Item.m_ItemID = (ENUM_ITEM_ID)atoi(Split[0].c_str()); - if ((a_Item.m_ItemID == 0) && (Split[0] != "0")) - { - // Parsing the number failed - return false; - } - if (Split.size() > 1) - { - a_Item.m_ItemHealth = atoi(Split[1].c_str()); - if ((a_Item.m_ItemHealth == 0) && (Split[1] != "0")) - { - // Parsing the number failed - return false; - } - } - return true; -} - - - - - -EMCSBiome StringToBiome(const AString & a_BiomeString) -{ - // If it is a number, return it: - int res = atoi(a_BiomeString.c_str()); - if ((res != 0) || (a_BiomeString.compare("0") == 0)) - { - // It was a valid number - return (EMCSBiome)res; - } - - // Convert using the built-in map: - static struct { - EMCSBiome m_Biome; - const char * m_String; - } BiomeMap[] = - { - {biOcean, "Ocean"} , - {biPlains, "Plains"}, - {biDesert, "Desert"}, - {biExtremeHills, "ExtremeHills"}, - {biForest, "Forest"}, - {biTaiga, "Taiga"}, - {biSwampland, "Swampland"}, - {biRiver, "River"}, - {biHell, "Hell"}, - {biHell, "Nether"}, - {biSky, "Sky"}, - {biFrozenOcean, "FrozenOcean"}, - {biFrozenRiver, "FrozenRiver"}, - {biIcePlains, "IcePlains"}, - {biIcePlains, "Tundra"}, - {biIceMountains, "IceMountains"}, - {biMushroomIsland, "MushroomIsland"}, - {biMushroomShore, "MushroomShore"}, - {biBeach, "Beach"}, - {biDesertHills, "DesertHills"}, - {biForestHills, "ForestHills"}, - {biTaigaHills, "TaigaHills"}, - {biExtremeHillsEdge, "ExtremeHillsEdge"}, - {biJungle, "Jungle"}, - {biJungleHills, "JungleHills"}, - } ; - - for (int i = 0; i < ARRAYCOUNT(BiomeMap); i++) - { - if (NoCaseCompare(BiomeMap[i].m_String, a_BiomeString) == 0) - { - return BiomeMap[i].m_Biome; - } - } // for i - BiomeMap[] - return (EMCSBiome)-1; -} - - - - - -// This is actually just some code that needs to run at program startup, so it is wrapped into a global var's constructor: -class cBlockPropertiesInitializer -{ -public: - cBlockPropertiesInitializer(void) - { - memset( g_BlockLightValue, 0x00, sizeof( g_BlockLightValue ) ); - memset( g_BlockSpreadLightFalloff, 0x0f, sizeof( g_BlockSpreadLightFalloff ) ); // 0x0f means total falloff - memset( g_BlockTransparent, 0x00, sizeof( g_BlockTransparent ) ); - memset( g_BlockOneHitDig, 0x00, sizeof( g_BlockOneHitDig ) ); - memset( g_BlockPistonBreakable, 0x00, sizeof( g_BlockPistonBreakable ) ); - memset( g_BlockIsSnowable, 0xff, sizeof( g_BlockIsSnowable)); // Set all blocks' snowable to true - - // Emissive blocks - g_BlockLightValue[E_BLOCK_FIRE] = 15; - g_BlockLightValue[E_BLOCK_GLOWSTONE] = 15; - g_BlockLightValue[E_BLOCK_JACK_O_LANTERN] = 15; - g_BlockLightValue[E_BLOCK_LAVA] = 15; - g_BlockLightValue[E_BLOCK_STATIONARY_LAVA] = 15; - g_BlockLightValue[E_BLOCK_END_PORTAL] = 15; - g_BlockLightValue[E_BLOCK_REDSTONE_LAMP_ON] = 15; - g_BlockLightValue[E_BLOCK_TORCH] = 14; - g_BlockLightValue[E_BLOCK_BURNING_FURNACE] = 13; - g_BlockLightValue[E_BLOCK_NETHER_PORTAL] = 11; - g_BlockLightValue[E_BLOCK_REDSTONE_ORE_GLOWING] = 9; - g_BlockLightValue[E_BLOCK_REDSTONE_REPEATER_ON] = 9; - g_BlockLightValue[E_BLOCK_REDSTONE_TORCH_ON] = 7; - g_BlockLightValue[E_BLOCK_BREWING_STAND] = 1; - g_BlockLightValue[E_BLOCK_BROWN_MUSHROOM] = 1; - g_BlockLightValue[E_BLOCK_DRAGON_EGG] = 1; - - // Spread blocks - g_BlockSpreadLightFalloff[E_BLOCK_AIR] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_CHEST] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_CROPS] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_FIRE] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_GLASS] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_GLOWSTONE] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_LEAVES] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_SIGN_POST] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_TORCH] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_VINES] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_WALLSIGN] = 1; - // Light in water and lava dissapears faster: - g_BlockSpreadLightFalloff[E_BLOCK_LAVA] = 2; - g_BlockSpreadLightFalloff[E_BLOCK_STATIONARY_LAVA] = 2; - g_BlockSpreadLightFalloff[E_BLOCK_STATIONARY_WATER] = 2; - g_BlockSpreadLightFalloff[E_BLOCK_WATER] = 2; - - // Transparent blocks - g_BlockTransparent[E_BLOCK_AIR] = true; - g_BlockTransparent[E_BLOCK_BROWN_MUSHROOM] = true; - g_BlockTransparent[E_BLOCK_CHEST] = true; - g_BlockTransparent[E_BLOCK_CROPS] = true; - g_BlockTransparent[E_BLOCK_FIRE] = true; - g_BlockTransparent[E_BLOCK_GLASS] = true; - g_BlockTransparent[E_BLOCK_ICE] = true; - g_BlockTransparent[E_BLOCK_RED_MUSHROOM] = true; - g_BlockTransparent[E_BLOCK_RED_ROSE] = true; - g_BlockTransparent[E_BLOCK_SIGN_POST] = true; - g_BlockTransparent[E_BLOCK_SNOW] = true; - g_BlockTransparent[E_BLOCK_TALL_GRASS] = true; - g_BlockTransparent[E_BLOCK_TORCH] = true; - g_BlockTransparent[E_BLOCK_VINES] = true; - g_BlockTransparent[E_BLOCK_WALLSIGN] = true; - g_BlockTransparent[E_BLOCK_YELLOW_FLOWER] = true; - - // TODO: Any other transparent blocks? - - // One hit break blocks - g_BlockOneHitDig[E_BLOCK_BROWN_MUSHROOM] = true; - g_BlockOneHitDig[E_BLOCK_CROPS] = true; - g_BlockOneHitDig[E_BLOCK_FIRE] = true; - g_BlockOneHitDig[E_BLOCK_LOCKED_CHEST] = true; - g_BlockOneHitDig[E_BLOCK_REDSTONE_REPEATER_OFF] = true; - g_BlockOneHitDig[E_BLOCK_REDSTONE_REPEATER_ON] = true; - g_BlockOneHitDig[E_BLOCK_REDSTONE_TORCH_OFF] = true; - g_BlockOneHitDig[E_BLOCK_REDSTONE_TORCH_ON] = true; - g_BlockOneHitDig[E_BLOCK_REDSTONE_WIRE] = true; - g_BlockOneHitDig[E_BLOCK_REDSTONE_WIRE] = true; - g_BlockOneHitDig[E_BLOCK_RED_MUSHROOM] = true; - g_BlockOneHitDig[E_BLOCK_RED_ROSE] = true; - g_BlockOneHitDig[E_BLOCK_REEDS] = true; - g_BlockOneHitDig[E_BLOCK_SAPLING] = true; - g_BlockOneHitDig[E_BLOCK_TNT] = true; - g_BlockOneHitDig[E_BLOCK_TALL_GRASS] = true; - g_BlockOneHitDig[E_BLOCK_TORCH] = true; - g_BlockOneHitDig[E_BLOCK_YELLOW_FLOWER] = true; - - // Blocks that breaks when pushed by piston - g_BlockPistonBreakable[E_BLOCK_AIR] = true; - g_BlockPistonBreakable[E_BLOCK_BED] = true; - g_BlockPistonBreakable[E_BLOCK_BROWN_MUSHROOM] = true; - g_BlockPistonBreakable[E_BLOCK_COBWEB] = true; - g_BlockPistonBreakable[E_BLOCK_CROPS] = true; - g_BlockPistonBreakable[E_BLOCK_DEAD_BUSH] = true; - g_BlockPistonBreakable[E_BLOCK_FIRE] = true; - g_BlockPistonBreakable[E_BLOCK_IRON_DOOR] = true; - g_BlockPistonBreakable[E_BLOCK_JACK_O_LANTERN] = true; - g_BlockPistonBreakable[E_BLOCK_LADDER] = true; - g_BlockPistonBreakable[E_BLOCK_LAVA] = false; - g_BlockPistonBreakable[E_BLOCK_LEVER] = true; - g_BlockPistonBreakable[E_BLOCK_MELON] = true; - g_BlockPistonBreakable[E_BLOCK_MELON_STEM] = true; - g_BlockPistonBreakable[E_BLOCK_PUMPKIN] = true; - g_BlockPistonBreakable[E_BLOCK_PUMPKIN_STEM] = true; - g_BlockPistonBreakable[E_BLOCK_REDSTONE_TORCH_OFF] = true; - g_BlockPistonBreakable[E_BLOCK_REDSTONE_TORCH_ON] = true; - g_BlockPistonBreakable[E_BLOCK_REDSTONE_WIRE] = true; - g_BlockPistonBreakable[E_BLOCK_RED_MUSHROOM] = true; - g_BlockPistonBreakable[E_BLOCK_RED_ROSE] = true; - g_BlockPistonBreakable[E_BLOCK_REEDS] = true; - g_BlockPistonBreakable[E_BLOCK_SNOW] = true; - g_BlockPistonBreakable[E_BLOCK_STATIONARY_LAVA] = false; - g_BlockPistonBreakable[E_BLOCK_STATIONARY_WATER] = false; //This gave pistons the ability to drop water :D - g_BlockPistonBreakable[E_BLOCK_STONE_BUTTON] = true; - g_BlockPistonBreakable[E_BLOCK_STONE_PRESSURE_PLATE] = true; - g_BlockPistonBreakable[E_BLOCK_TALL_GRASS] = true; - g_BlockPistonBreakable[E_BLOCK_TORCH] = true; - g_BlockPistonBreakable[E_BLOCK_VINES] = true; - g_BlockPistonBreakable[E_BLOCK_WATER] = false; - g_BlockPistonBreakable[E_BLOCK_WOODEN_DOOR] = true; - g_BlockPistonBreakable[E_BLOCK_WOODEN_PRESSURE_PLATE] = true; - g_BlockPistonBreakable[E_BLOCK_YELLOW_FLOWER] = true; - - // Blocks that can be snowed over: - g_BlockIsSnowable[E_BLOCK_BROWN_MUSHROOM] = false; - g_BlockIsSnowable[E_BLOCK_CACTUS] = false; - g_BlockIsSnowable[E_BLOCK_CHEST] = false; - g_BlockIsSnowable[E_BLOCK_CROPS] = false; - g_BlockIsSnowable[E_BLOCK_FIRE] = false; - g_BlockIsSnowable[E_BLOCK_FIRE] = false; - g_BlockIsSnowable[E_BLOCK_GLASS] = false; - g_BlockIsSnowable[E_BLOCK_ICE] = false; - g_BlockIsSnowable[E_BLOCK_LAVA] = false; - g_BlockIsSnowable[E_BLOCK_LOCKED_CHEST] = false; - g_BlockIsSnowable[E_BLOCK_REDSTONE_REPEATER_OFF] = false; - g_BlockIsSnowable[E_BLOCK_REDSTONE_REPEATER_ON] = false; - g_BlockIsSnowable[E_BLOCK_REDSTONE_TORCH_OFF] = false; - g_BlockIsSnowable[E_BLOCK_REDSTONE_TORCH_ON] = false; - g_BlockIsSnowable[E_BLOCK_REDSTONE_WIRE] = false; - g_BlockIsSnowable[E_BLOCK_RED_MUSHROOM] = false; - g_BlockIsSnowable[E_BLOCK_RED_ROSE] = false; - g_BlockIsSnowable[E_BLOCK_REEDS] = false; - g_BlockIsSnowable[E_BLOCK_SAPLING] = false; - g_BlockIsSnowable[E_BLOCK_SIGN_POST] = false; - g_BlockIsSnowable[E_BLOCK_SNOW] = false; - g_BlockIsSnowable[E_BLOCK_STATIONARY_LAVA] = false; - g_BlockIsSnowable[E_BLOCK_STATIONARY_WATER] = false; - g_BlockIsSnowable[E_BLOCK_TALL_GRASS] = false; - g_BlockIsSnowable[E_BLOCK_TNT] = false; - g_BlockIsSnowable[E_BLOCK_TORCH] = false; - g_BlockIsSnowable[E_BLOCK_WALLSIGN] = false; - g_BlockIsSnowable[E_BLOCK_WATER] = false; - g_BlockIsSnowable[E_BLOCK_YELLOW_FLOWER] = false; - } -} BlockPropertiesInitializer; - - - - + +// BlockID.cpp + +// Implements the helper functions for converting Block ID string to int etc. + +#include "Globals.h" +#include "BlockID.h" +#include "../iniFile/iniFile.h" +#include "cItem.h" + + + + + +NIBBLETYPE g_BlockLightValue[256]; +NIBBLETYPE g_BlockSpreadLightFalloff[256]; +bool g_BlockTransparent[256]; +bool g_BlockOneHitDig[256]; +bool g_BlockPistonBreakable[256]; +bool g_BlockIsSnowable[256]; + + + + + +class cBlockIDMap +{ +public: + cBlockIDMap(void) : m_Ini("items.ini") + { + m_Ini.ReadFile(); + } + + int Resolve(const AString & a_ItemName) + { + return m_Ini.GetValueI("Items", a_ItemName, -1); + } + + AString ResolveString(const AString & a_ItemName) + { + return m_Ini.GetValue("Items", a_ItemName, ""); + } + +protected: + cIniFile m_Ini; +} ; + + + + + +static cBlockIDMap gsBlockIDMap; + + + + + +int BlockStringToType(const AString & a_BlockTypeString) +{ + int res = atoi(a_BlockTypeString.c_str()); + if ((res != 0) || (a_BlockTypeString.compare("0") == 0)) + { + // It was a valid number, return that + return res; + } + + return gsBlockIDMap.Resolve(TrimString(a_BlockTypeString)); +} + + + + +bool StringToItem(const AString & a_ItemTypeString, cItem & a_Item) +{ + AString Resolved = TrimString(gsBlockIDMap.ResolveString(TrimString(a_ItemTypeString))); + AString txt = (!Resolved.empty()) ? Resolved : a_ItemTypeString; + AStringVector Split = StringSplit(txt, ":"); + if (Split.size() == 1) + { + Split = StringSplit(txt, "^"); + } + if (Split.empty()) + { + return false; + } + a_Item.m_ItemID = (ENUM_ITEM_ID)atoi(Split[0].c_str()); + if ((a_Item.m_ItemID == 0) && (Split[0] != "0")) + { + // Parsing the number failed + return false; + } + if (Split.size() > 1) + { + a_Item.m_ItemHealth = atoi(Split[1].c_str()); + if ((a_Item.m_ItemHealth == 0) && (Split[1] != "0")) + { + // Parsing the number failed + return false; + } + } + return true; +} + + + + + +EMCSBiome StringToBiome(const AString & a_BiomeString) +{ + // If it is a number, return it: + int res = atoi(a_BiomeString.c_str()); + if ((res != 0) || (a_BiomeString.compare("0") == 0)) + { + // It was a valid number + return (EMCSBiome)res; + } + + // Convert using the built-in map: + static struct { + EMCSBiome m_Biome; + const char * m_String; + } BiomeMap[] = + { + {biOcean, "Ocean"} , + {biPlains, "Plains"}, + {biDesert, "Desert"}, + {biExtremeHills, "ExtremeHills"}, + {biForest, "Forest"}, + {biTaiga, "Taiga"}, + {biSwampland, "Swampland"}, + {biRiver, "River"}, + {biHell, "Hell"}, + {biHell, "Nether"}, + {biSky, "Sky"}, + {biFrozenOcean, "FrozenOcean"}, + {biFrozenRiver, "FrozenRiver"}, + {biIcePlains, "IcePlains"}, + {biIcePlains, "Tundra"}, + {biIceMountains, "IceMountains"}, + {biMushroomIsland, "MushroomIsland"}, + {biMushroomShore, "MushroomShore"}, + {biBeach, "Beach"}, + {biDesertHills, "DesertHills"}, + {biForestHills, "ForestHills"}, + {biTaigaHills, "TaigaHills"}, + {biExtremeHillsEdge, "ExtremeHillsEdge"}, + {biJungle, "Jungle"}, + {biJungleHills, "JungleHills"}, + } ; + + for (int i = 0; i < ARRAYCOUNT(BiomeMap); i++) + { + if (NoCaseCompare(BiomeMap[i].m_String, a_BiomeString) == 0) + { + return BiomeMap[i].m_Biome; + } + } // for i - BiomeMap[] + return (EMCSBiome)-1; +} + + + + + +// This is actually just some code that needs to run at program startup, so it is wrapped into a global var's constructor: +class cBlockPropertiesInitializer +{ +public: + cBlockPropertiesInitializer(void) + { + memset( g_BlockLightValue, 0x00, sizeof( g_BlockLightValue ) ); + memset( g_BlockSpreadLightFalloff, 0x0f, sizeof( g_BlockSpreadLightFalloff ) ); // 0x0f means total falloff + memset( g_BlockTransparent, 0x00, sizeof( g_BlockTransparent ) ); + memset( g_BlockOneHitDig, 0x00, sizeof( g_BlockOneHitDig ) ); + memset( g_BlockPistonBreakable, 0x00, sizeof( g_BlockPistonBreakable ) ); + memset( g_BlockIsSnowable, 0xff, sizeof( g_BlockIsSnowable)); // Set all blocks' snowable to true + + // Emissive blocks + g_BlockLightValue[E_BLOCK_FIRE] = 15; + g_BlockLightValue[E_BLOCK_GLOWSTONE] = 15; + g_BlockLightValue[E_BLOCK_JACK_O_LANTERN] = 15; + g_BlockLightValue[E_BLOCK_LAVA] = 15; + g_BlockLightValue[E_BLOCK_STATIONARY_LAVA] = 15; + g_BlockLightValue[E_BLOCK_END_PORTAL] = 15; + g_BlockLightValue[E_BLOCK_REDSTONE_LAMP_ON] = 15; + g_BlockLightValue[E_BLOCK_TORCH] = 14; + g_BlockLightValue[E_BLOCK_BURNING_FURNACE] = 13; + g_BlockLightValue[E_BLOCK_NETHER_PORTAL] = 11; + g_BlockLightValue[E_BLOCK_REDSTONE_ORE_GLOWING] = 9; + g_BlockLightValue[E_BLOCK_REDSTONE_REPEATER_ON] = 9; + g_BlockLightValue[E_BLOCK_REDSTONE_TORCH_ON] = 7; + g_BlockLightValue[E_BLOCK_BREWING_STAND] = 1; + g_BlockLightValue[E_BLOCK_BROWN_MUSHROOM] = 1; + g_BlockLightValue[E_BLOCK_DRAGON_EGG] = 1; + + // Spread blocks + g_BlockSpreadLightFalloff[E_BLOCK_AIR] = 1; + g_BlockSpreadLightFalloff[E_BLOCK_CHEST] = 1; + g_BlockSpreadLightFalloff[E_BLOCK_CROPS] = 1; + g_BlockSpreadLightFalloff[E_BLOCK_FIRE] = 1; + g_BlockSpreadLightFalloff[E_BLOCK_GLASS] = 1; + g_BlockSpreadLightFalloff[E_BLOCK_GLOWSTONE] = 1; + g_BlockSpreadLightFalloff[E_BLOCK_LEAVES] = 1; + g_BlockSpreadLightFalloff[E_BLOCK_SIGN_POST] = 1; + g_BlockSpreadLightFalloff[E_BLOCK_TORCH] = 1; + g_BlockSpreadLightFalloff[E_BLOCK_VINES] = 1; + g_BlockSpreadLightFalloff[E_BLOCK_WALLSIGN] = 1; + // Light in water and lava dissapears faster: + g_BlockSpreadLightFalloff[E_BLOCK_LAVA] = 2; + g_BlockSpreadLightFalloff[E_BLOCK_STATIONARY_LAVA] = 2; + g_BlockSpreadLightFalloff[E_BLOCK_STATIONARY_WATER] = 2; + g_BlockSpreadLightFalloff[E_BLOCK_WATER] = 2; + + // Transparent blocks + g_BlockTransparent[E_BLOCK_AIR] = true; + g_BlockTransparent[E_BLOCK_BROWN_MUSHROOM] = true; + g_BlockTransparent[E_BLOCK_CHEST] = true; + g_BlockTransparent[E_BLOCK_CROPS] = true; + g_BlockTransparent[E_BLOCK_FIRE] = true; + g_BlockTransparent[E_BLOCK_GLASS] = true; + g_BlockTransparent[E_BLOCK_ICE] = true; + g_BlockTransparent[E_BLOCK_RED_MUSHROOM] = true; + g_BlockTransparent[E_BLOCK_RED_ROSE] = true; + g_BlockTransparent[E_BLOCK_SIGN_POST] = true; + g_BlockTransparent[E_BLOCK_SNOW] = true; + g_BlockTransparent[E_BLOCK_TALL_GRASS] = true; + g_BlockTransparent[E_BLOCK_TORCH] = true; + g_BlockTransparent[E_BLOCK_VINES] = true; + g_BlockTransparent[E_BLOCK_WALLSIGN] = true; + g_BlockTransparent[E_BLOCK_YELLOW_FLOWER] = true; + + // TODO: Any other transparent blocks? + + // One hit break blocks + g_BlockOneHitDig[E_BLOCK_BROWN_MUSHROOM] = true; + g_BlockOneHitDig[E_BLOCK_CROPS] = true; + g_BlockOneHitDig[E_BLOCK_FIRE] = true; + g_BlockOneHitDig[E_BLOCK_LOCKED_CHEST] = true; + g_BlockOneHitDig[E_BLOCK_REDSTONE_REPEATER_OFF] = true; + g_BlockOneHitDig[E_BLOCK_REDSTONE_REPEATER_ON] = true; + g_BlockOneHitDig[E_BLOCK_REDSTONE_TORCH_OFF] = true; + g_BlockOneHitDig[E_BLOCK_REDSTONE_TORCH_ON] = true; + g_BlockOneHitDig[E_BLOCK_REDSTONE_WIRE] = true; + g_BlockOneHitDig[E_BLOCK_REDSTONE_WIRE] = true; + g_BlockOneHitDig[E_BLOCK_RED_MUSHROOM] = true; + g_BlockOneHitDig[E_BLOCK_RED_ROSE] = true; + g_BlockOneHitDig[E_BLOCK_REEDS] = true; + g_BlockOneHitDig[E_BLOCK_SAPLING] = true; + g_BlockOneHitDig[E_BLOCK_TNT] = true; + g_BlockOneHitDig[E_BLOCK_TALL_GRASS] = true; + g_BlockOneHitDig[E_BLOCK_TORCH] = true; + g_BlockOneHitDig[E_BLOCK_YELLOW_FLOWER] = true; + + // Blocks that breaks when pushed by piston + g_BlockPistonBreakable[E_BLOCK_AIR] = true; + g_BlockPistonBreakable[E_BLOCK_BED] = true; + g_BlockPistonBreakable[E_BLOCK_BROWN_MUSHROOM] = true; + g_BlockPistonBreakable[E_BLOCK_COBWEB] = true; + g_BlockPistonBreakable[E_BLOCK_CROPS] = true; + g_BlockPistonBreakable[E_BLOCK_DEAD_BUSH] = true; + g_BlockPistonBreakable[E_BLOCK_FIRE] = true; + g_BlockPistonBreakable[E_BLOCK_IRON_DOOR] = true; + g_BlockPistonBreakable[E_BLOCK_JACK_O_LANTERN] = true; + g_BlockPistonBreakable[E_BLOCK_LADDER] = true; + g_BlockPistonBreakable[E_BLOCK_LAVA] = false; + g_BlockPistonBreakable[E_BLOCK_LEVER] = true; + g_BlockPistonBreakable[E_BLOCK_MELON] = true; + g_BlockPistonBreakable[E_BLOCK_MELON_STEM] = true; + g_BlockPistonBreakable[E_BLOCK_PUMPKIN] = true; + g_BlockPistonBreakable[E_BLOCK_PUMPKIN_STEM] = true; + g_BlockPistonBreakable[E_BLOCK_REDSTONE_TORCH_OFF] = true; + g_BlockPistonBreakable[E_BLOCK_REDSTONE_TORCH_ON] = true; + g_BlockPistonBreakable[E_BLOCK_REDSTONE_WIRE] = true; + g_BlockPistonBreakable[E_BLOCK_RED_MUSHROOM] = true; + g_BlockPistonBreakable[E_BLOCK_RED_ROSE] = true; + g_BlockPistonBreakable[E_BLOCK_REEDS] = true; + g_BlockPistonBreakable[E_BLOCK_SNOW] = true; + g_BlockPistonBreakable[E_BLOCK_STATIONARY_LAVA] = false; + g_BlockPistonBreakable[E_BLOCK_STATIONARY_WATER] = false; //This gave pistons the ability to drop water :D + g_BlockPistonBreakable[E_BLOCK_STONE_BUTTON] = true; + g_BlockPistonBreakable[E_BLOCK_STONE_PRESSURE_PLATE] = true; + g_BlockPistonBreakable[E_BLOCK_TALL_GRASS] = true; + g_BlockPistonBreakable[E_BLOCK_TORCH] = true; + g_BlockPistonBreakable[E_BLOCK_VINES] = true; + g_BlockPistonBreakable[E_BLOCK_WATER] = false; + g_BlockPistonBreakable[E_BLOCK_WOODEN_DOOR] = true; + g_BlockPistonBreakable[E_BLOCK_WOODEN_PRESSURE_PLATE] = true; + g_BlockPistonBreakable[E_BLOCK_YELLOW_FLOWER] = true; + + // Blocks that can be snowed over: + g_BlockIsSnowable[E_BLOCK_BROWN_MUSHROOM] = false; + g_BlockIsSnowable[E_BLOCK_CACTUS] = false; + g_BlockIsSnowable[E_BLOCK_CHEST] = false; + g_BlockIsSnowable[E_BLOCK_CROPS] = false; + g_BlockIsSnowable[E_BLOCK_FIRE] = false; + g_BlockIsSnowable[E_BLOCK_FIRE] = false; + g_BlockIsSnowable[E_BLOCK_GLASS] = false; + g_BlockIsSnowable[E_BLOCK_ICE] = false; + g_BlockIsSnowable[E_BLOCK_LAVA] = false; + g_BlockIsSnowable[E_BLOCK_LOCKED_CHEST] = false; + g_BlockIsSnowable[E_BLOCK_REDSTONE_REPEATER_OFF] = false; + g_BlockIsSnowable[E_BLOCK_REDSTONE_REPEATER_ON] = false; + g_BlockIsSnowable[E_BLOCK_REDSTONE_TORCH_OFF] = false; + g_BlockIsSnowable[E_BLOCK_REDSTONE_TORCH_ON] = false; + g_BlockIsSnowable[E_BLOCK_REDSTONE_WIRE] = false; + g_BlockIsSnowable[E_BLOCK_RED_MUSHROOM] = false; + g_BlockIsSnowable[E_BLOCK_RED_ROSE] = false; + g_BlockIsSnowable[E_BLOCK_REEDS] = false; + g_BlockIsSnowable[E_BLOCK_SAPLING] = false; + g_BlockIsSnowable[E_BLOCK_SIGN_POST] = false; + g_BlockIsSnowable[E_BLOCK_SNOW] = false; + g_BlockIsSnowable[E_BLOCK_STATIONARY_LAVA] = false; + g_BlockIsSnowable[E_BLOCK_STATIONARY_WATER] = false; + g_BlockIsSnowable[E_BLOCK_TALL_GRASS] = false; + g_BlockIsSnowable[E_BLOCK_TNT] = false; + g_BlockIsSnowable[E_BLOCK_TORCH] = false; + g_BlockIsSnowable[E_BLOCK_WALLSIGN] = false; + g_BlockIsSnowable[E_BLOCK_WATER] = false; + g_BlockIsSnowable[E_BLOCK_YELLOW_FLOWER] = false; + } +} BlockPropertiesInitializer; + + + + diff --git a/source/BlockID.h b/source/BlockID.h index 3e0b261cf..7ec2f9279 100644 --- a/source/BlockID.h +++ b/source/BlockID.h @@ -1,641 +1,641 @@ -#pragma once - -//tolua_begin -enum ENUM_BLOCK_ID -{ - E_BLOCK_AIR = 0, - E_BLOCK_STONE = 1, - E_BLOCK_GRASS = 2, - E_BLOCK_DIRT = 3, - E_BLOCK_COBBLESTONE = 4, - E_BLOCK_PLANKS = 5, - E_BLOCK_WOOD = E_BLOCK_PLANKS, - E_BLOCK_SAPLING = 6, - E_BLOCK_BEDROCK = 7, - E_BLOCK_WATER = 8, - E_BLOCK_STATIONARY_WATER = 9, - E_BLOCK_LAVA = 10, - E_BLOCK_STATIONARY_LAVA = 11, - E_BLOCK_SAND = 12, - E_BLOCK_GRAVEL = 13, - E_BLOCK_GOLD_ORE = 14, - E_BLOCK_IRON_ORE = 15, - E_BLOCK_COAL_ORE = 16, - E_BLOCK_LOG = 17, - E_BLOCK_LEAVES = 18, - E_BLOCK_SPONGE = 19, - E_BLOCK_GLASS = 20, - E_BLOCK_LAPIS_ORE = 21, - E_BLOCK_LAPIS_BLOCK = 22, - E_BLOCK_DISPENSER = 23, - E_BLOCK_SANDSTONE = 24, - E_BLOCK_NOTE_BLOCK = 25, - E_BLOCK_BED = 26, - E_BLOCK_POWERED_RAIL = 27, - E_BLOCK_DETECTOR_RAIL = 28, - E_BLOCK_STICKY_PISTON = 29, - E_BLOCK_COBWEB = 30, - E_BLOCK_TALL_GRASS = 31, - E_BLOCK_DEAD_BUSH = 32, - E_BLOCK_PISTON = 33, - E_BLOCK_PISTON_EXTENSION = 34, - E_BLOCK_WHITE_CLOTH = 35, // Deprecated, use E_BLOCK_WOOL instead - E_BLOCK_WOOL = 35, - E_BLOCK_PISTON_MOVED_BLOCK = 36, - E_BLOCK_YELLOW_FLOWER = 37, - E_BLOCK_RED_ROSE = 38, - E_BLOCK_BROWN_MUSHROOM = 39, - E_BLOCK_RED_MUSHROOM = 40, - E_BLOCK_GOLD_BLOCK = 41, - E_BLOCK_IRON_BLOCK = 42, - E_BLOCK_DOUBLE_STONE_SLAB = 43, - E_BLOCK_DOUBLE_STEP = 43, /// OBSOLETE, use E_BLOCK_DOUBLE_STONE_SLAB instead - E_BLOCK_STONE_SLAB = 44, - E_BLOCK_STEP = 44, /// OBSOLETE, use E_BLOCK_STONE_SLAB instead - E_BLOCK_BRICK = 45, - E_BLOCK_TNT = 46, - E_BLOCK_BOOKCASE = 47, - E_BLOCK_MOSSY_COBBLESTONE = 48, - E_BLOCK_OBSIDIAN = 49, - E_BLOCK_TORCH = 50, - E_BLOCK_FIRE = 51, - E_BLOCK_MOB_SPAWNER = 52, - E_BLOCK_WOODEN_STAIRS = 53, - E_BLOCK_CHEST = 54, - E_BLOCK_REDSTONE_WIRE = 55, - E_BLOCK_DIAMOND_ORE = 56, - E_BLOCK_DIAMOND_BLOCK = 57, - E_BLOCK_CRAFTING_TABLE = 58, - E_BLOCK_WORKBENCH = 58, - E_BLOCK_CROPS = 59, - E_BLOCK_SOIL = 60, // Deprecated, use E_BLOCK_FARMLAND instead - E_BLOCK_FARMLAND = 60, - E_BLOCK_FURNACE = 61, - E_BLOCK_LIT_FURNACE = 62, - E_BLOCK_BURNING_FURNACE = 62, - E_BLOCK_SIGN_POST = 63, - E_BLOCK_WOODEN_DOOR = 64, - E_BLOCK_LADDER = 65, - E_BLOCK_RAIL = 66, - E_BLOCK_MINECART_TRACKS = 66, - E_BLOCK_COBBLESTONE_STAIRS = 67, - E_BLOCK_WALLSIGN = 68, - E_BLOCK_LEVER = 69, - E_BLOCK_STONE_PRESSURE_PLATE = 70, - E_BLOCK_IRON_DOOR = 71, - E_BLOCK_WOODEN_PRESSURE_PLATE = 72, - E_BLOCK_REDSTONE_ORE = 73, - E_BLOCK_REDSTONE_ORE_GLOWING = 74, - E_BLOCK_REDSTONE_TORCH_OFF = 75, - E_BLOCK_REDSTONE_TORCH_ON = 76, - E_BLOCK_STONE_BUTTON = 77, - E_BLOCK_SNOW = 78, - E_BLOCK_ICE = 79, - E_BLOCK_SNOW_BLOCK = 80, - E_BLOCK_CACTUS = 81, - E_BLOCK_CLAY = 82, - E_BLOCK_SUGARCANE = 83, - E_BLOCK_REEDS = 83, - E_BLOCK_JUKEBOX = 84, - E_BLOCK_FENCE = 85, - E_BLOCK_PUMPKIN = 86, - E_BLOCK_BLOODSTONE = 87, // Deprecated, use E_BLOCK_NETHERRACK - E_BLOCK_NETHERRACK = 87, - E_BLOCK_SOULSAND = 88, - E_BLOCK_GLOWSTONE = 89, - E_BLOCK_PORT = 90, // Deprecated, use E_BLOCK_NETHER_PORTAL instead - E_BLOCK_NETHER_PORTAL = 90, - E_BLOCK_JACK_O_LANTERN = 91, - E_BLOCK_CAKE = 92, - E_BLOCK_REDSTONE_REPEATER_OFF = 93, - E_BLOCK_REDSTONE_REPEATER_ON = 94, - E_BLOCK_LOCKED_CHEST = 95, - E_BLOCK_TRAPDOOR = 96, - E_BLOCK_SILVERFISH_EGG = 97, - E_BLOCK_STONE_BRICKS = 98, - E_BLOCK_HUGE_BROWN_MUSHROOM = 99, - E_BLOCK_HUGE_RED_MUSHROOM = 100, - E_BLOCK_IRON_BAR = 101, - E_BLOCK_GLASS_PLANE = 102, - E_BLOCK_MELON = 103, - E_BLOCK_PUMPKIN_STEM = 104, - E_BLOCK_MELON_STEM = 105, - E_BLOCK_VINES = 106, - E_BLOCK_FENCE_GATE = 107, - E_BLOCK_BRICK_STAIRS = 108, - E_BLOCK_STONE_BRICK_STAIRS = 109, - E_BLOCK_MYCELIUM = 110, - E_BLOCK_LILY_PAD = 111, - E_BLOCK_NETHER_BRICK = 112, - E_BLOCK_NETHER_BRICK_FENCE = 113, - E_BLOCK_NETHER_BRICK_STAIRS = 114, - E_BLOCK_NETHER_WART = 115, - E_BLOCK_ENCHANTMENT_TABLE = 116, - E_BLOCK_BREWING_STAND = 117, - E_BLOCK_CAULDRON = 118, - E_BLOCK_END_PORTAL = 119, - E_BLOCK_END_PORTAL_FRAME = 120, - E_BLOCK_END_STONE = 121, - E_BLOCK_DRAGON_EGG = 122, - E_BLOCK_REDSTONE_LAMP_OFF = 123, - E_BLOCK_REDSTONE_LAMP_ON = 124, - E_BLOCK_DOUBLE_WOODEN_SLAB = 125, - E_BLOCK_WOODEN_SLAB = 126, - E_BLOCK_COCA_PLANT = 127, - E_BLOCK_SANDSTONE_STAIRS = 128, - E_BLOCK_EMERALD_ORE = 129, - E_BLOCK_ENDER_CHEST = 130, - E_BLOCK_TRIPWIRE_HOOK = 131, - E_BLOCK_TRIPWIRE = 132, - E_BLOCK_EMERALD_BLOCK = 133, - E_BLOCK_ = 121, -}; -//tolua_end - -//tolua_begin -enum ENUM_ITEM_ID -{ - E_ITEM_EMPTY = -1, - E_ITEM_STONE = 1, - E_ITEM_GRASS = 2, - E_ITEM_DIRT = 3, - E_ITEM_COBBLESTONE = 4, - E_ITEM_PLANKS = 5, - E_ITEM_WOOD = 5, // obsolete, use E_ITEM_PLANKS instead - E_ITEM_SAPLING = 6, - E_ITEM_BEDROCK = 7, - E_ITEM_WATER = 8, - E_ITEM_STATIONARY_WATER = 9, - E_ITEM_LAVA = 10, - E_ITEM_STATIONARY_LAVA = 11, - E_ITEM_SAND = 12, - E_ITEM_GRAVEL = 13, - E_ITEM_GOLD_ORE = 14, - E_ITEM_IRON_ORE = 15, - E_ITEM_COAL_ORE = 16, - E_ITEM_LOG = 17, - E_ITEM_LEAVES = 18, - E_ITEM_SPONGE = 19, - E_ITEM_GLASS = 20, - E_ITEM_LAPIS_ORE = 21, - E_ITEM_LAPIS_BLOCK = 22, - E_ITEM_DISPENSER = 23, - E_ITEM_SANDSTONE = 24, - E_ITEM_NOTE_ITEM = 25, - - E_ITEM_POWERED_RAIL = 27, - E_ITEM_DETECTOR_RAIL = 28, - E_ITEM_STICKY_PISTON = 29, - E_ITEM_COBWEB = 30, - E_ITEM_TALL_GRASS = 31, - E_ITEM_DEAD_BRUSH = 32, - E_ITEM_PISTON = 33, - E_ITEM_PISTON_EXTENSION = 34, - E_ITEM_WHITE_CLOTH = 35, - E_ITEM_PISTON_MOVED_BLOCK = 36, - E_ITEM_YELLOW_FLOWER = 37, - E_ITEM_RED_ROSE = 38, - E_ITEM_BROWN_MUSHROOM = 39, - E_ITEM_RED_MUSHROOM = 40, - E_ITEM_GOLD_BLOCK = 41, - E_ITEM_IRON_BLOCK = 42, - E_ITEM_DOUBLE_STONE_SLAB = 43, - E_ITEM_DOUBLE_STEP = 43, /// OBSOLETE, use E_ITEM_DOUBLE_STONE_SLAB - E_ITEM_STONE_SLAB = 44, - E_ITEM_STEP = 44, /// OBSOLETE, use E_ITEM_STONE_SLAB - E_ITEM_BRICK = 45, - E_ITEM_TNT = 46, - E_ITEM_BOOKCASE = 47, - E_ITEM_MOSSY_COBBLESTONE = 48, - E_ITEM_OBSIDIAN = 49, - E_ITEM_TORCH = 50, - E_ITEM_FIRE = 51, - E_ITEM_MOB_SPAWNER = 52, - E_ITEM_WOODEN_STAIRS = 53, - E_ITEM_CHEST = 54, - E_ITEM_REDSTONE_WIRE = 55, - E_ITEM_DIAMOND_ORE = 56, - E_ITEM_DIAMOND_BLOCK = 57, - E_ITEM_WORKBENCH = 58, - E_ITEM_CROPS = 59, - E_ITEM_SOIL = 60, - E_ITEM_FURNACE = 61, - E_ITEM_BURNING_FURNACE = 62, - E_ITEM_SIGN_POST = 63, - - E_ITEM_LADDER = 65, - E_ITEM_MINECART_TRACKS = 66, - E_ITEM_COBBLESTONE_STAIRS = 67, - E_ITEM_WALLSIGN = 68, - E_ITEM_LEVER = 69, - E_ITEM_STONE_PRESSURE_PLATE = 70, - - E_ITEM_WOODEN_PRESSURE_PLATE = 72, - E_ITEM_REDSTONE_ORE = 73, - E_ITEM_REDSTONE_ORE_GLOWING = 74, - E_ITEM_REDSTONE_TORCH_ON = 75, - E_ITEM_REDSTONE_TORCH_OFF = 76, - E_ITEM_STONE_BUTTON = 77, - E_ITEM_SNOW = 78, - E_ITEM_ICE = 79, - E_ITEM_SNOW_BLOCK = 80, - E_ITEM_CACTUS = 81, - - E_ITEM_REEDS = 83, - E_ITEM_JUKEBOX = 84, - E_ITEM_FENCE = 85, - E_ITEM_PUMPKIN = 86, - E_ITEM_BLOODSTONE = 87, - E_ITEM_SOULSAND = 88, - E_ITEM_GLOWSTONE = 89, - E_ITEM_PORT = 90, - E_ITEM_JACK_O_LANTERN = 91, - - E_ITEM_REDSTONE_REPEATER_OFF = 93, - E_ITEM_REDSTONE_REPEATER_ON = 94, - E_ITEM_LOCKED_CHEST = 95, - E_ITEM_TRAPDOOR = 96, - E_ITEM_SILVERFISH_EGG = 97, - E_ITEM_STONE_BRICKS = 98, - E_ITEM_HUGE_BROWN_MUSHROOM = 99, - E_ITEM_HUGE_RED_MUSHROOM = 100, - E_ITEM_IRON_BAR = 101, - E_ITEM_GLASS_PLANE = 102, - E_ITEM_MELON = 103, - E_ITEM_PUMPKIN_STEM = 104, - E_ITEM_MELON_STEM = 105, - E_ITEM_VINES = 106, - E_ITEM_FENCE_GATE = 107, - E_ITEM_BRICK_STAIRS = 108, - E_ITEM_STONE_BRICK_STAIRS = 109, - E_ITEM_MYCELIUM = 110, - E_ITEM_LILY_PAD = 111, - E_ITEM_NETHER_BRICK = 112, - E_ITEM_NETHER_BRICK_FENCE = 113, - E_ITEM_NETHER_BRICK_STAIRS = 114, - - E_ITEM_ENCHANTMENT_TABLE = 116, - - E_ITEM_END_PORTAL = 119, - E_ITEM_END_PORTAL_FRAME = 120, - E_ITEM_END_STONE = 121, - - E_ITEM_DOUBLE_WOODEN_SLAB = 125, - E_ITEM_WOODEN_SLAB = 126, - E_ITEM_COCA_PLANT = 127, - E_ITEM_SANDSTONE_STAIRS = 128, - E_ITEM_EMERALD_ORE = 129, - E_ITEM_ENDER_CHEST = 130, - E_ITEM_TRIPWIRE_HOOK = 131, - E_ITEM_TRIPWIRE = 132, - E_ITEM_EMERALD_BLOCK = 133, - - E_ITEM_IRON_SHOVEL = 256, - E_ITEM_IRON_PICKAXE = 257, - E_ITEM_IRON_AXE = 258, - E_ITEM_FLINT_AND_STEEL = 259, - E_ITEM_RED_APPLE = 260, - E_ITEM_APPLE = 260, // OBSOLETE, use E_ITEM_RED_APPLE instead - E_ITEM_BOW = 261, - E_ITEM_ARROW = 262, - E_ITEM_COAL = 263, - E_ITEM_DIAMOND = 264, - E_ITEM_IRON = 265, - E_ITEM_GOLD = 266, - E_ITEM_IRON_SWORD = 267, - E_ITEM_WOODEN_SWORD = 268, - E_ITEM_WOODEN_SHOVEL = 269, - E_ITEM_WOODEN_PICKAXE = 270, - E_ITEM_WOODEN_AXE = 271, - E_ITEM_STONE_SWORD = 272, - E_ITEM_STONE_SHOVEL = 273, - E_ITEM_STONE_PICKAXE = 274, - E_ITEM_STONE_AXE = 275, - E_ITEM_DIAMOND_SWORD = 276, - E_ITEM_DIAMOND_SHOVEL = 277, - E_ITEM_DIAMOND_PICKAXE = 278, - E_ITEM_DIAMOND_AXE = 279, - E_ITEM_STICK = 280, - E_ITEM_BOWL = 281, - E_ITEM_MUSHROOM_SOUP = 282, - E_ITEM_GOLD_SWORD = 283, - E_ITEM_GOLD_SHOVEL = 284, - E_ITEM_GOLD_PICKAXE = 285, - E_ITEM_GOLD_AXE = 286, - E_ITEM_STRING = 287, - E_ITEM_FEATHER = 288, - E_ITEM_GUNPOWDER = 289, - E_ITEM_WOODEN_HOE = 290, - E_ITEM_STONE_HOE = 291, - E_ITEM_IRON_HOE = 292, - E_ITEM_DIAMOND_HOE = 293, - E_ITEM_GOLD_HOE = 294, - E_ITEM_SEEDS = 295, - E_ITEM_WHEAT = 296, - E_ITEM_BREAD = 297, - E_ITEM_LEATHER_CAP = 298, - E_ITEM_LEATHER_TUNIC = 299, - E_ITEM_LEATHER_PANTS = 300, - E_ITEM_LEATHER_BOOTS = 301, - E_ITEM_CHAIN_HELMET = 302, - E_ITEM_CHAIN_CHESTPLATE = 303, - E_ITEM_CHAIN_LEGGINGS = 304, - E_ITEM_CHAIN_BOOTS = 305, - E_ITEM_IRON_HELMET = 306, - E_ITEM_IRON_CHESTPLATE = 307, - E_ITEM_IRON_LEGGINGS = 308, - E_ITEM_IRON_BOOTS = 309, - E_ITEM_DIAMOND_HELMET = 310, - E_ITEM_DIAMOND_CHESTPLATE = 311, - E_ITEM_DIAMOND_LEGGINGS = 312, - E_ITEM_DIAMOND_BOOTS = 313, - E_ITEM_GOLD_HELMET = 314, - E_ITEM_GOLD_CHESTPLATE = 315, - E_ITEM_GOLD_LEGGINGS = 316, - E_ITEM_GOLD_BOOTS = 317, - E_ITEM_FLINT = 318, - E_ITEM_RAW_MEAT = 319, - E_ITEM_COOKED_MEAT = 320, - E_ITEM_PAINTINGS = 321, - E_ITEM_GOLDEN_APPLE = 322, - E_ITEM_SIGN = 323, - E_ITEM_WOODEN_DOOR = 324, - E_ITEM_BUCKET = 325, - E_ITEM_WATER_BUCKET = 326, - E_ITEM_LAVA_BUCKET = 327, - E_ITEM_MINECART = 328, - E_ITEM_SADDLE = 329, - E_ITEM_IRON_DOOR = 330, - E_ITEM_REDSTONE_DUST = 331, - E_ITEM_SNOWBALL = 332, - E_ITEM_BOAT = 333, - E_ITEM_LEATHER = 334, - E_ITEM_MILK = 335, - E_ITEM_CLAY_BRICK = 336, - E_ITEM_CLAY = 337, - E_ITEM_SUGARCANE = 338, - E_ITEM_SUGAR_CANE = 338, - E_ITEM_PAPER = 339, - E_ITEM_BOOK = 340, - E_ITEM_SLIMEBALL = 341, - E_ITEM_CHEST_MINECART = 342, - E_ITEM_FURNACE_MINECART = 343, - E_ITEM_EGG = 344, - E_ITEM_COMPASS = 345, - E_ITEM_FISHING_ROD = 346, - E_ITEM_CLOCK = 347, - E_ITEM_GLOWSTONE_DUST = 348, - E_ITEM_RAW_FISH = 349, - E_ITEM_COOKED_FISH = 350, - E_ITEM_DYE = 351, - E_ITEM_BONE = 352, - E_ITEM_SUGAR = 353, - E_ITEM_CAKE = 354, - E_ITEM_BED = 355, - E_ITEM_REDSTONE_REPEATER = 356, - E_ITEM_COOKIE = 357, - E_ITEM_MAP = 358, - E_ITEM_SHEARS = 359, - E_ITEM_MELON_SLICE = 360, - E_ITEM_PUMPKIN_SEEDS = 361, - E_ITEM_MELON_SEEDS = 362, - E_ITEM_RAW_BEEF = 363, - E_ITEM_STEAK = 364, - E_ITEM_RAW_CHICKEN = 365, - E_ITEM_COOKED_CHICKEN = 366, - E_ITEM_ROTTEN_FLESH = 367, - E_ITEM_ENDER_PEARL = 368, - E_ITEM_BLAZE_ROD = 369, - E_ITEM_GHAST_TEAR = 370, - E_ITEM_GOLD_NUGGET = 371, - E_ITEM_NETHER_WART = 372, - E_ITEM_POTIONS = 373, - E_ITEM_GLASS_BOTTLE = 374, - E_ITEM_SPIDER_EYE = 375, - E_ITEM_FERMENTED_SPIDER_EYE = 376, - E_ITEM_BLAZE_POWDER = 377, - E_ITEM_MAGMA_CREAM = 378, - E_ITEM_BREWING_STAND = 379, - E_ITEM_CAULDRON = 380, - E_ITEM_EYE_OF_ENDER = 381, - E_ITEM_GLISTERING_MELON = 382, - - E_ITEM_SPAWN_EGG = 383, - E_ITEM_BOTTLE_O_ENCHANTING = 384, - E_ITEM_FIRE_CHARGE = 385, - E_ITEM_BOOK_AND_QUILL = 386, - E_ITEM_WRITTEN_BOOK = 387, - E_ITEM_EMERALD = 388, - - E_ITEM_13_DISC = 2256, - E_ITEM_CAT_DISC = 2257, - E_ITEM_BLOCKS_DISC = 2258, - E_ITEM_CHIRP_DISC = 2259, - E_ITEM_FAR_DISC = 2260, - E_ITEM_MALL_DISC = 2261, - E_ITEM_MELLOHI_DISC = 2262, - E_ITEM_STAL_DISC = 2263, - E_ITEM_STRAD_DISC = 2264, - E_ITEM_WARD_DISC = 2265, - E_ITEM_11_DISC = 2266, -}; - - - - - -enum -{ - // E_BLOCK_PLANKS metas: - E_META_PLANKS_APPLE = 0, - E_META_PLANKS_CONIFER = 1, - E_META_PLANKS_BIRCH = 2, - E_META_PLANKS_JUNGLE = 3, - - // E_BLOCK_LOG metas: - E_META_LOG_APPLE = 0, - E_META_LOG_CONIFER = 1, - E_META_LOG_BIRCH = 2, - E_META_LOG_JUNGLE = 3, - - // E_BLOCK_LEAVES metas: - E_META_LEAVES_APPLE = 0, - E_META_LEAVES_CONIFER = 1, - E_META_LEAVES_BIRCH = 2, - E_META_LEAVES_JUNGLE = 3, - - // E_BLOCK_SAPLING metas (lowest 3 bits): - E_META_SAPLING_APPLE = 0, - E_META_SAPLING_CONIFER = 1, - E_META_SAPLING_BIRCH = 2, - E_META_SAPLING_JUNGLE = 3, - - // E_BLOCK_TALL_GRASS metas: - E_META_TALL_GRASS_DEAD_SHRUB = 0, - E_META_TALL_GRASS_GRASS = 1, - E_META_TALL_GRASS_FERN = 2, - - // E_BLOCK_SANDSTONE metas: - E_META_SANDSTONE_NORMAL = 0, - E_META_SANDSTONE_ORNAMENT = 1, - E_META_SANDSTONE_SMOOTH = 2, - - // E_BLOCK_WOOL metas: - E_META_WOOL_WHITE = 0, - E_META_WOOL_ORANGE = 1, - E_META_WOOL_MAGENTA = 2, - E_META_WOOL_LIGHTBLUE = 3, - E_META_WOOL_YELLOW = 4, - E_META_WOOL_LIGHTGREEN = 5, - E_META_WOOL_PINK = 6, - E_META_WOOL_GRAY = 7, - E_META_WOOL_LIGHTGRAY = 8, - E_META_WOOL_CYAN = 9, - E_META_WOOL_PURPLE = 10, - E_META_WOOL_BLUE = 11, - E_META_WOOL_BROWN = 12, - E_META_WOOL_GREEN = 13, - E_META_WOOL_RED = 14, - E_META_WOOL_BLACK = 15, - - // E_BLOCK_DOUBLE_STEP metas: - E_META_DOUBLE_STEP_STONE = 0, - E_META_DOUBLE_STEP_SANDSTONE = 1, - E_META_DOUBLE_STEP_WOODEN = 2, - E_META_DOUBLE_STEP_COBBLESTONE = 3, - E_META_DOUBLE_STEP_BRICK = 4, - E_META_DOUBLE_STEP_STONE_BRICK = 5, - E_META_DOUBLE_STEP_STONE_SECRET = 6, - - // E_BLOCK_STEP metas: - E_META_STEP_STONE = 0, - E_META_STEP_SANDSTONE = 1, - E_META_STEP_PLANKS = 2, - E_META_STEP_COBBLESTONE = 3, - E_META_STEP_BRICK = 4, - E_META_STEP_STONE_BRICK = 5, - E_META_STEP_STONE_SECRET = 6, - - // E_BLOCK_SILVERFISH_EGG metas: - E_META_SILVERFISH_EGG_STONE = 0, - E_META_SILVERFISH_EGG_COBBLESTONE = 1, - E_META_SILVERFISH_EGG_STONE_BRICK = 2, - - // E_BLOCK_STONE_BRICKS metas: - E_META_STONE_BRICK_NORMAL = 0, - E_META_STONE_BRICK_MOSSY = 1, - E_META_STONE_BRICK_CRACKED = 2, - E_META_STONE_BRICK_ORNAMENT = 3, - - // E_BLOCK_WOODEN_DOUBLE_STEP metas: - E_BLOCK_WOODEN_DOUBLE_STEP_APPLE = 0, - E_BLOCK_WOODEN_DOUBLE_STEP_CONIFER = 1, - E_BLOCK_WOODEN_DOUBLE_STEP_BIRCH = 2, - E_BLOCK_WOODEN_DOUBLE_STEP_JUNGLE = 3, - - // E_BLOCK_WOODEN_STEP metas: - E_BLOCK_WOODEN_STEP_APPLE = 0, - E_BLOCK_WOODEN_STEP_CONIFER = 1, - E_BLOCK_WOODEN_STEP_BIRCH = 2, - E_BLOCK_WOODEN_STEP_JUNGLE = 3, -} ; - - - - - - - -enum -{ - // E_ITEM_COAL metas: - E_META_COAL_NORMAL = 0, - E_META_COAL_CHARCOAL = 1, - - // E_ITEM_GOLDEN_APPLE metas: - E_META_GOLDEN_APPLE_NORMAL = 0, - E_META_GOLDEN_APPLE_ENCHANTED = 1, - - // E_ITEM_DYE metas: - E_META_DYE_BLACK = 0, - E_META_DYE_RED = 1, - E_META_DYE_GREEN = 2, - E_META_DYE_BROWN = 3, - E_META_DYE_BLUE = 4, - E_META_DYE_PURPLE = 5, - E_META_DYE_CYAN = 6, - E_META_DYE_LIGHTGRAY = 7, - E_META_DYE_GRAY = 8, - E_META_DYE_PINK = 9, - E_META_DYE_LIGHTGREEN = 10, - E_META_DYE_YELLOW = 11, - E_META_DYE_LIGHTBLUE = 12, - E_META_DYE_MAGENTA = 13, - E_META_DYE_ORANGE = 14, - E_META_DYE_WHITE = 15, - - // E_ITEM_SPAWN_EGG spawn EntityIDs: - // hostile: - E_META_SPAWN_EGG_CREEPER = 50, - E_META_SPAWN_EGG_SKELETON = 51, - E_META_SPAWN_EGG_SPIDER = 52, - E_META_SPAWN_EGG_ZOMBIE = 54, - E_META_SPAWN_EGG_SLIME = 55, - E_META_SPAWN_EGG_GHAST = 56, - E_META_SPAWN_EGG_ZOMBIE_PIGMAN = 57, - E_META_SPAWN_EGG_ENDERMAN = 58, - E_META_SPAWN_EGG_CAVE_SPIDER = 59, - E_META_SPAWN_EGG_SILVERFISH = 60, - E_META_SPAWN_EGG_BLAZE = 61, - E_META_SPAWN_EGG_MAGMA_CUBE = 62, - E_META_SPAWN_EGG_GIANT = 53, - E_META_SPAWN_EGG_ENDER_DRAGON = 63, - E_META_SPAWN_EGG_PIG = 90, - E_META_SPAWN_EGG_SHEEP = 91, - E_META_SPAWN_EGG_COW = 92, - E_META_SPAWN_EGG_CHICKEN = 93, - E_META_SPAWN_EGG_SQUID = 94, - E_META_SPAWN_EGG_WOLF = 95, - E_META_SPAWN_EGG_MOOSHROOM = 96, - E_META_SPAWN_EGG_OCELOT = 98, - E_META_SPAWN_EGG_VILLAGER = 120, - E_META_SPAWN_EGG_SNOW_GOLEM = 97, - E_META_SPAWN_EGG_IRON_GOLEM = 99, -} ; -//tolua_end - - - - -// fwd: cItem.h: -class cItem; - - - - - -/// Translates a blocktype string into blocktype. Takes either a number or an items.ini alias as input. Returns -1 on failure. -extern int BlockStringToType(const AString & a_BlockTypeString); // tolua_export - -/// Translates an itemtype string into an item. Takes either a number, number^number, number:number or an items.ini alias as input. Returns true if successful. -extern bool StringToItem(const AString & a_ItemTypeString, cItem & a_Item); // tolua_export - -/// Translates a biome string to biome enum. Takes either a number or a biome alias (built-in). Returns -1 on failure. -extern EMCSBiome StringToBiome(const AString & a_BiomeString); - - - - - -// Block properties: -extern NIBBLETYPE g_BlockLightValue[256]; -extern NIBBLETYPE g_BlockSpreadLightFalloff[256]; -extern bool g_BlockTransparent[256]; -extern bool g_BlockOneHitDig[256]; -extern bool g_BlockPistonBreakable[256]; -extern bool g_BlockIsSnowable[256]; - - - - - +#pragma once + +//tolua_begin +enum ENUM_BLOCK_ID +{ + E_BLOCK_AIR = 0, + E_BLOCK_STONE = 1, + E_BLOCK_GRASS = 2, + E_BLOCK_DIRT = 3, + E_BLOCK_COBBLESTONE = 4, + E_BLOCK_PLANKS = 5, + E_BLOCK_WOOD = E_BLOCK_PLANKS, + E_BLOCK_SAPLING = 6, + E_BLOCK_BEDROCK = 7, + E_BLOCK_WATER = 8, + E_BLOCK_STATIONARY_WATER = 9, + E_BLOCK_LAVA = 10, + E_BLOCK_STATIONARY_LAVA = 11, + E_BLOCK_SAND = 12, + E_BLOCK_GRAVEL = 13, + E_BLOCK_GOLD_ORE = 14, + E_BLOCK_IRON_ORE = 15, + E_BLOCK_COAL_ORE = 16, + E_BLOCK_LOG = 17, + E_BLOCK_LEAVES = 18, + E_BLOCK_SPONGE = 19, + E_BLOCK_GLASS = 20, + E_BLOCK_LAPIS_ORE = 21, + E_BLOCK_LAPIS_BLOCK = 22, + E_BLOCK_DISPENSER = 23, + E_BLOCK_SANDSTONE = 24, + E_BLOCK_NOTE_BLOCK = 25, + E_BLOCK_BED = 26, + E_BLOCK_POWERED_RAIL = 27, + E_BLOCK_DETECTOR_RAIL = 28, + E_BLOCK_STICKY_PISTON = 29, + E_BLOCK_COBWEB = 30, + E_BLOCK_TALL_GRASS = 31, + E_BLOCK_DEAD_BUSH = 32, + E_BLOCK_PISTON = 33, + E_BLOCK_PISTON_EXTENSION = 34, + E_BLOCK_WHITE_CLOTH = 35, // Deprecated, use E_BLOCK_WOOL instead + E_BLOCK_WOOL = 35, + E_BLOCK_PISTON_MOVED_BLOCK = 36, + E_BLOCK_YELLOW_FLOWER = 37, + E_BLOCK_RED_ROSE = 38, + E_BLOCK_BROWN_MUSHROOM = 39, + E_BLOCK_RED_MUSHROOM = 40, + E_BLOCK_GOLD_BLOCK = 41, + E_BLOCK_IRON_BLOCK = 42, + E_BLOCK_DOUBLE_STONE_SLAB = 43, + E_BLOCK_DOUBLE_STEP = 43, /// OBSOLETE, use E_BLOCK_DOUBLE_STONE_SLAB instead + E_BLOCK_STONE_SLAB = 44, + E_BLOCK_STEP = 44, /// OBSOLETE, use E_BLOCK_STONE_SLAB instead + E_BLOCK_BRICK = 45, + E_BLOCK_TNT = 46, + E_BLOCK_BOOKCASE = 47, + E_BLOCK_MOSSY_COBBLESTONE = 48, + E_BLOCK_OBSIDIAN = 49, + E_BLOCK_TORCH = 50, + E_BLOCK_FIRE = 51, + E_BLOCK_MOB_SPAWNER = 52, + E_BLOCK_WOODEN_STAIRS = 53, + E_BLOCK_CHEST = 54, + E_BLOCK_REDSTONE_WIRE = 55, + E_BLOCK_DIAMOND_ORE = 56, + E_BLOCK_DIAMOND_BLOCK = 57, + E_BLOCK_CRAFTING_TABLE = 58, + E_BLOCK_WORKBENCH = 58, + E_BLOCK_CROPS = 59, + E_BLOCK_SOIL = 60, // Deprecated, use E_BLOCK_FARMLAND instead + E_BLOCK_FARMLAND = 60, + E_BLOCK_FURNACE = 61, + E_BLOCK_LIT_FURNACE = 62, + E_BLOCK_BURNING_FURNACE = 62, + E_BLOCK_SIGN_POST = 63, + E_BLOCK_WOODEN_DOOR = 64, + E_BLOCK_LADDER = 65, + E_BLOCK_RAIL = 66, + E_BLOCK_MINECART_TRACKS = 66, + E_BLOCK_COBBLESTONE_STAIRS = 67, + E_BLOCK_WALLSIGN = 68, + E_BLOCK_LEVER = 69, + E_BLOCK_STONE_PRESSURE_PLATE = 70, + E_BLOCK_IRON_DOOR = 71, + E_BLOCK_WOODEN_PRESSURE_PLATE = 72, + E_BLOCK_REDSTONE_ORE = 73, + E_BLOCK_REDSTONE_ORE_GLOWING = 74, + E_BLOCK_REDSTONE_TORCH_OFF = 75, + E_BLOCK_REDSTONE_TORCH_ON = 76, + E_BLOCK_STONE_BUTTON = 77, + E_BLOCK_SNOW = 78, + E_BLOCK_ICE = 79, + E_BLOCK_SNOW_BLOCK = 80, + E_BLOCK_CACTUS = 81, + E_BLOCK_CLAY = 82, + E_BLOCK_SUGARCANE = 83, + E_BLOCK_REEDS = 83, + E_BLOCK_JUKEBOX = 84, + E_BLOCK_FENCE = 85, + E_BLOCK_PUMPKIN = 86, + E_BLOCK_BLOODSTONE = 87, // Deprecated, use E_BLOCK_NETHERRACK + E_BLOCK_NETHERRACK = 87, + E_BLOCK_SOULSAND = 88, + E_BLOCK_GLOWSTONE = 89, + E_BLOCK_PORT = 90, // Deprecated, use E_BLOCK_NETHER_PORTAL instead + E_BLOCK_NETHER_PORTAL = 90, + E_BLOCK_JACK_O_LANTERN = 91, + E_BLOCK_CAKE = 92, + E_BLOCK_REDSTONE_REPEATER_OFF = 93, + E_BLOCK_REDSTONE_REPEATER_ON = 94, + E_BLOCK_LOCKED_CHEST = 95, + E_BLOCK_TRAPDOOR = 96, + E_BLOCK_SILVERFISH_EGG = 97, + E_BLOCK_STONE_BRICKS = 98, + E_BLOCK_HUGE_BROWN_MUSHROOM = 99, + E_BLOCK_HUGE_RED_MUSHROOM = 100, + E_BLOCK_IRON_BAR = 101, + E_BLOCK_GLASS_PLANE = 102, + E_BLOCK_MELON = 103, + E_BLOCK_PUMPKIN_STEM = 104, + E_BLOCK_MELON_STEM = 105, + E_BLOCK_VINES = 106, + E_BLOCK_FENCE_GATE = 107, + E_BLOCK_BRICK_STAIRS = 108, + E_BLOCK_STONE_BRICK_STAIRS = 109, + E_BLOCK_MYCELIUM = 110, + E_BLOCK_LILY_PAD = 111, + E_BLOCK_NETHER_BRICK = 112, + E_BLOCK_NETHER_BRICK_FENCE = 113, + E_BLOCK_NETHER_BRICK_STAIRS = 114, + E_BLOCK_NETHER_WART = 115, + E_BLOCK_ENCHANTMENT_TABLE = 116, + E_BLOCK_BREWING_STAND = 117, + E_BLOCK_CAULDRON = 118, + E_BLOCK_END_PORTAL = 119, + E_BLOCK_END_PORTAL_FRAME = 120, + E_BLOCK_END_STONE = 121, + E_BLOCK_DRAGON_EGG = 122, + E_BLOCK_REDSTONE_LAMP_OFF = 123, + E_BLOCK_REDSTONE_LAMP_ON = 124, + E_BLOCK_DOUBLE_WOODEN_SLAB = 125, + E_BLOCK_WOODEN_SLAB = 126, + E_BLOCK_COCA_PLANT = 127, + E_BLOCK_SANDSTONE_STAIRS = 128, + E_BLOCK_EMERALD_ORE = 129, + E_BLOCK_ENDER_CHEST = 130, + E_BLOCK_TRIPWIRE_HOOK = 131, + E_BLOCK_TRIPWIRE = 132, + E_BLOCK_EMERALD_BLOCK = 133, + E_BLOCK_ = 121, +}; +//tolua_end + +//tolua_begin +enum ENUM_ITEM_ID +{ + E_ITEM_EMPTY = -1, + E_ITEM_STONE = 1, + E_ITEM_GRASS = 2, + E_ITEM_DIRT = 3, + E_ITEM_COBBLESTONE = 4, + E_ITEM_PLANKS = 5, + E_ITEM_WOOD = 5, // obsolete, use E_ITEM_PLANKS instead + E_ITEM_SAPLING = 6, + E_ITEM_BEDROCK = 7, + E_ITEM_WATER = 8, + E_ITEM_STATIONARY_WATER = 9, + E_ITEM_LAVA = 10, + E_ITEM_STATIONARY_LAVA = 11, + E_ITEM_SAND = 12, + E_ITEM_GRAVEL = 13, + E_ITEM_GOLD_ORE = 14, + E_ITEM_IRON_ORE = 15, + E_ITEM_COAL_ORE = 16, + E_ITEM_LOG = 17, + E_ITEM_LEAVES = 18, + E_ITEM_SPONGE = 19, + E_ITEM_GLASS = 20, + E_ITEM_LAPIS_ORE = 21, + E_ITEM_LAPIS_BLOCK = 22, + E_ITEM_DISPENSER = 23, + E_ITEM_SANDSTONE = 24, + E_ITEM_NOTE_ITEM = 25, + + E_ITEM_POWERED_RAIL = 27, + E_ITEM_DETECTOR_RAIL = 28, + E_ITEM_STICKY_PISTON = 29, + E_ITEM_COBWEB = 30, + E_ITEM_TALL_GRASS = 31, + E_ITEM_DEAD_BRUSH = 32, + E_ITEM_PISTON = 33, + E_ITEM_PISTON_EXTENSION = 34, + E_ITEM_WHITE_CLOTH = 35, + E_ITEM_PISTON_MOVED_BLOCK = 36, + E_ITEM_YELLOW_FLOWER = 37, + E_ITEM_RED_ROSE = 38, + E_ITEM_BROWN_MUSHROOM = 39, + E_ITEM_RED_MUSHROOM = 40, + E_ITEM_GOLD_BLOCK = 41, + E_ITEM_IRON_BLOCK = 42, + E_ITEM_DOUBLE_STONE_SLAB = 43, + E_ITEM_DOUBLE_STEP = 43, /// OBSOLETE, use E_ITEM_DOUBLE_STONE_SLAB + E_ITEM_STONE_SLAB = 44, + E_ITEM_STEP = 44, /// OBSOLETE, use E_ITEM_STONE_SLAB + E_ITEM_BRICK = 45, + E_ITEM_TNT = 46, + E_ITEM_BOOKCASE = 47, + E_ITEM_MOSSY_COBBLESTONE = 48, + E_ITEM_OBSIDIAN = 49, + E_ITEM_TORCH = 50, + E_ITEM_FIRE = 51, + E_ITEM_MOB_SPAWNER = 52, + E_ITEM_WOODEN_STAIRS = 53, + E_ITEM_CHEST = 54, + E_ITEM_REDSTONE_WIRE = 55, + E_ITEM_DIAMOND_ORE = 56, + E_ITEM_DIAMOND_BLOCK = 57, + E_ITEM_WORKBENCH = 58, + E_ITEM_CROPS = 59, + E_ITEM_SOIL = 60, + E_ITEM_FURNACE = 61, + E_ITEM_BURNING_FURNACE = 62, + E_ITEM_SIGN_POST = 63, + + E_ITEM_LADDER = 65, + E_ITEM_MINECART_TRACKS = 66, + E_ITEM_COBBLESTONE_STAIRS = 67, + E_ITEM_WALLSIGN = 68, + E_ITEM_LEVER = 69, + E_ITEM_STONE_PRESSURE_PLATE = 70, + + E_ITEM_WOODEN_PRESSURE_PLATE = 72, + E_ITEM_REDSTONE_ORE = 73, + E_ITEM_REDSTONE_ORE_GLOWING = 74, + E_ITEM_REDSTONE_TORCH_ON = 75, + E_ITEM_REDSTONE_TORCH_OFF = 76, + E_ITEM_STONE_BUTTON = 77, + E_ITEM_SNOW = 78, + E_ITEM_ICE = 79, + E_ITEM_SNOW_BLOCK = 80, + E_ITEM_CACTUS = 81, + + E_ITEM_REEDS = 83, + E_ITEM_JUKEBOX = 84, + E_ITEM_FENCE = 85, + E_ITEM_PUMPKIN = 86, + E_ITEM_BLOODSTONE = 87, + E_ITEM_SOULSAND = 88, + E_ITEM_GLOWSTONE = 89, + E_ITEM_PORT = 90, + E_ITEM_JACK_O_LANTERN = 91, + + E_ITEM_REDSTONE_REPEATER_OFF = 93, + E_ITEM_REDSTONE_REPEATER_ON = 94, + E_ITEM_LOCKED_CHEST = 95, + E_ITEM_TRAPDOOR = 96, + E_ITEM_SILVERFISH_EGG = 97, + E_ITEM_STONE_BRICKS = 98, + E_ITEM_HUGE_BROWN_MUSHROOM = 99, + E_ITEM_HUGE_RED_MUSHROOM = 100, + E_ITEM_IRON_BAR = 101, + E_ITEM_GLASS_PLANE = 102, + E_ITEM_MELON = 103, + E_ITEM_PUMPKIN_STEM = 104, + E_ITEM_MELON_STEM = 105, + E_ITEM_VINES = 106, + E_ITEM_FENCE_GATE = 107, + E_ITEM_BRICK_STAIRS = 108, + E_ITEM_STONE_BRICK_STAIRS = 109, + E_ITEM_MYCELIUM = 110, + E_ITEM_LILY_PAD = 111, + E_ITEM_NETHER_BRICK = 112, + E_ITEM_NETHER_BRICK_FENCE = 113, + E_ITEM_NETHER_BRICK_STAIRS = 114, + + E_ITEM_ENCHANTMENT_TABLE = 116, + + E_ITEM_END_PORTAL = 119, + E_ITEM_END_PORTAL_FRAME = 120, + E_ITEM_END_STONE = 121, + + E_ITEM_DOUBLE_WOODEN_SLAB = 125, + E_ITEM_WOODEN_SLAB = 126, + E_ITEM_COCA_PLANT = 127, + E_ITEM_SANDSTONE_STAIRS = 128, + E_ITEM_EMERALD_ORE = 129, + E_ITEM_ENDER_CHEST = 130, + E_ITEM_TRIPWIRE_HOOK = 131, + E_ITEM_TRIPWIRE = 132, + E_ITEM_EMERALD_BLOCK = 133, + + E_ITEM_IRON_SHOVEL = 256, + E_ITEM_IRON_PICKAXE = 257, + E_ITEM_IRON_AXE = 258, + E_ITEM_FLINT_AND_STEEL = 259, + E_ITEM_RED_APPLE = 260, + E_ITEM_APPLE = 260, // OBSOLETE, use E_ITEM_RED_APPLE instead + E_ITEM_BOW = 261, + E_ITEM_ARROW = 262, + E_ITEM_COAL = 263, + E_ITEM_DIAMOND = 264, + E_ITEM_IRON = 265, + E_ITEM_GOLD = 266, + E_ITEM_IRON_SWORD = 267, + E_ITEM_WOODEN_SWORD = 268, + E_ITEM_WOODEN_SHOVEL = 269, + E_ITEM_WOODEN_PICKAXE = 270, + E_ITEM_WOODEN_AXE = 271, + E_ITEM_STONE_SWORD = 272, + E_ITEM_STONE_SHOVEL = 273, + E_ITEM_STONE_PICKAXE = 274, + E_ITEM_STONE_AXE = 275, + E_ITEM_DIAMOND_SWORD = 276, + E_ITEM_DIAMOND_SHOVEL = 277, + E_ITEM_DIAMOND_PICKAXE = 278, + E_ITEM_DIAMOND_AXE = 279, + E_ITEM_STICK = 280, + E_ITEM_BOWL = 281, + E_ITEM_MUSHROOM_SOUP = 282, + E_ITEM_GOLD_SWORD = 283, + E_ITEM_GOLD_SHOVEL = 284, + E_ITEM_GOLD_PICKAXE = 285, + E_ITEM_GOLD_AXE = 286, + E_ITEM_STRING = 287, + E_ITEM_FEATHER = 288, + E_ITEM_GUNPOWDER = 289, + E_ITEM_WOODEN_HOE = 290, + E_ITEM_STONE_HOE = 291, + E_ITEM_IRON_HOE = 292, + E_ITEM_DIAMOND_HOE = 293, + E_ITEM_GOLD_HOE = 294, + E_ITEM_SEEDS = 295, + E_ITEM_WHEAT = 296, + E_ITEM_BREAD = 297, + E_ITEM_LEATHER_CAP = 298, + E_ITEM_LEATHER_TUNIC = 299, + E_ITEM_LEATHER_PANTS = 300, + E_ITEM_LEATHER_BOOTS = 301, + E_ITEM_CHAIN_HELMET = 302, + E_ITEM_CHAIN_CHESTPLATE = 303, + E_ITEM_CHAIN_LEGGINGS = 304, + E_ITEM_CHAIN_BOOTS = 305, + E_ITEM_IRON_HELMET = 306, + E_ITEM_IRON_CHESTPLATE = 307, + E_ITEM_IRON_LEGGINGS = 308, + E_ITEM_IRON_BOOTS = 309, + E_ITEM_DIAMOND_HELMET = 310, + E_ITEM_DIAMOND_CHESTPLATE = 311, + E_ITEM_DIAMOND_LEGGINGS = 312, + E_ITEM_DIAMOND_BOOTS = 313, + E_ITEM_GOLD_HELMET = 314, + E_ITEM_GOLD_CHESTPLATE = 315, + E_ITEM_GOLD_LEGGINGS = 316, + E_ITEM_GOLD_BOOTS = 317, + E_ITEM_FLINT = 318, + E_ITEM_RAW_MEAT = 319, + E_ITEM_COOKED_MEAT = 320, + E_ITEM_PAINTINGS = 321, + E_ITEM_GOLDEN_APPLE = 322, + E_ITEM_SIGN = 323, + E_ITEM_WOODEN_DOOR = 324, + E_ITEM_BUCKET = 325, + E_ITEM_WATER_BUCKET = 326, + E_ITEM_LAVA_BUCKET = 327, + E_ITEM_MINECART = 328, + E_ITEM_SADDLE = 329, + E_ITEM_IRON_DOOR = 330, + E_ITEM_REDSTONE_DUST = 331, + E_ITEM_SNOWBALL = 332, + E_ITEM_BOAT = 333, + E_ITEM_LEATHER = 334, + E_ITEM_MILK = 335, + E_ITEM_CLAY_BRICK = 336, + E_ITEM_CLAY = 337, + E_ITEM_SUGARCANE = 338, + E_ITEM_SUGAR_CANE = 338, + E_ITEM_PAPER = 339, + E_ITEM_BOOK = 340, + E_ITEM_SLIMEBALL = 341, + E_ITEM_CHEST_MINECART = 342, + E_ITEM_FURNACE_MINECART = 343, + E_ITEM_EGG = 344, + E_ITEM_COMPASS = 345, + E_ITEM_FISHING_ROD = 346, + E_ITEM_CLOCK = 347, + E_ITEM_GLOWSTONE_DUST = 348, + E_ITEM_RAW_FISH = 349, + E_ITEM_COOKED_FISH = 350, + E_ITEM_DYE = 351, + E_ITEM_BONE = 352, + E_ITEM_SUGAR = 353, + E_ITEM_CAKE = 354, + E_ITEM_BED = 355, + E_ITEM_REDSTONE_REPEATER = 356, + E_ITEM_COOKIE = 357, + E_ITEM_MAP = 358, + E_ITEM_SHEARS = 359, + E_ITEM_MELON_SLICE = 360, + E_ITEM_PUMPKIN_SEEDS = 361, + E_ITEM_MELON_SEEDS = 362, + E_ITEM_RAW_BEEF = 363, + E_ITEM_STEAK = 364, + E_ITEM_RAW_CHICKEN = 365, + E_ITEM_COOKED_CHICKEN = 366, + E_ITEM_ROTTEN_FLESH = 367, + E_ITEM_ENDER_PEARL = 368, + E_ITEM_BLAZE_ROD = 369, + E_ITEM_GHAST_TEAR = 370, + E_ITEM_GOLD_NUGGET = 371, + E_ITEM_NETHER_WART = 372, + E_ITEM_POTIONS = 373, + E_ITEM_GLASS_BOTTLE = 374, + E_ITEM_SPIDER_EYE = 375, + E_ITEM_FERMENTED_SPIDER_EYE = 376, + E_ITEM_BLAZE_POWDER = 377, + E_ITEM_MAGMA_CREAM = 378, + E_ITEM_BREWING_STAND = 379, + E_ITEM_CAULDRON = 380, + E_ITEM_EYE_OF_ENDER = 381, + E_ITEM_GLISTERING_MELON = 382, + + E_ITEM_SPAWN_EGG = 383, + E_ITEM_BOTTLE_O_ENCHANTING = 384, + E_ITEM_FIRE_CHARGE = 385, + E_ITEM_BOOK_AND_QUILL = 386, + E_ITEM_WRITTEN_BOOK = 387, + E_ITEM_EMERALD = 388, + + E_ITEM_13_DISC = 2256, + E_ITEM_CAT_DISC = 2257, + E_ITEM_BLOCKS_DISC = 2258, + E_ITEM_CHIRP_DISC = 2259, + E_ITEM_FAR_DISC = 2260, + E_ITEM_MALL_DISC = 2261, + E_ITEM_MELLOHI_DISC = 2262, + E_ITEM_STAL_DISC = 2263, + E_ITEM_STRAD_DISC = 2264, + E_ITEM_WARD_DISC = 2265, + E_ITEM_11_DISC = 2266, +}; + + + + + +enum +{ + // E_BLOCK_PLANKS metas: + E_META_PLANKS_APPLE = 0, + E_META_PLANKS_CONIFER = 1, + E_META_PLANKS_BIRCH = 2, + E_META_PLANKS_JUNGLE = 3, + + // E_BLOCK_LOG metas: + E_META_LOG_APPLE = 0, + E_META_LOG_CONIFER = 1, + E_META_LOG_BIRCH = 2, + E_META_LOG_JUNGLE = 3, + + // E_BLOCK_LEAVES metas: + E_META_LEAVES_APPLE = 0, + E_META_LEAVES_CONIFER = 1, + E_META_LEAVES_BIRCH = 2, + E_META_LEAVES_JUNGLE = 3, + + // E_BLOCK_SAPLING metas (lowest 3 bits): + E_META_SAPLING_APPLE = 0, + E_META_SAPLING_CONIFER = 1, + E_META_SAPLING_BIRCH = 2, + E_META_SAPLING_JUNGLE = 3, + + // E_BLOCK_TALL_GRASS metas: + E_META_TALL_GRASS_DEAD_SHRUB = 0, + E_META_TALL_GRASS_GRASS = 1, + E_META_TALL_GRASS_FERN = 2, + + // E_BLOCK_SANDSTONE metas: + E_META_SANDSTONE_NORMAL = 0, + E_META_SANDSTONE_ORNAMENT = 1, + E_META_SANDSTONE_SMOOTH = 2, + + // E_BLOCK_WOOL metas: + E_META_WOOL_WHITE = 0, + E_META_WOOL_ORANGE = 1, + E_META_WOOL_MAGENTA = 2, + E_META_WOOL_LIGHTBLUE = 3, + E_META_WOOL_YELLOW = 4, + E_META_WOOL_LIGHTGREEN = 5, + E_META_WOOL_PINK = 6, + E_META_WOOL_GRAY = 7, + E_META_WOOL_LIGHTGRAY = 8, + E_META_WOOL_CYAN = 9, + E_META_WOOL_PURPLE = 10, + E_META_WOOL_BLUE = 11, + E_META_WOOL_BROWN = 12, + E_META_WOOL_GREEN = 13, + E_META_WOOL_RED = 14, + E_META_WOOL_BLACK = 15, + + // E_BLOCK_DOUBLE_STEP metas: + E_META_DOUBLE_STEP_STONE = 0, + E_META_DOUBLE_STEP_SANDSTONE = 1, + E_META_DOUBLE_STEP_WOODEN = 2, + E_META_DOUBLE_STEP_COBBLESTONE = 3, + E_META_DOUBLE_STEP_BRICK = 4, + E_META_DOUBLE_STEP_STONE_BRICK = 5, + E_META_DOUBLE_STEP_STONE_SECRET = 6, + + // E_BLOCK_STEP metas: + E_META_STEP_STONE = 0, + E_META_STEP_SANDSTONE = 1, + E_META_STEP_PLANKS = 2, + E_META_STEP_COBBLESTONE = 3, + E_META_STEP_BRICK = 4, + E_META_STEP_STONE_BRICK = 5, + E_META_STEP_STONE_SECRET = 6, + + // E_BLOCK_SILVERFISH_EGG metas: + E_META_SILVERFISH_EGG_STONE = 0, + E_META_SILVERFISH_EGG_COBBLESTONE = 1, + E_META_SILVERFISH_EGG_STONE_BRICK = 2, + + // E_BLOCK_STONE_BRICKS metas: + E_META_STONE_BRICK_NORMAL = 0, + E_META_STONE_BRICK_MOSSY = 1, + E_META_STONE_BRICK_CRACKED = 2, + E_META_STONE_BRICK_ORNAMENT = 3, + + // E_BLOCK_WOODEN_DOUBLE_STEP metas: + E_BLOCK_WOODEN_DOUBLE_STEP_APPLE = 0, + E_BLOCK_WOODEN_DOUBLE_STEP_CONIFER = 1, + E_BLOCK_WOODEN_DOUBLE_STEP_BIRCH = 2, + E_BLOCK_WOODEN_DOUBLE_STEP_JUNGLE = 3, + + // E_BLOCK_WOODEN_STEP metas: + E_BLOCK_WOODEN_STEP_APPLE = 0, + E_BLOCK_WOODEN_STEP_CONIFER = 1, + E_BLOCK_WOODEN_STEP_BIRCH = 2, + E_BLOCK_WOODEN_STEP_JUNGLE = 3, +} ; + + + + + + + +enum +{ + // E_ITEM_COAL metas: + E_META_COAL_NORMAL = 0, + E_META_COAL_CHARCOAL = 1, + + // E_ITEM_GOLDEN_APPLE metas: + E_META_GOLDEN_APPLE_NORMAL = 0, + E_META_GOLDEN_APPLE_ENCHANTED = 1, + + // E_ITEM_DYE metas: + E_META_DYE_BLACK = 0, + E_META_DYE_RED = 1, + E_META_DYE_GREEN = 2, + E_META_DYE_BROWN = 3, + E_META_DYE_BLUE = 4, + E_META_DYE_PURPLE = 5, + E_META_DYE_CYAN = 6, + E_META_DYE_LIGHTGRAY = 7, + E_META_DYE_GRAY = 8, + E_META_DYE_PINK = 9, + E_META_DYE_LIGHTGREEN = 10, + E_META_DYE_YELLOW = 11, + E_META_DYE_LIGHTBLUE = 12, + E_META_DYE_MAGENTA = 13, + E_META_DYE_ORANGE = 14, + E_META_DYE_WHITE = 15, + + // E_ITEM_SPAWN_EGG spawn EntityIDs: + // hostile: + E_META_SPAWN_EGG_CREEPER = 50, + E_META_SPAWN_EGG_SKELETON = 51, + E_META_SPAWN_EGG_SPIDER = 52, + E_META_SPAWN_EGG_ZOMBIE = 54, + E_META_SPAWN_EGG_SLIME = 55, + E_META_SPAWN_EGG_GHAST = 56, + E_META_SPAWN_EGG_ZOMBIE_PIGMAN = 57, + E_META_SPAWN_EGG_ENDERMAN = 58, + E_META_SPAWN_EGG_CAVE_SPIDER = 59, + E_META_SPAWN_EGG_SILVERFISH = 60, + E_META_SPAWN_EGG_BLAZE = 61, + E_META_SPAWN_EGG_MAGMA_CUBE = 62, + E_META_SPAWN_EGG_GIANT = 53, + E_META_SPAWN_EGG_ENDER_DRAGON = 63, + E_META_SPAWN_EGG_PIG = 90, + E_META_SPAWN_EGG_SHEEP = 91, + E_META_SPAWN_EGG_COW = 92, + E_META_SPAWN_EGG_CHICKEN = 93, + E_META_SPAWN_EGG_SQUID = 94, + E_META_SPAWN_EGG_WOLF = 95, + E_META_SPAWN_EGG_MOOSHROOM = 96, + E_META_SPAWN_EGG_OCELOT = 98, + E_META_SPAWN_EGG_VILLAGER = 120, + E_META_SPAWN_EGG_SNOW_GOLEM = 97, + E_META_SPAWN_EGG_IRON_GOLEM = 99, +} ; +//tolua_end + + + + +// fwd: cItem.h: +class cItem; + + + + + +/// Translates a blocktype string into blocktype. Takes either a number or an items.ini alias as input. Returns -1 on failure. +extern int BlockStringToType(const AString & a_BlockTypeString); // tolua_export + +/// Translates an itemtype string into an item. Takes either a number, number^number, number:number or an items.ini alias as input. Returns true if successful. +extern bool StringToItem(const AString & a_ItemTypeString, cItem & a_Item); // tolua_export + +/// Translates a biome string to biome enum. Takes either a number or a biome alias (built-in). Returns -1 on failure. +extern EMCSBiome StringToBiome(const AString & a_BiomeString); + + + + + +// Block properties: +extern NIBBLETYPE g_BlockLightValue[256]; +extern NIBBLETYPE g_BlockSpreadLightFalloff[256]; +extern bool g_BlockTransparent[256]; +extern bool g_BlockOneHitDig[256]; +extern bool g_BlockPistonBreakable[256]; +extern bool g_BlockIsSnowable[256]; + + + + + diff --git a/source/ChunkDef.h b/source/ChunkDef.h index 5bafde4af..2aaaa5288 100644 --- a/source/ChunkDef.h +++ b/source/ChunkDef.h @@ -1,492 +1,492 @@ - -// ChunkDef.h - -// Interfaces to helper types for chunk definitions. Most modules want to include this instead of cChunk.h - - - - - -#pragma once - -#include "Vector3i.h" - - - - - -/** This is really only a placeholder to be used in places where we need to "make up" a chunk's Y coord. -It will help us when the new chunk format comes out and we need to patch everything up for compatibility. -*/ -#define ZERO_CHUNK_Y 0 - -// Used to smoothly convert to new axis ordering. One will be removed when deemed stable. -#define AXIS_ORDER_YZX 1 // Original (1.1-) -#define AXIS_ORDER_XZY 2 // New (1.2+) -#define AXIS_ORDER AXIS_ORDER_XZY - - - - - -// fwd -class cBlockEntity; -class cEntity; -class cClientHandle; -class cBlockEntity; - -typedef std::list cEntityList; -typedef std::list cBlockEntityList; - - - - -/// The datatype used by blockdata -typedef char BLOCKTYPE; - -/// The datatype used by nibbledata (meta, light, skylight) -typedef unsigned char NIBBLETYPE; - -/// The type used by the heightmap -typedef unsigned char HEIGHTTYPE; - - - - - -/** Biome IDs -The first batch corresponds to the clientside biomes, used by MineCraft. -BiomeIDs over 255 are used by MCServer internally and are translated to MC biomes before sending them to client -*/ -enum EMCSBiome -{ - biOcean = 0, - biPlains = 1, - biDesert = 2, - biExtremeHills = 3, - biForest = 4, - biTaiga = 5, - biSwampland = 6, - biRiver = 7, - biHell = 8, // same as Nether - biNether = 8, - biSky = 9, - biFrozenOcean = 10, - biFrozenRiver = 11, - biIcePlains = 12, - biTundra = 12, // same as Ice Plains - biIceMountains = 13, - biMushroomIsland = 14, - biMushroomShore = 15, - biBeach = 16, - biDesertHills = 17, - biForestHills = 18, - biTaigaHills = 19, - biExtremeHillsEdge = 20, - biJungle = 21, - biJungleHills = 22, - - // Automatically capture the maximum biome value into biMaxBiome: - biNumBiomes, // True number of biomes, since they are zero-based - biMaxBiome = biNumBiomes - 1, // The maximum biome value -} ; - - - - - -/// Constants used throughout the code, useful typedefs and utility functions -class cChunkDef -{ -public: - static const int Width = 16; - static const int Height = 256; - static const int NumBlocks = Width * Height * Width; - static const int BlockDataSize = NumBlocks * 2 + (NumBlocks / 2); // 2.5 * numblocks - - // Offsets to individual components in the joined blockdata array - static const int MetaOffset = NumBlocks; - static const int LightOffset = MetaOffset + NumBlocks / 2; - static const int SkyLightOffset = LightOffset + NumBlocks / 2; - - static const unsigned int INDEX_OUT_OF_RANGE = 0xffffffff; - - /// The type used for any heightmap operations and storage; idx = x + Width * z - typedef HEIGHTTYPE HeightMap[Width * Width]; - - /** The type used for any biomemap operations and storage inside MCServer, - using MCServer biomes (need not correspond to client representation!) - idx = x + Width * z // Need to verify this with the protocol spec, currently unknown! - */ - typedef EMCSBiome BiomeMap[Width * Width]; - - /// The type used for block type operations and storage, AXIS_ORDER ordering - typedef BLOCKTYPE BlockTypes[NumBlocks]; - - /// The type used for block data in nibble format, AXIS_ORDER ordering - typedef NIBBLETYPE BlockNibbles[NumBlocks / 2]; - - - /// Converts absolute block coords into relative (chunk + block) coords: - inline static void AbsoluteToRelative(/* in-out */ int & a_X, int & a_Y, int & a_Z, /* out */ int & a_ChunkX, int & a_ChunkZ ) - { - BlockToChunk(a_X, a_Y, a_Z, a_ChunkX, a_ChunkZ); - - a_X = a_X - a_ChunkX * Width; - a_Z = a_Z - a_ChunkZ * Width; - } - - - /// Converts absolute block coords to chunk coords: - inline static void BlockToChunk( int a_X, int a_Y, int a_Z, int & a_ChunkX, int & a_ChunkZ ) - { - (void)a_Y; - a_ChunkX = a_X / Width; - if ((a_X < 0) && (a_X % Width != 0)) - { - a_ChunkX--; - } - a_ChunkZ = a_Z / cChunkDef::Width; - if ((a_Z < 0) && (a_Z % Width != 0)) - { - a_ChunkZ--; - } - } - - - inline static unsigned int MakeIndex(int x, int y, int z ) - { - if( x < cChunkDef::Width && x > -1 && y < cChunkDef::Height && y > -1 && z < cChunkDef::Width && z > -1 ) - { - return MakeIndexNoCheck(x, y, z); - } - return INDEX_OUT_OF_RANGE; - } - - - inline static unsigned int MakeIndexNoCheck(int x, int y, int z) - { - #if AXIS_ORDER == AXIS_ORDER_XZY - // For some reason, NOT using the Horner schema is faster. Weird. - return x + (z * cChunkDef::Width) + (y * cChunkDef::Width * cChunkDef::Width); // 1.2 is XZY - #elif AXIS_ORDER == AXIS_ORDER_YZX - return y + (z * cChunkDef::Width) + (x * cChunkDef::Height * cChunkDef::Width); // 1.1 is YZX - #endif - } - - - inline static Vector3i IndexToCoordinate( unsigned int index ) - { - #if AXIS_ORDER == AXIS_ORDER_XZY - return Vector3i( // 1.2 - index % cChunkDef::Width, // X - index / (cChunkDef::Width * cChunkDef::Width), // Y - (index / cChunkDef::Width) % cChunkDef::Width // Z - ); - #elif AXIS_ORDER == AXIS_ORDER_YZX - return Vector3i( // 1.1 - index / (cChunkDef::Height * cChunkDef::Width), // X - index % cChunkDef::Height, // Y - (index / cChunkDef::Height) % cChunkDef::Width // Z - ); - #endif - } - - - inline static void SetBlock(BLOCKTYPE * a_BlockTypes, int a_X, int a_Y, int a_Z, BLOCKTYPE a_Type) - { - ASSERT((a_X >= 0) && (a_X < Width)); - ASSERT((a_Y >= 0) && (a_Y < Height)); - ASSERT((a_Z >= 0) && (a_Z < Width)); - a_BlockTypes[MakeIndexNoCheck(a_X, a_Y, a_Z)] = a_Type; - } - - - inline static BLOCKTYPE GetBlock(BLOCKTYPE * a_BlockTypes, int a_X, int a_Y, int a_Z) - { - ASSERT((a_X >= 0) && (a_X < Width)); - ASSERT((a_Y >= 0) && (a_Y < Height)); - ASSERT((a_Z >= 0) && (a_Z < Width)); - return a_BlockTypes[MakeIndexNoCheck(a_X, a_Y, a_Z)]; - } - - - inline static int GetHeight(const HeightMap & a_HeightMap, int a_X, int a_Z) - { - return a_HeightMap[a_X + Width * a_Z]; - } - - - inline static void SetHeight(HeightMap & a_HeightMap, int a_X, int a_Z, unsigned char a_Height) - { - a_HeightMap[a_X + Width * a_Z] = a_Height; - } - - - inline static EMCSBiome GetBiome(const BiomeMap & a_BiomeMap, int a_X, int a_Z) - { - return a_BiomeMap[a_X + Width * a_Z]; - } - - - inline static void SetBiome(BiomeMap & a_BiomeMap, int a_X, int a_Z, EMCSBiome a_Biome) - { - a_BiomeMap[a_X + Width * a_Z] = a_Biome; - } - - - static NIBBLETYPE GetNibble(NIBBLETYPE * a_Buffer, int a_BlockIdx) - { - if ((a_BlockIdx > -1) && (a_BlockIdx < cChunkDef::NumBlocks)) - { - return (a_Buffer[a_BlockIdx / 2] >> ((a_BlockIdx & 1) * 4)) & 0x0f; - } - return 0; - } - - - static NIBBLETYPE GetNibble(NIBBLETYPE * a_Buffer, int x, int y, int z) - { - if ((x < Width) && (x > -1) && (y < Height) && (y > -1) && (z < Width) && (z > -1)) - { - int Index = MakeIndexNoCheck(x, y, z); - return (a_Buffer[Index / 2] >> ((Index & 1) * 4)) & 0x0f; - } - return 0; - } - - - static void SetNibble(NIBBLETYPE * a_Buffer, int a_BlockIdx, NIBBLETYPE a_Nibble) - { - if ((a_BlockIdx > -1) && (a_BlockIdx < cChunkDef::NumBlocks)) - { - a_Buffer[a_BlockIdx / 2] = ( - (a_Buffer[a_BlockIdx / 2] & (0xf0 >> ((a_BlockIdx & 1) * 4))) | // The untouched nibble - ((a_Nibble & 0x0f) << ((a_BlockIdx & 1) * 4)) // The nibble being set - ); - } - } - - - static void SetNibble(NIBBLETYPE * a_Buffer, int x, int y, int z, NIBBLETYPE a_Nibble) - { - if ((x < cChunkDef::Width) && (x > -1) && (y < cChunkDef::Height) && (y > -1) && (z < cChunkDef::Width) && (z > -1)) - { - int Index = MakeIndexNoCheck(x, y, z); - a_Buffer[Index / 2] = ( - (a_Buffer[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble - ((a_Nibble & 0x0f) << ((Index & 1) * 4)) // The nibble being set - ); - } - } - - - inline static char GetNibble(NIBBLETYPE * a_Buffer, const Vector3i & a_BlockPos ) - { - return GetNibble( a_Buffer, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z ); - } - - - inline static void SetNibble(NIBBLETYPE * a_Buffer, const Vector3i & a_BlockPos, char a_Value ) - { - SetNibble( a_Buffer, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, a_Value ); - } - -} ; - - - - - -/** Interface class used for getting data out of a chunk using the GetAllData() function. -Implementation must use the pointers immediately and NOT store any of them for later use -The virtual methods are called in the same order as they're declared here. -*/ -class cChunkDataCallback abstract -{ -public: - /// Called once to provide heightmap data - virtual void HeightMap(const cChunkDef::HeightMap * a_HeightMap) {}; - - /// Called once to provide biome data - virtual void BiomeData (const cChunkDef::BiomeMap * a_BiomeMap) {}; - - /// Called once to export block types - virtual void BlockTypes (const BLOCKTYPE * a_Type) {}; - - /// Called once to export block meta - virtual void BlockMeta (const NIBBLETYPE * a_Meta) {}; - - /// Called once to let know if the chunk lighting is valid. Return value is used to control if BlockLight() and BlockSkyLight() are called next - virtual bool LightIsValid(bool a_IsLightValid) {return true; }; - - /// Called once to export block light - virtual void BlockLight (const NIBBLETYPE * a_Meta) {}; - - /// Called once to export sky light - virtual void BlockSkyLight(const NIBBLETYPE * a_Meta) {}; - - /// Called for each entity in the chunk - virtual void Entity(cEntity * a_Entity) {}; - - /// Called for each blockentity in the chunk - virtual void BlockEntity(cBlockEntity * a_Entity) {}; -} ; - - - - - -/** A simple implementation of the cChunkDataCallback interface that collects all block data into a single buffer -*/ -class cChunkDataCollector : - public cChunkDataCallback -{ -public: - - // Must be char instead of BLOCKTYPE or NIBBLETYPE, because it houses both. - char m_BlockData[cChunkDef::BlockDataSize]; - -protected: - - virtual void BlockTypes(const BLOCKTYPE * a_BlockTypes) override - { - memcpy(m_BlockData, a_BlockTypes, sizeof(cChunkDef::BlockTypes)); - } - - - virtual void BlockMeta(const NIBBLETYPE * a_BlockMeta) override - { - memcpy(m_BlockData + cChunkDef::NumBlocks, a_BlockMeta, cChunkDef::NumBlocks / 2); - } - - - virtual void BlockLight(const NIBBLETYPE * a_BlockLight) override - { - memcpy(m_BlockData + 3 * cChunkDef::NumBlocks / 2, a_BlockLight, cChunkDef::NumBlocks / 2); - } - - - virtual void BlockSkyLight(const NIBBLETYPE * a_BlockSkyLight) override - { - memcpy(m_BlockData + 2 * cChunkDef::NumBlocks, a_BlockSkyLight, cChunkDef::NumBlocks / 2); - } -} ; - - - - - -/** A simple implementation of the cChunkDataCallback interface that collects all block data into a separate buffers -*/ -class cChunkDataSeparateCollector : - public cChunkDataCallback -{ -public: - - cChunkDef::BlockTypes m_BlockTypes; - cChunkDef::BlockNibbles m_BlockMetas; - cChunkDef::BlockNibbles m_BlockLight; - cChunkDef::BlockNibbles m_BlockSkyLight; - -protected: - - virtual void BlockTypes(const BLOCKTYPE * a_BlockTypes) override - { - memcpy(m_BlockTypes, a_BlockTypes, sizeof(m_BlockTypes)); - } - - - virtual void BlockMeta(const NIBBLETYPE * a_BlockMeta) override - { - memcpy(m_BlockMetas, a_BlockMeta, sizeof(m_BlockMetas)); - } - - - virtual void BlockLight(const NIBBLETYPE * a_BlockLight) override - { - memcpy(m_BlockLight, a_BlockLight, sizeof(m_BlockLight)); - } - - - virtual void BlockSkyLight(const NIBBLETYPE * a_BlockSkyLight) override - { - memcpy(m_BlockSkyLight, a_BlockSkyLight, sizeof(m_BlockSkyLight)); - } -} ; - - - - - -/** Interface class used for comparing clients of two chunks. -Used primarily for entity moving while both chunks are locked. -*/ -class cClientDiffCallback -{ -public: - /// Called for clients that are in Chunk1 and not in Chunk2, - virtual void Removed(cClientHandle * a_Client) = 0; - - /// Called for clients that are in Chunk2 and not in Chunk1. - virtual void Added(cClientHandle * a_Client) = 0; -} ; - - - - - -struct sSetBlock -{ - int x, y, z; - int ChunkX, ChunkZ; - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - - sSetBlock( int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ); // absolute block position - sSetBlock(int a_ChunkX, int a_ChunkZ, int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) : - ChunkX(a_ChunkX), ChunkZ(a_ChunkZ), - x(a_X), y(a_Y), z(a_Z), - BlockType(a_BlockType), - BlockMeta(a_BlockMeta) - {} -}; - -typedef std::list sSetBlockList; -typedef std::vector sSetBlockVector; - - - - - -class cChunkCoords -{ -public: - int m_ChunkX; - int m_ChunkY; - int m_ChunkZ; - - cChunkCoords(int a_ChunkX, int a_ChunkY, int a_ChunkZ) : m_ChunkX(a_ChunkX), m_ChunkY(a_ChunkY), m_ChunkZ(a_ChunkZ) {} - - bool operator == (const cChunkCoords & a_Other) const - { - return ((m_ChunkX == a_Other.m_ChunkX) && (m_ChunkY == a_Other.m_ChunkY) && (m_ChunkZ == a_Other.m_ChunkZ)); - } -} ; - -typedef std::list cChunkCoordsList; - - - - - -/// Interface class used as a callback for operations that involve chunk coords -class cChunkCoordCallback -{ -public: - virtual void Call(int a_ChunkX, int a_ChunkZ) = 0; -} ; - - - - + +// ChunkDef.h + +// Interfaces to helper types for chunk definitions. Most modules want to include this instead of cChunk.h + + + + + +#pragma once + +#include "Vector3i.h" + + + + + +/** This is really only a placeholder to be used in places where we need to "make up" a chunk's Y coord. +It will help us when the new chunk format comes out and we need to patch everything up for compatibility. +*/ +#define ZERO_CHUNK_Y 0 + +// Used to smoothly convert to new axis ordering. One will be removed when deemed stable. +#define AXIS_ORDER_YZX 1 // Original (1.1-) +#define AXIS_ORDER_XZY 2 // New (1.2+) +#define AXIS_ORDER AXIS_ORDER_XZY + + + + + +// fwd +class cBlockEntity; +class cEntity; +class cClientHandle; +class cBlockEntity; + +typedef std::list cEntityList; +typedef std::list cBlockEntityList; + + + + +/// The datatype used by blockdata +typedef char BLOCKTYPE; + +/// The datatype used by nibbledata (meta, light, skylight) +typedef unsigned char NIBBLETYPE; + +/// The type used by the heightmap +typedef unsigned char HEIGHTTYPE; + + + + + +/** Biome IDs +The first batch corresponds to the clientside biomes, used by MineCraft. +BiomeIDs over 255 are used by MCServer internally and are translated to MC biomes before sending them to client +*/ +enum EMCSBiome +{ + biOcean = 0, + biPlains = 1, + biDesert = 2, + biExtremeHills = 3, + biForest = 4, + biTaiga = 5, + biSwampland = 6, + biRiver = 7, + biHell = 8, // same as Nether + biNether = 8, + biSky = 9, + biFrozenOcean = 10, + biFrozenRiver = 11, + biIcePlains = 12, + biTundra = 12, // same as Ice Plains + biIceMountains = 13, + biMushroomIsland = 14, + biMushroomShore = 15, + biBeach = 16, + biDesertHills = 17, + biForestHills = 18, + biTaigaHills = 19, + biExtremeHillsEdge = 20, + biJungle = 21, + biJungleHills = 22, + + // Automatically capture the maximum biome value into biMaxBiome: + biNumBiomes, // True number of biomes, since they are zero-based + biMaxBiome = biNumBiomes - 1, // The maximum biome value +} ; + + + + + +/// Constants used throughout the code, useful typedefs and utility functions +class cChunkDef +{ +public: + static const int Width = 16; + static const int Height = 256; + static const int NumBlocks = Width * Height * Width; + static const int BlockDataSize = NumBlocks * 2 + (NumBlocks / 2); // 2.5 * numblocks + + // Offsets to individual components in the joined blockdata array + static const int MetaOffset = NumBlocks; + static const int LightOffset = MetaOffset + NumBlocks / 2; + static const int SkyLightOffset = LightOffset + NumBlocks / 2; + + static const unsigned int INDEX_OUT_OF_RANGE = 0xffffffff; + + /// The type used for any heightmap operations and storage; idx = x + Width * z + typedef HEIGHTTYPE HeightMap[Width * Width]; + + /** The type used for any biomemap operations and storage inside MCServer, + using MCServer biomes (need not correspond to client representation!) + idx = x + Width * z // Need to verify this with the protocol spec, currently unknown! + */ + typedef EMCSBiome BiomeMap[Width * Width]; + + /// The type used for block type operations and storage, AXIS_ORDER ordering + typedef BLOCKTYPE BlockTypes[NumBlocks]; + + /// The type used for block data in nibble format, AXIS_ORDER ordering + typedef NIBBLETYPE BlockNibbles[NumBlocks / 2]; + + + /// Converts absolute block coords into relative (chunk + block) coords: + inline static void AbsoluteToRelative(/* in-out */ int & a_X, int & a_Y, int & a_Z, /* out */ int & a_ChunkX, int & a_ChunkZ ) + { + BlockToChunk(a_X, a_Y, a_Z, a_ChunkX, a_ChunkZ); + + a_X = a_X - a_ChunkX * Width; + a_Z = a_Z - a_ChunkZ * Width; + } + + + /// Converts absolute block coords to chunk coords: + inline static void BlockToChunk( int a_X, int a_Y, int a_Z, int & a_ChunkX, int & a_ChunkZ ) + { + (void)a_Y; + a_ChunkX = a_X / Width; + if ((a_X < 0) && (a_X % Width != 0)) + { + a_ChunkX--; + } + a_ChunkZ = a_Z / cChunkDef::Width; + if ((a_Z < 0) && (a_Z % Width != 0)) + { + a_ChunkZ--; + } + } + + + inline static unsigned int MakeIndex(int x, int y, int z ) + { + if( x < cChunkDef::Width && x > -1 && y < cChunkDef::Height && y > -1 && z < cChunkDef::Width && z > -1 ) + { + return MakeIndexNoCheck(x, y, z); + } + return INDEX_OUT_OF_RANGE; + } + + + inline static unsigned int MakeIndexNoCheck(int x, int y, int z) + { + #if AXIS_ORDER == AXIS_ORDER_XZY + // For some reason, NOT using the Horner schema is faster. Weird. + return x + (z * cChunkDef::Width) + (y * cChunkDef::Width * cChunkDef::Width); // 1.2 is XZY + #elif AXIS_ORDER == AXIS_ORDER_YZX + return y + (z * cChunkDef::Width) + (x * cChunkDef::Height * cChunkDef::Width); // 1.1 is YZX + #endif + } + + + inline static Vector3i IndexToCoordinate( unsigned int index ) + { + #if AXIS_ORDER == AXIS_ORDER_XZY + return Vector3i( // 1.2 + index % cChunkDef::Width, // X + index / (cChunkDef::Width * cChunkDef::Width), // Y + (index / cChunkDef::Width) % cChunkDef::Width // Z + ); + #elif AXIS_ORDER == AXIS_ORDER_YZX + return Vector3i( // 1.1 + index / (cChunkDef::Height * cChunkDef::Width), // X + index % cChunkDef::Height, // Y + (index / cChunkDef::Height) % cChunkDef::Width // Z + ); + #endif + } + + + inline static void SetBlock(BLOCKTYPE * a_BlockTypes, int a_X, int a_Y, int a_Z, BLOCKTYPE a_Type) + { + ASSERT((a_X >= 0) && (a_X < Width)); + ASSERT((a_Y >= 0) && (a_Y < Height)); + ASSERT((a_Z >= 0) && (a_Z < Width)); + a_BlockTypes[MakeIndexNoCheck(a_X, a_Y, a_Z)] = a_Type; + } + + + inline static BLOCKTYPE GetBlock(BLOCKTYPE * a_BlockTypes, int a_X, int a_Y, int a_Z) + { + ASSERT((a_X >= 0) && (a_X < Width)); + ASSERT((a_Y >= 0) && (a_Y < Height)); + ASSERT((a_Z >= 0) && (a_Z < Width)); + return a_BlockTypes[MakeIndexNoCheck(a_X, a_Y, a_Z)]; + } + + + inline static int GetHeight(const HeightMap & a_HeightMap, int a_X, int a_Z) + { + return a_HeightMap[a_X + Width * a_Z]; + } + + + inline static void SetHeight(HeightMap & a_HeightMap, int a_X, int a_Z, unsigned char a_Height) + { + a_HeightMap[a_X + Width * a_Z] = a_Height; + } + + + inline static EMCSBiome GetBiome(const BiomeMap & a_BiomeMap, int a_X, int a_Z) + { + return a_BiomeMap[a_X + Width * a_Z]; + } + + + inline static void SetBiome(BiomeMap & a_BiomeMap, int a_X, int a_Z, EMCSBiome a_Biome) + { + a_BiomeMap[a_X + Width * a_Z] = a_Biome; + } + + + static NIBBLETYPE GetNibble(NIBBLETYPE * a_Buffer, int a_BlockIdx) + { + if ((a_BlockIdx > -1) && (a_BlockIdx < cChunkDef::NumBlocks)) + { + return (a_Buffer[a_BlockIdx / 2] >> ((a_BlockIdx & 1) * 4)) & 0x0f; + } + return 0; + } + + + static NIBBLETYPE GetNibble(NIBBLETYPE * a_Buffer, int x, int y, int z) + { + if ((x < Width) && (x > -1) && (y < Height) && (y > -1) && (z < Width) && (z > -1)) + { + int Index = MakeIndexNoCheck(x, y, z); + return (a_Buffer[Index / 2] >> ((Index & 1) * 4)) & 0x0f; + } + return 0; + } + + + static void SetNibble(NIBBLETYPE * a_Buffer, int a_BlockIdx, NIBBLETYPE a_Nibble) + { + if ((a_BlockIdx > -1) && (a_BlockIdx < cChunkDef::NumBlocks)) + { + a_Buffer[a_BlockIdx / 2] = ( + (a_Buffer[a_BlockIdx / 2] & (0xf0 >> ((a_BlockIdx & 1) * 4))) | // The untouched nibble + ((a_Nibble & 0x0f) << ((a_BlockIdx & 1) * 4)) // The nibble being set + ); + } + } + + + static void SetNibble(NIBBLETYPE * a_Buffer, int x, int y, int z, NIBBLETYPE a_Nibble) + { + if ((x < cChunkDef::Width) && (x > -1) && (y < cChunkDef::Height) && (y > -1) && (z < cChunkDef::Width) && (z > -1)) + { + int Index = MakeIndexNoCheck(x, y, z); + a_Buffer[Index / 2] = ( + (a_Buffer[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble + ((a_Nibble & 0x0f) << ((Index & 1) * 4)) // The nibble being set + ); + } + } + + + inline static char GetNibble(NIBBLETYPE * a_Buffer, const Vector3i & a_BlockPos ) + { + return GetNibble( a_Buffer, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z ); + } + + + inline static void SetNibble(NIBBLETYPE * a_Buffer, const Vector3i & a_BlockPos, char a_Value ) + { + SetNibble( a_Buffer, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, a_Value ); + } + +} ; + + + + + +/** Interface class used for getting data out of a chunk using the GetAllData() function. +Implementation must use the pointers immediately and NOT store any of them for later use +The virtual methods are called in the same order as they're declared here. +*/ +class cChunkDataCallback abstract +{ +public: + /// Called once to provide heightmap data + virtual void HeightMap(const cChunkDef::HeightMap * a_HeightMap) {}; + + /// Called once to provide biome data + virtual void BiomeData (const cChunkDef::BiomeMap * a_BiomeMap) {}; + + /// Called once to export block types + virtual void BlockTypes (const BLOCKTYPE * a_Type) {}; + + /// Called once to export block meta + virtual void BlockMeta (const NIBBLETYPE * a_Meta) {}; + + /// Called once to let know if the chunk lighting is valid. Return value is used to control if BlockLight() and BlockSkyLight() are called next + virtual bool LightIsValid(bool a_IsLightValid) {return true; }; + + /// Called once to export block light + virtual void BlockLight (const NIBBLETYPE * a_Meta) {}; + + /// Called once to export sky light + virtual void BlockSkyLight(const NIBBLETYPE * a_Meta) {}; + + /// Called for each entity in the chunk + virtual void Entity(cEntity * a_Entity) {}; + + /// Called for each blockentity in the chunk + virtual void BlockEntity(cBlockEntity * a_Entity) {}; +} ; + + + + + +/** A simple implementation of the cChunkDataCallback interface that collects all block data into a single buffer +*/ +class cChunkDataCollector : + public cChunkDataCallback +{ +public: + + // Must be char instead of BLOCKTYPE or NIBBLETYPE, because it houses both. + char m_BlockData[cChunkDef::BlockDataSize]; + +protected: + + virtual void BlockTypes(const BLOCKTYPE * a_BlockTypes) override + { + memcpy(m_BlockData, a_BlockTypes, sizeof(cChunkDef::BlockTypes)); + } + + + virtual void BlockMeta(const NIBBLETYPE * a_BlockMeta) override + { + memcpy(m_BlockData + cChunkDef::NumBlocks, a_BlockMeta, cChunkDef::NumBlocks / 2); + } + + + virtual void BlockLight(const NIBBLETYPE * a_BlockLight) override + { + memcpy(m_BlockData + 3 * cChunkDef::NumBlocks / 2, a_BlockLight, cChunkDef::NumBlocks / 2); + } + + + virtual void BlockSkyLight(const NIBBLETYPE * a_BlockSkyLight) override + { + memcpy(m_BlockData + 2 * cChunkDef::NumBlocks, a_BlockSkyLight, cChunkDef::NumBlocks / 2); + } +} ; + + + + + +/** A simple implementation of the cChunkDataCallback interface that collects all block data into a separate buffers +*/ +class cChunkDataSeparateCollector : + public cChunkDataCallback +{ +public: + + cChunkDef::BlockTypes m_BlockTypes; + cChunkDef::BlockNibbles m_BlockMetas; + cChunkDef::BlockNibbles m_BlockLight; + cChunkDef::BlockNibbles m_BlockSkyLight; + +protected: + + virtual void BlockTypes(const BLOCKTYPE * a_BlockTypes) override + { + memcpy(m_BlockTypes, a_BlockTypes, sizeof(m_BlockTypes)); + } + + + virtual void BlockMeta(const NIBBLETYPE * a_BlockMeta) override + { + memcpy(m_BlockMetas, a_BlockMeta, sizeof(m_BlockMetas)); + } + + + virtual void BlockLight(const NIBBLETYPE * a_BlockLight) override + { + memcpy(m_BlockLight, a_BlockLight, sizeof(m_BlockLight)); + } + + + virtual void BlockSkyLight(const NIBBLETYPE * a_BlockSkyLight) override + { + memcpy(m_BlockSkyLight, a_BlockSkyLight, sizeof(m_BlockSkyLight)); + } +} ; + + + + + +/** Interface class used for comparing clients of two chunks. +Used primarily for entity moving while both chunks are locked. +*/ +class cClientDiffCallback +{ +public: + /// Called for clients that are in Chunk1 and not in Chunk2, + virtual void Removed(cClientHandle * a_Client) = 0; + + /// Called for clients that are in Chunk2 and not in Chunk1. + virtual void Added(cClientHandle * a_Client) = 0; +} ; + + + + + +struct sSetBlock +{ + int x, y, z; + int ChunkX, ChunkZ; + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + + sSetBlock( int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ); // absolute block position + sSetBlock(int a_ChunkX, int a_ChunkZ, int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) : + ChunkX(a_ChunkX), ChunkZ(a_ChunkZ), + x(a_X), y(a_Y), z(a_Z), + BlockType(a_BlockType), + BlockMeta(a_BlockMeta) + {} +}; + +typedef std::list sSetBlockList; +typedef std::vector sSetBlockVector; + + + + + +class cChunkCoords +{ +public: + int m_ChunkX; + int m_ChunkY; + int m_ChunkZ; + + cChunkCoords(int a_ChunkX, int a_ChunkY, int a_ChunkZ) : m_ChunkX(a_ChunkX), m_ChunkY(a_ChunkY), m_ChunkZ(a_ChunkZ) {} + + bool operator == (const cChunkCoords & a_Other) const + { + return ((m_ChunkX == a_Other.m_ChunkX) && (m_ChunkY == a_Other.m_ChunkY) && (m_ChunkZ == a_Other.m_ChunkZ)); + } +} ; + +typedef std::list cChunkCoordsList; + + + + + +/// Interface class used as a callback for operations that involve chunk coords +class cChunkCoordCallback +{ +public: + virtual void Call(int a_ChunkX, int a_ChunkZ) = 0; +} ; + + + + diff --git a/source/ChunkSender.cpp b/source/ChunkSender.cpp index 8c65eece6..1f16a6b72 100644 --- a/source/ChunkSender.cpp +++ b/source/ChunkSender.cpp @@ -1,300 +1,300 @@ - -// ChunkSender.cpp - -// Interfaces to the cChunkSender class representing the thread that waits for chunks becoming ready (loaded / generated) and sends them to clients - - - - - -#include "Globals.h" -#include "ChunkSender.h" -#include "cWorld.h" -#include "packets/cPacket_MapChunk.h" -#include "packets/cPacket_PreChunk.h" -#include "cBlockEntity.h" - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cNotifyChunkSender: - -void cNotifyChunkSender::Call(int a_ChunkX, int a_ChunkZ) -{ - m_ChunkSender->ChunkReady(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cChunkSender: - -cChunkSender::cChunkSender(void) : - super("ChunkSender"), - m_World(NULL), - m_Notify(NULL) -{ - m_Notify.SetChunkSender(this); -} - - - - - -cChunkSender::~cChunkSender() -{ - Stop(); -} - - - - - -bool cChunkSender::Start(cWorld * a_World) -{ - m_World = a_World; - return super::Start(); -} - - - - - -void cChunkSender::Stop(void) -{ - m_ShouldTerminate = true; - m_evtQueue.Set(); - Wait(); -} - - - - - -void cChunkSender::ChunkReady(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - // This is probably never gonna be called twice for the same chunk, and if it is, we don't mind, so we don't check - { - cCSLock Lock(m_CS); - m_ChunksReady.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); - } - m_evtQueue.Set(); -} - - - - - -void cChunkSender::QueueSendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) -{ - ASSERT(a_Client != NULL); - { - cCSLock Lock(m_CS); - if (std::find(m_SendChunks.begin(), m_SendChunks.end(), sSendChunk(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client)) != m_SendChunks.end()) - { - // Already queued, bail out - return; - } - m_SendChunks.push_back(sSendChunk(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client)); - } - m_evtQueue.Set(); -} - - - - - -void cChunkSender::RemoveClient(cClientHandle * a_Client) -{ - { - cCSLock Lock(m_CS); - for (sSendChunkList::iterator itr = m_SendChunks.begin(); itr != m_SendChunks.end();) - { - if (itr->m_Client == a_Client) - { - itr = m_SendChunks.erase(itr); - continue; - } - ++itr; - } // for itr - m_SendChunks[] - m_RemoveCount++; - } - m_evtQueue.Set(); - m_evtRemoved.Wait(); // Wait for removal confirmation -} - - - - - -void cChunkSender::Execute(void) -{ - while (!m_ShouldTerminate) - { - cCSLock Lock(m_CS); - while (m_ChunksReady.empty() && m_SendChunks.empty()) - { - int RemoveCount = m_RemoveCount; - m_RemoveCount = 0; - cCSUnlock Unlock(Lock); - for (int i = 0; i < RemoveCount; i++) - { - m_evtRemoved.Set(); // Notify that the removed clients are safe to be deleted - } - m_evtQueue.Wait(); - if (m_ShouldTerminate) - { - return; - } - } // while (empty) - - if (!m_ChunksReady.empty()) - { - // Take one from the queue: - cChunkCoords Coords(m_ChunksReady.front()); - m_ChunksReady.pop_front(); - Lock.Unlock(); - - SendChunk(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, NULL); - } - else - { - // Take one from the queue: - sSendChunk Chunk(m_SendChunks.front()); - m_SendChunks.pop_front(); - Lock.Unlock(); - - SendChunk(Chunk.m_ChunkX, Chunk.m_ChunkY, Chunk.m_ChunkZ, Chunk.m_Client); - } - Lock.Lock(); - int RemoveCount = m_RemoveCount; - m_RemoveCount = 0; - Lock.Unlock(); - for (int i = 0; i < RemoveCount; i++) - { - m_evtRemoved.Set(); // Notify that the removed clients are safe to be deleted - } - } // while (!mShouldTerminate) -} - - - - - -void cChunkSender::SendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) -{ - ASSERT(m_World != NULL); - - // Ask the client if it still wants the chunk: - if (a_Client != NULL) - { - if (!a_Client->WantsSendChunk(a_ChunkX, a_ChunkY, a_ChunkZ)) - { - return; - } - } - - // If the chunk has no clients, no need to packetize it: - if (!m_World->HasChunkAnyClients(a_ChunkX, a_ChunkY, a_ChunkZ)) - { - return; - } - - // If the chunk is not valid, do nothing - whoever needs it has queued it for loading / generating - if (!m_World->IsChunkValid(a_ChunkX, a_ChunkY, a_ChunkZ)) - { - return; - } - - // If the chunk is not lighted, queue it for relighting and get notified when it's ready: - if (!m_World->IsChunkLighted(a_ChunkX, a_ChunkZ)) - { - m_World->QueueLightChunk(a_ChunkX, a_ChunkZ, &m_Notify); - return; - } - - // Prepare MapChunk packets: - if( !m_World->GetChunkData(a_ChunkX, a_ChunkY, a_ChunkZ, *this) ) - { - return; - } - cPacket_PreChunk PreChunk(a_ChunkX, a_ChunkZ, true); - cPacket_MapChunk MapChunk(a_ChunkX, a_ChunkY, a_ChunkZ, m_BlockData, m_BiomeMap); - - // Send: - if (a_Client == NULL) - { - m_World->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, PreChunk); - m_World->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, MapChunk); - } - else - { - a_Client->Send(PreChunk); - a_Client->Send(MapChunk); - } - - // Send entity creation packets: - for (PacketList::iterator itr = m_Packets.begin(); itr != m_Packets.end(); ++itr) - { - if (a_Client == NULL) - { - m_World->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, **itr); - } - else - { - a_Client->Send(**itr); - } - delete *itr; - } // for itr - m_Packets[] - m_Packets.clear(); -} - - - - - -void cChunkSender::BlockEntity(cBlockEntity * a_Entity) -{ - cPacket * Packet = a_Entity->GetPacket(); - if (Packet != NULL) - { - m_Packets.push_back(Packet); - } -} - - - - -void cChunkSender::Entity(cEntity * a_Entity) -{ - // Nothing needed yet, perhaps in the future when we save entities into chunks we'd like to send them upon load, too ;) -} - - - - - -void cChunkSender::BiomeData(const cChunkDef::BiomeMap * a_BiomeMap) -{ - for (int i = 0; i < ARRAYCOUNT(m_BiomeMap); i++) - { - if ((*a_BiomeMap)[i] < 255) - { - // Normal MC biome, copy as-is: - m_BiomeMap[i] = (unsigned char)((*a_BiomeMap)[i]); - } - else - { - // TODO: MCS-specific biome, need to map to some basic MC biome: - ASSERT(!"Unimplemented MCS-specific biome"); - } - } // for i - m_BiomeMap[] -} - - - - + +// ChunkSender.cpp + +// Interfaces to the cChunkSender class representing the thread that waits for chunks becoming ready (loaded / generated) and sends them to clients + + + + + +#include "Globals.h" +#include "ChunkSender.h" +#include "cWorld.h" +#include "packets/cPacket_MapChunk.h" +#include "packets/cPacket_PreChunk.h" +#include "cBlockEntity.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cNotifyChunkSender: + +void cNotifyChunkSender::Call(int a_ChunkX, int a_ChunkZ) +{ + m_ChunkSender->ChunkReady(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cChunkSender: + +cChunkSender::cChunkSender(void) : + super("ChunkSender"), + m_World(NULL), + m_Notify(NULL) +{ + m_Notify.SetChunkSender(this); +} + + + + + +cChunkSender::~cChunkSender() +{ + Stop(); +} + + + + + +bool cChunkSender::Start(cWorld * a_World) +{ + m_World = a_World; + return super::Start(); +} + + + + + +void cChunkSender::Stop(void) +{ + m_ShouldTerminate = true; + m_evtQueue.Set(); + Wait(); +} + + + + + +void cChunkSender::ChunkReady(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + // This is probably never gonna be called twice for the same chunk, and if it is, we don't mind, so we don't check + { + cCSLock Lock(m_CS); + m_ChunksReady.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); + } + m_evtQueue.Set(); +} + + + + + +void cChunkSender::QueueSendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) +{ + ASSERT(a_Client != NULL); + { + cCSLock Lock(m_CS); + if (std::find(m_SendChunks.begin(), m_SendChunks.end(), sSendChunk(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client)) != m_SendChunks.end()) + { + // Already queued, bail out + return; + } + m_SendChunks.push_back(sSendChunk(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client)); + } + m_evtQueue.Set(); +} + + + + + +void cChunkSender::RemoveClient(cClientHandle * a_Client) +{ + { + cCSLock Lock(m_CS); + for (sSendChunkList::iterator itr = m_SendChunks.begin(); itr != m_SendChunks.end();) + { + if (itr->m_Client == a_Client) + { + itr = m_SendChunks.erase(itr); + continue; + } + ++itr; + } // for itr - m_SendChunks[] + m_RemoveCount++; + } + m_evtQueue.Set(); + m_evtRemoved.Wait(); // Wait for removal confirmation +} + + + + + +void cChunkSender::Execute(void) +{ + while (!m_ShouldTerminate) + { + cCSLock Lock(m_CS); + while (m_ChunksReady.empty() && m_SendChunks.empty()) + { + int RemoveCount = m_RemoveCount; + m_RemoveCount = 0; + cCSUnlock Unlock(Lock); + for (int i = 0; i < RemoveCount; i++) + { + m_evtRemoved.Set(); // Notify that the removed clients are safe to be deleted + } + m_evtQueue.Wait(); + if (m_ShouldTerminate) + { + return; + } + } // while (empty) + + if (!m_ChunksReady.empty()) + { + // Take one from the queue: + cChunkCoords Coords(m_ChunksReady.front()); + m_ChunksReady.pop_front(); + Lock.Unlock(); + + SendChunk(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, NULL); + } + else + { + // Take one from the queue: + sSendChunk Chunk(m_SendChunks.front()); + m_SendChunks.pop_front(); + Lock.Unlock(); + + SendChunk(Chunk.m_ChunkX, Chunk.m_ChunkY, Chunk.m_ChunkZ, Chunk.m_Client); + } + Lock.Lock(); + int RemoveCount = m_RemoveCount; + m_RemoveCount = 0; + Lock.Unlock(); + for (int i = 0; i < RemoveCount; i++) + { + m_evtRemoved.Set(); // Notify that the removed clients are safe to be deleted + } + } // while (!mShouldTerminate) +} + + + + + +void cChunkSender::SendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) +{ + ASSERT(m_World != NULL); + + // Ask the client if it still wants the chunk: + if (a_Client != NULL) + { + if (!a_Client->WantsSendChunk(a_ChunkX, a_ChunkY, a_ChunkZ)) + { + return; + } + } + + // If the chunk has no clients, no need to packetize it: + if (!m_World->HasChunkAnyClients(a_ChunkX, a_ChunkY, a_ChunkZ)) + { + return; + } + + // If the chunk is not valid, do nothing - whoever needs it has queued it for loading / generating + if (!m_World->IsChunkValid(a_ChunkX, a_ChunkY, a_ChunkZ)) + { + return; + } + + // If the chunk is not lighted, queue it for relighting and get notified when it's ready: + if (!m_World->IsChunkLighted(a_ChunkX, a_ChunkZ)) + { + m_World->QueueLightChunk(a_ChunkX, a_ChunkZ, &m_Notify); + return; + } + + // Prepare MapChunk packets: + if( !m_World->GetChunkData(a_ChunkX, a_ChunkY, a_ChunkZ, *this) ) + { + return; + } + cPacket_PreChunk PreChunk(a_ChunkX, a_ChunkZ, true); + cPacket_MapChunk MapChunk(a_ChunkX, a_ChunkY, a_ChunkZ, m_BlockData, m_BiomeMap); + + // Send: + if (a_Client == NULL) + { + m_World->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, PreChunk); + m_World->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, MapChunk); + } + else + { + a_Client->Send(PreChunk); + a_Client->Send(MapChunk); + } + + // Send entity creation packets: + for (PacketList::iterator itr = m_Packets.begin(); itr != m_Packets.end(); ++itr) + { + if (a_Client == NULL) + { + m_World->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, **itr); + } + else + { + a_Client->Send(**itr); + } + delete *itr; + } // for itr - m_Packets[] + m_Packets.clear(); +} + + + + + +void cChunkSender::BlockEntity(cBlockEntity * a_Entity) +{ + cPacket * Packet = a_Entity->GetPacket(); + if (Packet != NULL) + { + m_Packets.push_back(Packet); + } +} + + + + +void cChunkSender::Entity(cEntity * a_Entity) +{ + // Nothing needed yet, perhaps in the future when we save entities into chunks we'd like to send them upon load, too ;) +} + + + + + +void cChunkSender::BiomeData(const cChunkDef::BiomeMap * a_BiomeMap) +{ + for (int i = 0; i < ARRAYCOUNT(m_BiomeMap); i++) + { + if ((*a_BiomeMap)[i] < 255) + { + // Normal MC biome, copy as-is: + m_BiomeMap[i] = (unsigned char)((*a_BiomeMap)[i]); + } + else + { + // TODO: MCS-specific biome, need to map to some basic MC biome: + ASSERT(!"Unimplemented MCS-specific biome"); + } + } // for i - m_BiomeMap[] +} + + + + diff --git a/source/ChunkSender.h b/source/ChunkSender.h index 196db1dfa..08d97cfca 100644 --- a/source/ChunkSender.h +++ b/source/ChunkSender.h @@ -1,153 +1,153 @@ - -// ChunkSender.h - -// Interfaces to the cChunkSender class representing the thread that waits for chunks becoming ready (loaded / generated) and sends them to clients - -/* -The whole thing is a thread that runs in a loop, waiting for either: - "finished chunks" (ChunkReady()), or - "chunks to send" (QueueSendChunkTo() ) -to come to a queue. -And once they do, it requests the chunk data and sends it all away, either - broadcasting (ChunkReady), or - sends to a specific client (QueueSendChunkTo) -Chunk data is queried using the cChunkDataCallback interface. -It is cached inside the ChunkSender object during the query and then processed after the query ends. -Note that the data needs to be compressed only *after* the query finishes, -because the query callbacks run with ChunkMap's CS locked. - -A client may remove itself from all direct requests(QueueSendChunkTo()) by calling RemoveClient(); -this ensures that the client's Send() won't be called anymore by ChunkSender. -Note that it may be called by world's BroadcastToChunk() if the client is still in the chunk. -*/ - - - -#pragma once - -#include "cIsThread.h" -#include "ChunkDef.h" -#include "packets/cPacket.h" - - - - - -class cWorld; -class cClientHandle; - - - - - -// fwd: -class cChunkSender; - - - - - -/// Callback that can be used to notify chunk sender upon another chunkcoord notification -class cNotifyChunkSender : - public cChunkCoordCallback -{ - virtual void Call(int a_ChunkX, int a_ChunkZ) override; - - cChunkSender * m_ChunkSender; -public: - cNotifyChunkSender(cChunkSender * a_ChunkSender) : m_ChunkSender(a_ChunkSender) {} - - void SetChunkSender(cChunkSender * a_ChunkSender) - { - m_ChunkSender = a_ChunkSender; - } -} ; - - - - - -class cChunkSender: - public cIsThread, - public cChunkDataCollector -{ - typedef cIsThread super; -public: - cChunkSender(void); - ~cChunkSender(); - - bool Start(cWorld * a_World); - - void Stop(void); - - /// Notifies that a chunk has become ready and it should be sent to all its clients - void ChunkReady(int a_ChunkX, int a_ChunkY, int a_ChunkZ); - - /// Queues a chunk to be sent to a specific client - void QueueSendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); - - /// Removes the a_Client from all waiting chunk send operations - void RemoveClient(cClientHandle * a_Client); - -protected: - - /// Used for sending chunks to specific clients - struct sSendChunk - { - int m_ChunkX; - int m_ChunkY; - int m_ChunkZ; - cClientHandle * m_Client; - - sSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) : - m_ChunkX(a_ChunkX), - m_ChunkY(a_ChunkY), - m_ChunkZ(a_ChunkZ), - m_Client(a_Client) - { - } - - bool operator ==(const sSendChunk & a_Other) - { - return ( - (a_Other.m_ChunkX == m_ChunkX) && - (a_Other.m_ChunkY == m_ChunkY) && - (a_Other.m_ChunkZ == m_ChunkZ) && - (a_Other.m_Client == m_Client) - ); - } - }; - typedef std::list sSendChunkList; - - cWorld * m_World; - - cCriticalSection m_CS; - cChunkCoordsList m_ChunksReady; - sSendChunkList m_SendChunks; - cEvent m_evtQueue; // Set when anything is added to m_ChunksReady - cEvent m_evtRemoved; // Set when removed clients are safe to be deleted - int m_RemoveCount; // Number of threads waiting for a client removal (m_evtRemoved needs to be set this many times) - - cNotifyChunkSender m_Notify; // Used for chunks that don't have a valid lighting - they will be re-queued after lightcalc - - // Data about the chunk that is being sent: - // NOTE that m_BlockData[] is inherited from the cChunkDataCollector - unsigned char m_BiomeMap[cChunkDef::Width * cChunkDef::Width]; - PacketList m_Packets; // Accumulator for the entity-packets to send - - // cIsThread override: - virtual void Execute(void) override; - - // cChunkDataCollector overrides: - // (Note that they are called while the ChunkMap's CS is locked - don't do heavy calculations here!) - virtual void BiomeData (const cChunkDef::BiomeMap * a_BiomeMap) override; - virtual void Entity (cEntity * a_Entity) override; - virtual void BlockEntity (cBlockEntity * a_Entity) override; - - /// Sends the specified chunk to a_Client, or to all chunk clients if a_Client == NULL - void SendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); -} ; - - - - + +// ChunkSender.h + +// Interfaces to the cChunkSender class representing the thread that waits for chunks becoming ready (loaded / generated) and sends them to clients + +/* +The whole thing is a thread that runs in a loop, waiting for either: + "finished chunks" (ChunkReady()), or + "chunks to send" (QueueSendChunkTo() ) +to come to a queue. +And once they do, it requests the chunk data and sends it all away, either + broadcasting (ChunkReady), or + sends to a specific client (QueueSendChunkTo) +Chunk data is queried using the cChunkDataCallback interface. +It is cached inside the ChunkSender object during the query and then processed after the query ends. +Note that the data needs to be compressed only *after* the query finishes, +because the query callbacks run with ChunkMap's CS locked. + +A client may remove itself from all direct requests(QueueSendChunkTo()) by calling RemoveClient(); +this ensures that the client's Send() won't be called anymore by ChunkSender. +Note that it may be called by world's BroadcastToChunk() if the client is still in the chunk. +*/ + + + +#pragma once + +#include "cIsThread.h" +#include "ChunkDef.h" +#include "packets/cPacket.h" + + + + + +class cWorld; +class cClientHandle; + + + + + +// fwd: +class cChunkSender; + + + + + +/// Callback that can be used to notify chunk sender upon another chunkcoord notification +class cNotifyChunkSender : + public cChunkCoordCallback +{ + virtual void Call(int a_ChunkX, int a_ChunkZ) override; + + cChunkSender * m_ChunkSender; +public: + cNotifyChunkSender(cChunkSender * a_ChunkSender) : m_ChunkSender(a_ChunkSender) {} + + void SetChunkSender(cChunkSender * a_ChunkSender) + { + m_ChunkSender = a_ChunkSender; + } +} ; + + + + + +class cChunkSender: + public cIsThread, + public cChunkDataCollector +{ + typedef cIsThread super; +public: + cChunkSender(void); + ~cChunkSender(); + + bool Start(cWorld * a_World); + + void Stop(void); + + /// Notifies that a chunk has become ready and it should be sent to all its clients + void ChunkReady(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Queues a chunk to be sent to a specific client + void QueueSendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); + + /// Removes the a_Client from all waiting chunk send operations + void RemoveClient(cClientHandle * a_Client); + +protected: + + /// Used for sending chunks to specific clients + struct sSendChunk + { + int m_ChunkX; + int m_ChunkY; + int m_ChunkZ; + cClientHandle * m_Client; + + sSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) : + m_ChunkX(a_ChunkX), + m_ChunkY(a_ChunkY), + m_ChunkZ(a_ChunkZ), + m_Client(a_Client) + { + } + + bool operator ==(const sSendChunk & a_Other) + { + return ( + (a_Other.m_ChunkX == m_ChunkX) && + (a_Other.m_ChunkY == m_ChunkY) && + (a_Other.m_ChunkZ == m_ChunkZ) && + (a_Other.m_Client == m_Client) + ); + } + }; + typedef std::list sSendChunkList; + + cWorld * m_World; + + cCriticalSection m_CS; + cChunkCoordsList m_ChunksReady; + sSendChunkList m_SendChunks; + cEvent m_evtQueue; // Set when anything is added to m_ChunksReady + cEvent m_evtRemoved; // Set when removed clients are safe to be deleted + int m_RemoveCount; // Number of threads waiting for a client removal (m_evtRemoved needs to be set this many times) + + cNotifyChunkSender m_Notify; // Used for chunks that don't have a valid lighting - they will be re-queued after lightcalc + + // Data about the chunk that is being sent: + // NOTE that m_BlockData[] is inherited from the cChunkDataCollector + unsigned char m_BiomeMap[cChunkDef::Width * cChunkDef::Width]; + PacketList m_Packets; // Accumulator for the entity-packets to send + + // cIsThread override: + virtual void Execute(void) override; + + // cChunkDataCollector overrides: + // (Note that they are called while the ChunkMap's CS is locked - don't do heavy calculations here!) + virtual void BiomeData (const cChunkDef::BiomeMap * a_BiomeMap) override; + virtual void Entity (cEntity * a_Entity) override; + virtual void BlockEntity (cBlockEntity * a_Entity) override; + + /// Sends the specified chunk to a_Client, or to all chunk clients if a_Client == NULL + void SendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); +} ; + + + + diff --git a/source/CompoGen.cpp b/source/CompoGen.cpp index dfb0a40f8..e5f519611 100644 --- a/source/CompoGen.cpp +++ b/source/CompoGen.cpp @@ -1,427 +1,427 @@ - -// CompoGen.cpp - -/* Implements the various terrain composition generators: - - cCompoGenSameBlock - - cCompoGenDebugBiomes - - cCompoGenClassic -*/ - -#include "Globals.h" -#include "CompoGen.h" -#include "BlockID.h" - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cCompoGenSameBlock: - -void cCompoGenSameBlock::ComposeTerrain( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated - cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated - const cChunkDef::HeightMap & a_HeightMap, // The height map to fit - const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to - cEntityList & a_Entities, // Entitites may be generated along with the terrain - cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) -) -{ - memset(a_BlockTypes, E_BLOCK_AIR, sizeof(a_BlockTypes)); - memset(a_BlockMeta, 0, sizeof(a_BlockMeta)); - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int x = 0; x < cChunkDef::Width; x++) - { - int Start; - if (m_IsBedrocked) - { - a_BlockTypes[cChunkDef::MakeIndex(x, 0, z)] = E_BLOCK_BEDROCK; - Start = 1; - } - else - { - Start = 0; - } - for (int y = a_HeightMap[x + cChunkDef::Width * z]; y >= Start; y--) - { - a_BlockTypes[cChunkDef::MakeIndex(x, y, z)] = m_BlockType; - } // for y - } // for z - } // for x -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cCompoGenDebugBiomes: - -void cCompoGenDebugBiomes::ComposeTerrain( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated - cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated - const cChunkDef::HeightMap & a_HeightMap, // The height map to fit - const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to - cEntityList & a_Entities, // Entitites may be generated along with the terrain - cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) -) -{ - static BLOCKTYPE Blocks[] = - { - E_BLOCK_STONE, - E_BLOCK_COBBLESTONE, - E_BLOCK_LOG, - E_BLOCK_PLANKS, - E_BLOCK_SANDSTONE, - E_BLOCK_WHITE_CLOTH, - E_BLOCK_COAL_ORE, - E_BLOCK_IRON_ORE, - E_BLOCK_GOLD_ORE, - E_BLOCK_DIAMOND_ORE, - E_BLOCK_LAPIS_ORE, - E_BLOCK_REDSTONE_ORE, - E_BLOCK_IRON_BLOCK, - E_BLOCK_GOLD_BLOCK, - E_BLOCK_DIAMOND_BLOCK, - E_BLOCK_LAPIS_BLOCK, - E_BLOCK_BRICK, - E_BLOCK_MOSSY_COBBLESTONE, - E_BLOCK_OBSIDIAN, - E_BLOCK_NETHERRACK, - E_BLOCK_SOULSAND, - E_BLOCK_NETHER_BRICK, - E_BLOCK_BEDROCK, - } ; - - memset(a_BlockTypes, E_BLOCK_AIR, sizeof(a_BlockTypes)); - memset(a_BlockMeta, 0, sizeof(a_BlockMeta)); - - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int x = 0; x < cChunkDef::Width; x++) - { - BLOCKTYPE BlockType = Blocks[cChunkDef::GetBiome(a_BiomeMap, x, z) % ARRAYCOUNT(Blocks)]; - for (int y = a_HeightMap[x + cChunkDef::Width * z]; y >= 0; y--) - { - cChunkDef::SetBlock(a_BlockTypes, x, y, z, BlockType); - } // for y - } // for z - } // for x -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cCompoGenClassic: - -cCompoGenClassic::cCompoGenClassic( - int a_SeaLevel, int a_BeachHeight, int a_BeachDepth, - BLOCKTYPE a_BlockTop, BLOCKTYPE a_BlockMiddle, BLOCKTYPE a_BlockBottom, - BLOCKTYPE a_BlockBeach, BLOCKTYPE a_BlockBeachBottom, BLOCKTYPE a_BlockSea -) : - m_SeaLevel(a_SeaLevel), - m_BeachHeight(a_BeachHeight), - m_BeachDepth(a_BeachDepth), - m_BlockTop(a_BlockTop), - m_BlockMiddle(a_BlockMiddle), - m_BlockBottom(a_BlockBottom), - m_BlockBeach(a_BlockBeach), - m_BlockBeachBottom(a_BlockBeachBottom), - m_BlockSea(a_BlockSea) -{ -} - - - - - -void cCompoGenClassic::ComposeTerrain( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated - cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated - const cChunkDef::HeightMap & a_HeightMap, // The height map to fit - const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to - cEntityList & a_Entities, // Entitites may be generated along with the terrain - cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) -) -{ - /* The classic composition means: - - 1 layer of grass, 3 of dirt and the rest stone, if the height > sealevel + beachheight - - 3 sand and a 1 sandstone, rest stone if between sealevel and sealevel + beachheight - - water from waterlevel to height, then 3 sand, 1 sandstone, the rest stone, if water depth < beachdepth - - water from waterlevel, then 3 dirt, the rest stone otherwise - - bedrock at the bottom - */ - - memset(a_BlockTypes, E_BLOCK_AIR, sizeof(a_BlockTypes)); - memset(a_BlockMeta, 0, sizeof(a_BlockMeta)); - - // The patterns to use for different situations, must be same length! - static const BLOCKTYPE PatternGround[] = {m_BlockTop, m_BlockMiddle, m_BlockMiddle, m_BlockMiddle} ; - static const BLOCKTYPE PatternBeach[] = {m_BlockBeach, m_BlockBeach, m_BlockBeach, m_BlockBeachBottom} ; - static const BLOCKTYPE PatternOcean[] = {m_BlockMiddle, m_BlockMiddle, m_BlockMiddle, m_BlockBottom} ; - static int PatternLength = ARRAYCOUNT(PatternGround); - ASSERT(ARRAYCOUNT(PatternGround) == ARRAYCOUNT(PatternBeach)); - ASSERT(ARRAYCOUNT(PatternGround) == ARRAYCOUNT(PatternOcean)); - - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int x = 0; x < cChunkDef::Width; x++) - { - int Height = cChunkDef::GetHeight(a_HeightMap, x, z); - const BLOCKTYPE * Pattern; - if (Height > m_SeaLevel + m_BeachHeight) - { - Pattern = PatternGround; - } - else if (Height > m_SeaLevel - m_BeachDepth) - { - Pattern = PatternBeach; - } - else - { - Pattern = PatternOcean; - } - - // Fill water from sealevel down to height (if any): - for (int y = m_SeaLevel; y >= Height; --y) - { - cChunkDef::SetBlock(a_BlockTypes, x, y, z, m_BlockSea); - } - - // Fill from height till the bottom: - for (int y = Height; y >= 1; y--) - { - cChunkDef::SetBlock(a_BlockTypes, x, y, z, (Height - y < PatternLength) ? Pattern[Height - y] : m_BlockBottom); - } - - // The last layer is always bedrock: - cChunkDef::SetBlock(a_BlockTypes, x, 0, z, E_BLOCK_BEDROCK); - } // for x - } // for z -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cCompoGenBiomal: - -void cCompoGenBiomal::ComposeTerrain( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated - cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated - const cChunkDef::HeightMap & a_HeightMap, // The height map to fit - const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to - cEntityList & a_Entities, // Entitites may be generated along with the terrain - cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) -) -{ - memset(a_BlockTypes, 0, sizeof(a_BlockTypes)); - memset(a_BlockMeta, 0, sizeof(a_BlockMeta)); - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int x = 0; x < cChunkDef::Width; x++) - { - int Height = cChunkDef::GetHeight(a_HeightMap, x, z); - if (Height > m_SeaLevel) - { - switch (cChunkDef::GetBiome(a_BiomeMap, x, z)) - { - case biOcean: - case biPlains: - case biExtremeHills: - case biForest: - case biTaiga: - case biSwampland: - case biRiver: - case biFrozenOcean: - case biFrozenRiver: - case biIcePlains: - case biIceMountains: - case biForestHills: - case biTaigaHills: - case biExtremeHillsEdge: - case biJungle: - case biJungleHills: - { - FillColumnGrass(x, z, Height, a_BlockTypes); - break; - } - case biDesertHills: - case biDesert: - case biBeach: - { - FillColumnSand(x, z, Height, a_BlockTypes); - break; - } - case biMushroomIsland: - case biMushroomShore: - { - FillColumnMycelium(x, z, Height, a_BlockTypes); - break; - } - default: - { - // TODO - ASSERT(!"CompoGenBiomal: Biome not implemented yet!"); - break; - } - } - } - else - { - switch (cChunkDef::GetBiome(a_BiomeMap, x, z)) - { - case biDesert: - case biBeach: - { - // Fill with water, sand, sandstone and stone - FillColumnWaterSand(x, z, Height, a_BlockTypes); - break; - } - default: - { - // Fill with water, sand/dirt/clay mix and stone - FillColumnWaterMix(a_ChunkX, a_ChunkZ, x, z, Height, a_BlockTypes); - break; - } - } // switch (biome) - } // else (under water) - cChunkDef::SetBlock(a_BlockTypes, x, 0, z, E_BLOCK_BEDROCK); - } // for x - } // for z -} - - - - - -void cCompoGenBiomal::FillColumnGrass(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) -{ - BLOCKTYPE Pattern[] = - { - E_BLOCK_GRASS, - E_BLOCK_DIRT, - E_BLOCK_DIRT, - E_BLOCK_DIRT, - } ; - FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); - - for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); - } -} - - - - - -void cCompoGenBiomal::FillColumnSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) -{ - BLOCKTYPE Pattern[] = - { - E_BLOCK_SAND, - E_BLOCK_SAND, - E_BLOCK_SAND, - E_BLOCK_SANDSTONE, - } ; - FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); - - for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); - } -} - - - - - - -void cCompoGenBiomal::FillColumnMycelium (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) -{ - BLOCKTYPE Pattern[] = - { - E_BLOCK_MYCELIUM, - E_BLOCK_DIRT, - E_BLOCK_DIRT, - E_BLOCK_DIRT, - } ; - FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); - - for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); - } -} - - - - - -void cCompoGenBiomal::FillColumnWaterSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) -{ - FillColumnSand(a_RelX, a_RelZ, a_Height, a_BlockTypes); - for (int y = a_Height + 1; y <= m_SeaLevel + 1; y++) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_WATER); - } -} - - - - - -void cCompoGenBiomal::FillColumnWaterMix(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) -{ - if (m_Noise.CubicNoise2D(0.5f * (cChunkDef::Width * a_ChunkX + a_RelX), 0.5f * (cChunkDef::Width * a_ChunkZ + a_RelZ)) < 0) - { - FillColumnWaterSand(a_RelX, a_RelZ, a_Height, a_BlockTypes); - } - else - { - // Dirt - BLOCKTYPE Pattern[] = - { - E_BLOCK_DIRT, - E_BLOCK_DIRT, - E_BLOCK_DIRT, - E_BLOCK_DIRT, - } ; - FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); - - for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); - } - for (int y = a_Height + 1; y <= m_SeaLevel + 1; y++) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_WATER); - } - } -} - - - - - - -void cCompoGenBiomal::FillColumnPattern(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes, const BLOCKTYPE * a_Pattern, int a_PatternSize) -{ - for (int y = a_Height, idx = 0; (y >= 0) && (idx < a_PatternSize); y--, idx++) - { - cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, a_Pattern[idx]); - } -} - - - - + +// CompoGen.cpp + +/* Implements the various terrain composition generators: + - cCompoGenSameBlock + - cCompoGenDebugBiomes + - cCompoGenClassic +*/ + +#include "Globals.h" +#include "CompoGen.h" +#include "BlockID.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCompoGenSameBlock: + +void cCompoGenSameBlock::ComposeTerrain( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated + cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated + const cChunkDef::HeightMap & a_HeightMap, // The height map to fit + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entitites may be generated along with the terrain + cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) +) +{ + memset(a_BlockTypes, E_BLOCK_AIR, sizeof(a_BlockTypes)); + memset(a_BlockMeta, 0, sizeof(a_BlockMeta)); + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + int Start; + if (m_IsBedrocked) + { + a_BlockTypes[cChunkDef::MakeIndex(x, 0, z)] = E_BLOCK_BEDROCK; + Start = 1; + } + else + { + Start = 0; + } + for (int y = a_HeightMap[x + cChunkDef::Width * z]; y >= Start; y--) + { + a_BlockTypes[cChunkDef::MakeIndex(x, y, z)] = m_BlockType; + } // for y + } // for z + } // for x +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCompoGenDebugBiomes: + +void cCompoGenDebugBiomes::ComposeTerrain( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated + cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated + const cChunkDef::HeightMap & a_HeightMap, // The height map to fit + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entitites may be generated along with the terrain + cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) +) +{ + static BLOCKTYPE Blocks[] = + { + E_BLOCK_STONE, + E_BLOCK_COBBLESTONE, + E_BLOCK_LOG, + E_BLOCK_PLANKS, + E_BLOCK_SANDSTONE, + E_BLOCK_WHITE_CLOTH, + E_BLOCK_COAL_ORE, + E_BLOCK_IRON_ORE, + E_BLOCK_GOLD_ORE, + E_BLOCK_DIAMOND_ORE, + E_BLOCK_LAPIS_ORE, + E_BLOCK_REDSTONE_ORE, + E_BLOCK_IRON_BLOCK, + E_BLOCK_GOLD_BLOCK, + E_BLOCK_DIAMOND_BLOCK, + E_BLOCK_LAPIS_BLOCK, + E_BLOCK_BRICK, + E_BLOCK_MOSSY_COBBLESTONE, + E_BLOCK_OBSIDIAN, + E_BLOCK_NETHERRACK, + E_BLOCK_SOULSAND, + E_BLOCK_NETHER_BRICK, + E_BLOCK_BEDROCK, + } ; + + memset(a_BlockTypes, E_BLOCK_AIR, sizeof(a_BlockTypes)); + memset(a_BlockMeta, 0, sizeof(a_BlockMeta)); + + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + BLOCKTYPE BlockType = Blocks[cChunkDef::GetBiome(a_BiomeMap, x, z) % ARRAYCOUNT(Blocks)]; + for (int y = a_HeightMap[x + cChunkDef::Width * z]; y >= 0; y--) + { + cChunkDef::SetBlock(a_BlockTypes, x, y, z, BlockType); + } // for y + } // for z + } // for x +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCompoGenClassic: + +cCompoGenClassic::cCompoGenClassic( + int a_SeaLevel, int a_BeachHeight, int a_BeachDepth, + BLOCKTYPE a_BlockTop, BLOCKTYPE a_BlockMiddle, BLOCKTYPE a_BlockBottom, + BLOCKTYPE a_BlockBeach, BLOCKTYPE a_BlockBeachBottom, BLOCKTYPE a_BlockSea +) : + m_SeaLevel(a_SeaLevel), + m_BeachHeight(a_BeachHeight), + m_BeachDepth(a_BeachDepth), + m_BlockTop(a_BlockTop), + m_BlockMiddle(a_BlockMiddle), + m_BlockBottom(a_BlockBottom), + m_BlockBeach(a_BlockBeach), + m_BlockBeachBottom(a_BlockBeachBottom), + m_BlockSea(a_BlockSea) +{ +} + + + + + +void cCompoGenClassic::ComposeTerrain( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated + cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated + const cChunkDef::HeightMap & a_HeightMap, // The height map to fit + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entitites may be generated along with the terrain + cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) +) +{ + /* The classic composition means: + - 1 layer of grass, 3 of dirt and the rest stone, if the height > sealevel + beachheight + - 3 sand and a 1 sandstone, rest stone if between sealevel and sealevel + beachheight + - water from waterlevel to height, then 3 sand, 1 sandstone, the rest stone, if water depth < beachdepth + - water from waterlevel, then 3 dirt, the rest stone otherwise + - bedrock at the bottom + */ + + memset(a_BlockTypes, E_BLOCK_AIR, sizeof(a_BlockTypes)); + memset(a_BlockMeta, 0, sizeof(a_BlockMeta)); + + // The patterns to use for different situations, must be same length! + static const BLOCKTYPE PatternGround[] = {m_BlockTop, m_BlockMiddle, m_BlockMiddle, m_BlockMiddle} ; + static const BLOCKTYPE PatternBeach[] = {m_BlockBeach, m_BlockBeach, m_BlockBeach, m_BlockBeachBottom} ; + static const BLOCKTYPE PatternOcean[] = {m_BlockMiddle, m_BlockMiddle, m_BlockMiddle, m_BlockBottom} ; + static int PatternLength = ARRAYCOUNT(PatternGround); + ASSERT(ARRAYCOUNT(PatternGround) == ARRAYCOUNT(PatternBeach)); + ASSERT(ARRAYCOUNT(PatternGround) == ARRAYCOUNT(PatternOcean)); + + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + int Height = cChunkDef::GetHeight(a_HeightMap, x, z); + const BLOCKTYPE * Pattern; + if (Height > m_SeaLevel + m_BeachHeight) + { + Pattern = PatternGround; + } + else if (Height > m_SeaLevel - m_BeachDepth) + { + Pattern = PatternBeach; + } + else + { + Pattern = PatternOcean; + } + + // Fill water from sealevel down to height (if any): + for (int y = m_SeaLevel; y >= Height; --y) + { + cChunkDef::SetBlock(a_BlockTypes, x, y, z, m_BlockSea); + } + + // Fill from height till the bottom: + for (int y = Height; y >= 1; y--) + { + cChunkDef::SetBlock(a_BlockTypes, x, y, z, (Height - y < PatternLength) ? Pattern[Height - y] : m_BlockBottom); + } + + // The last layer is always bedrock: + cChunkDef::SetBlock(a_BlockTypes, x, 0, z, E_BLOCK_BEDROCK); + } // for x + } // for z +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCompoGenBiomal: + +void cCompoGenBiomal::ComposeTerrain( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated + cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated + const cChunkDef::HeightMap & a_HeightMap, // The height map to fit + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entitites may be generated along with the terrain + cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) +) +{ + memset(a_BlockTypes, 0, sizeof(a_BlockTypes)); + memset(a_BlockMeta, 0, sizeof(a_BlockMeta)); + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + int Height = cChunkDef::GetHeight(a_HeightMap, x, z); + if (Height > m_SeaLevel) + { + switch (cChunkDef::GetBiome(a_BiomeMap, x, z)) + { + case biOcean: + case biPlains: + case biExtremeHills: + case biForest: + case biTaiga: + case biSwampland: + case biRiver: + case biFrozenOcean: + case biFrozenRiver: + case biIcePlains: + case biIceMountains: + case biForestHills: + case biTaigaHills: + case biExtremeHillsEdge: + case biJungle: + case biJungleHills: + { + FillColumnGrass(x, z, Height, a_BlockTypes); + break; + } + case biDesertHills: + case biDesert: + case biBeach: + { + FillColumnSand(x, z, Height, a_BlockTypes); + break; + } + case biMushroomIsland: + case biMushroomShore: + { + FillColumnMycelium(x, z, Height, a_BlockTypes); + break; + } + default: + { + // TODO + ASSERT(!"CompoGenBiomal: Biome not implemented yet!"); + break; + } + } + } + else + { + switch (cChunkDef::GetBiome(a_BiomeMap, x, z)) + { + case biDesert: + case biBeach: + { + // Fill with water, sand, sandstone and stone + FillColumnWaterSand(x, z, Height, a_BlockTypes); + break; + } + default: + { + // Fill with water, sand/dirt/clay mix and stone + FillColumnWaterMix(a_ChunkX, a_ChunkZ, x, z, Height, a_BlockTypes); + break; + } + } // switch (biome) + } // else (under water) + cChunkDef::SetBlock(a_BlockTypes, x, 0, z, E_BLOCK_BEDROCK); + } // for x + } // for z +} + + + + + +void cCompoGenBiomal::FillColumnGrass(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) +{ + BLOCKTYPE Pattern[] = + { + E_BLOCK_GRASS, + E_BLOCK_DIRT, + E_BLOCK_DIRT, + E_BLOCK_DIRT, + } ; + FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); + + for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) + { + cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); + } +} + + + + + +void cCompoGenBiomal::FillColumnSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) +{ + BLOCKTYPE Pattern[] = + { + E_BLOCK_SAND, + E_BLOCK_SAND, + E_BLOCK_SAND, + E_BLOCK_SANDSTONE, + } ; + FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); + + for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) + { + cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); + } +} + + + + + + +void cCompoGenBiomal::FillColumnMycelium (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) +{ + BLOCKTYPE Pattern[] = + { + E_BLOCK_MYCELIUM, + E_BLOCK_DIRT, + E_BLOCK_DIRT, + E_BLOCK_DIRT, + } ; + FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); + + for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) + { + cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); + } +} + + + + + +void cCompoGenBiomal::FillColumnWaterSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) +{ + FillColumnSand(a_RelX, a_RelZ, a_Height, a_BlockTypes); + for (int y = a_Height + 1; y <= m_SeaLevel + 1; y++) + { + cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_WATER); + } +} + + + + + +void cCompoGenBiomal::FillColumnWaterMix(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) +{ + if (m_Noise.CubicNoise2D(0.5f * (cChunkDef::Width * a_ChunkX + a_RelX), 0.5f * (cChunkDef::Width * a_ChunkZ + a_RelZ)) < 0) + { + FillColumnWaterSand(a_RelX, a_RelZ, a_Height, a_BlockTypes); + } + else + { + // Dirt + BLOCKTYPE Pattern[] = + { + E_BLOCK_DIRT, + E_BLOCK_DIRT, + E_BLOCK_DIRT, + E_BLOCK_DIRT, + } ; + FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); + + for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) + { + cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); + } + for (int y = a_Height + 1; y <= m_SeaLevel + 1; y++) + { + cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_WATER); + } + } +} + + + + + + +void cCompoGenBiomal::FillColumnPattern(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes, const BLOCKTYPE * a_Pattern, int a_PatternSize) +{ + for (int y = a_Height, idx = 0; (y >= 0) && (idx < a_PatternSize); y--, idx++) + { + cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, a_Pattern[idx]); + } +} + + + + diff --git a/source/CompoGen.h b/source/CompoGen.h index e04494fd8..a7939e68d 100644 --- a/source/CompoGen.h +++ b/source/CompoGen.h @@ -1,154 +1,154 @@ - -// CompoGen.h - -/* Interfaces to the various terrain composition generators: - - cCompoGenSameBlock - - cCompoGenDebugBiomes - - cCompoGenClassic - - cCompoGenBiomal -*/ - - - - - -#pragma once - -#include "cChunkGenerator.h" -#include "cNoise.h" - - - - - -class cCompoGenSameBlock : - public cTerrainCompositionGen -{ -public: - cCompoGenSameBlock(BLOCKTYPE a_BlockType, bool a_IsBedrocked) : - m_BlockType(a_BlockType), - m_IsBedrocked(a_IsBedrocked) - {} - -protected: - - BLOCKTYPE m_BlockType; - bool m_IsBedrocked; - - // cTerrainCompositionGen overrides: - virtual void ComposeTerrain( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated - cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated - const cChunkDef::HeightMap & a_HeightMap, // The height map to fit - const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to - cEntityList & a_Entities, // Entitites may be generated along with the terrain - cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) - ) override; -} ; - - - - - -class cCompoGenDebugBiomes : - public cTerrainCompositionGen -{ -public: - cCompoGenDebugBiomes(void) {} - -protected: - - // cTerrainCompositionGen overrides: - virtual void ComposeTerrain( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated - cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated - const cChunkDef::HeightMap & a_HeightMap, // The height map to fit - const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to - cEntityList & a_Entities, // Entitites may be generated along with the terrain - cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) - ) override; -} ; - - - - - -class cCompoGenClassic : - public cTerrainCompositionGen -{ -public: - cCompoGenClassic( - int a_SeaLevel, int a_BeachHeight, int a_BeachDepth, - BLOCKTYPE a_BlockTop, BLOCKTYPE a_BlockMiddle, BLOCKTYPE a_BlockBottom, - BLOCKTYPE a_BlockBeach, BLOCKTYPE a_BlockBeachBottom, BLOCKTYPE a_BlockSea - ); - -protected: - - int m_SeaLevel; - int m_BeachHeight; - int m_BeachDepth; - BLOCKTYPE m_BlockTop; - BLOCKTYPE m_BlockMiddle; - BLOCKTYPE m_BlockBottom; - BLOCKTYPE m_BlockBeach; - BLOCKTYPE m_BlockBeachBottom; - BLOCKTYPE m_BlockSea; - - // cTerrainCompositionGen overrides: - virtual void ComposeTerrain( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated - cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated - const cChunkDef::HeightMap & a_HeightMap, // The height map to fit - const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to - cEntityList & a_Entities, // Entitites may be generated along with the terrain - cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) - ) override; -} ; - - - - - -class cCompoGenBiomal : - public cTerrainCompositionGen -{ -public: - cCompoGenBiomal(int a_Seed, int a_SeaLevel) : - m_Noise(a_Seed + 1000), - m_SeaLevel(a_SeaLevel - 1) // we do an adjustment later in filling the terrain with water - { - } - -protected: - - cNoise m_Noise; - int m_SeaLevel; - - // cTerrainCompositionGen overrides: - virtual void ComposeTerrain( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated - cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated - const cChunkDef::HeightMap & a_HeightMap, // The height map to fit - const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to - cEntityList & a_Entities, // Entitites may be generated along with the terrain - cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) - ) override; - - void FillColumnGrass (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); - void FillColumnSand (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); - void FillColumnMycelium (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); - void FillColumnWaterSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); - - void FillColumnWaterMix (int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); - - void FillColumnPattern (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes, const BLOCKTYPE * a_Pattern, int a_PatternSize); -} ; - - - - + +// CompoGen.h + +/* Interfaces to the various terrain composition generators: + - cCompoGenSameBlock + - cCompoGenDebugBiomes + - cCompoGenClassic + - cCompoGenBiomal +*/ + + + + + +#pragma once + +#include "cChunkGenerator.h" +#include "cNoise.h" + + + + + +class cCompoGenSameBlock : + public cTerrainCompositionGen +{ +public: + cCompoGenSameBlock(BLOCKTYPE a_BlockType, bool a_IsBedrocked) : + m_BlockType(a_BlockType), + m_IsBedrocked(a_IsBedrocked) + {} + +protected: + + BLOCKTYPE m_BlockType; + bool m_IsBedrocked; + + // cTerrainCompositionGen overrides: + virtual void ComposeTerrain( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated + cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated + const cChunkDef::HeightMap & a_HeightMap, // The height map to fit + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entitites may be generated along with the terrain + cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) + ) override; +} ; + + + + + +class cCompoGenDebugBiomes : + public cTerrainCompositionGen +{ +public: + cCompoGenDebugBiomes(void) {} + +protected: + + // cTerrainCompositionGen overrides: + virtual void ComposeTerrain( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated + cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated + const cChunkDef::HeightMap & a_HeightMap, // The height map to fit + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entitites may be generated along with the terrain + cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) + ) override; +} ; + + + + + +class cCompoGenClassic : + public cTerrainCompositionGen +{ +public: + cCompoGenClassic( + int a_SeaLevel, int a_BeachHeight, int a_BeachDepth, + BLOCKTYPE a_BlockTop, BLOCKTYPE a_BlockMiddle, BLOCKTYPE a_BlockBottom, + BLOCKTYPE a_BlockBeach, BLOCKTYPE a_BlockBeachBottom, BLOCKTYPE a_BlockSea + ); + +protected: + + int m_SeaLevel; + int m_BeachHeight; + int m_BeachDepth; + BLOCKTYPE m_BlockTop; + BLOCKTYPE m_BlockMiddle; + BLOCKTYPE m_BlockBottom; + BLOCKTYPE m_BlockBeach; + BLOCKTYPE m_BlockBeachBottom; + BLOCKTYPE m_BlockSea; + + // cTerrainCompositionGen overrides: + virtual void ComposeTerrain( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated + cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated + const cChunkDef::HeightMap & a_HeightMap, // The height map to fit + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entitites may be generated along with the terrain + cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) + ) override; +} ; + + + + + +class cCompoGenBiomal : + public cTerrainCompositionGen +{ +public: + cCompoGenBiomal(int a_Seed, int a_SeaLevel) : + m_Noise(a_Seed + 1000), + m_SeaLevel(a_SeaLevel - 1) // we do an adjustment later in filling the terrain with water + { + } + +protected: + + cNoise m_Noise; + int m_SeaLevel; + + // cTerrainCompositionGen overrides: + virtual void ComposeTerrain( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated + cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated + const cChunkDef::HeightMap & a_HeightMap, // The height map to fit + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entitites may be generated along with the terrain + cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) + ) override; + + void FillColumnGrass (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); + void FillColumnSand (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); + void FillColumnMycelium (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); + void FillColumnWaterSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); + + void FillColumnWaterMix (int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); + + void FillColumnPattern (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes, const BLOCKTYPE * a_Pattern, int a_PatternSize); +} ; + + + + diff --git a/source/CraftingRecipes.cpp b/source/CraftingRecipes.cpp index d26f553e9..38daa1fe8 100644 --- a/source/CraftingRecipes.cpp +++ b/source/CraftingRecipes.cpp @@ -1,765 +1,765 @@ - -// CraftingRecipes.cpp - -// Interfaces to the cCraftingRecipes class representing the storage of crafting recipes - -#include "Globals.h" -#include "CraftingRecipes.h" -#include "cRoot.h" -#include "cPluginManager.h" - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cCraftingGrid: - -cCraftingGrid::cCraftingGrid(int a_Width, int a_Height) : - m_Width(a_Width), - m_Height(a_Height), - m_Items(new cItem[a_Width * a_Height]) -{ -} - - - - - -cCraftingGrid::cCraftingGrid(cItem * a_Items, int a_Width, int a_Height) : - m_Width(a_Width), - m_Height(a_Height), - m_Items(new cItem[a_Width * a_Height]) -{ - for (int i = a_Width * a_Height - 1; i >= 0; i--) - { - m_Items[i] = a_Items[i]; - } -} - - - - - -cCraftingGrid::cCraftingGrid(const cCraftingGrid & a_Original) : - m_Width(a_Original.m_Width), - m_Height(a_Original.m_Height), - m_Items(new cItem[a_Original.m_Width * a_Original.m_Height]) -{ - for (int i = m_Width * m_Height - 1; i >= 0; i--) - { - m_Items[i] = a_Original.m_Items[i]; - } -} - - - - - -cCraftingGrid::~cCraftingGrid() -{ - delete[] m_Items; -} - - - - - -cItem & cCraftingGrid::GetItem(int x, int y) const -{ - // Accessible through scripting, must verify parameters: - if ((x < 0) || (x >= m_Width) || (y < 0) || (y >= m_Height)) - { - LOGERROR("Attempted to get an invalid item from a crafting grid: (%d, %d), grid dimensions: (%d, %d).", - x, y, m_Width, m_Height - ); - return m_Items[0]; - } - return m_Items[x + m_Width * y]; -} - - - - - -void cCraftingGrid::SetItem(int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth) -{ - // Accessible through scripting, must verify parameters: - if ((x < 0) || (x >= m_Width) || (y < 0) || (y >= m_Height)) - { - LOGERROR("Attempted to set an invalid item in a crafting grid: (%d, %d), grid dimensions: (%d, %d).", - x, y, m_Width, m_Height - ); - return; - } - - m_Items[x + m_Width * y] = cItem(a_ItemType, a_ItemCount, a_ItemHealth); -} - - - - - -void cCraftingGrid::SetItem(int x, int y, const cItem & a_Item) -{ - // Accessible through scripting, must verify parameters: - if ((x < 0) || (x >= m_Width) || (y < 0) || (y >= m_Height)) - { - LOGERROR("Attempted to set an invalid item in a crafting grid: (%d, %d), grid dimensions: (%d, %d).", - x, y, m_Width, m_Height - ); - return; - } - - m_Items[x + m_Width * y] = a_Item; -} - - - - - -void cCraftingGrid::Clear(void) -{ - for (int y = 0; y < m_Height; y++) for (int x = 0; x < m_Width; x++) - { - m_Items[x + m_Width * y].Empty(); - } -} - - - - - -void cCraftingGrid::ConsumeGrid(const cCraftingGrid & a_Grid) -{ - if ((a_Grid.m_Width != m_Width) || (a_Grid.m_Height != m_Height)) - { - LOGWARNING("Consuming a grid of different dimensions: (%d, %d) vs (%d, %d)", - a_Grid.m_Width, a_Grid.m_Height, m_Width, m_Height - ); - } - int MinX = std::min(a_Grid.m_Width, m_Width); - int MinY = std::min(a_Grid.m_Height, m_Height); - for (int y = 0; y < MinY; y++) for (int x = 0; x < MinX; x++) - { - int ThatIdx = x + a_Grid.m_Width * y; - if (a_Grid.m_Items[ThatIdx].IsEmpty()) - { - continue; - } - int ThisIdx = x + m_Width * y; - if (a_Grid.m_Items[ThatIdx].m_ItemID != m_Items[ThisIdx].m_ItemID) - { - LOGWARNING("Consuming incompatible grids: item at (%d, %d) is %d in grid and %d in ingredients. Item not consumed.", - x, y, m_Items[ThisIdx].m_ItemID, a_Grid.m_Items[ThatIdx].m_ItemID - ); - continue; - } - char NumWantedItems = a_Grid.m_Items[ThatIdx].m_ItemCount; - if (NumWantedItems > m_Items[ThisIdx].m_ItemCount) - { - LOGWARNING("Consuming more items than there actually are in slot (%d, %d), item %d (want %d, have %d). Item zeroed out.", - x, y, m_Items[ThisIdx].m_ItemID, - NumWantedItems, m_Items[ThisIdx].m_ItemCount - ); - NumWantedItems = m_Items[ThisIdx].m_ItemCount; - } - m_Items[ThisIdx].m_ItemCount -= NumWantedItems; - if (m_Items[ThisIdx].m_ItemCount == 0) - { - m_Items[ThisIdx].Clear(); - } - } // for x, for y -} - - - - - -void cCraftingGrid::CopyToItems(cItem * a_Items) const -{ - for (int i = m_Height * m_Width - 1; i >= 0; i--) - { - a_Items[i] = m_Items[i]; - } // for x, for y -} - - - - - -void cCraftingGrid::Dump(void) -{ - for (int y = 0; y < m_Height; y++) for (int x = 0; x < m_Width; x++) - { - int idx = x + m_Width * y; - LOGD("Slot (%d, %d): Type %d, health %d, count %d", - x, y, m_Items[idx].m_ItemID, m_Items[idx].m_ItemHealth, m_Items[idx].m_ItemCount - ); - } -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cCraftingRecipe: - -cCraftingRecipe::cCraftingRecipe(const cCraftingGrid & a_CraftingGrid) : - m_Ingredients(a_CraftingGrid) -{ -} - - - - - -void cCraftingRecipe::Clear(void) -{ - m_Ingredients.Clear(); - m_Result.Clear(); -} - - - - - -void cCraftingRecipe::SetResult(ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth) -{ - m_Result = cItem(a_ItemType, a_ItemCount, a_ItemHealth); -} - - - - - -void cCraftingRecipe::ConsumeIngredients(cCraftingGrid & a_CraftingGrid) -{ - a_CraftingGrid.ConsumeGrid(m_Ingredients); -} - - - - - -void cCraftingRecipe::Dump(void) -{ - LOGD("Recipe ingredients:"); - m_Ingredients.Dump(); - LOGD("Result: Type %d, health %d, count %d", - m_Result.m_ItemID, m_Result.m_ItemHealth, m_Result.m_ItemCount - ); -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cCraftingRecipes: - -cCraftingRecipes::cCraftingRecipes(void) -{ - LoadRecipes(); -} - - - - - -cCraftingRecipes::~cCraftingRecipes() -{ - ClearRecipes(); -} - - - - - -void cCraftingRecipes::GetRecipe(const cPlayer * a_Player, const cCraftingGrid & a_CraftingGrid, cCraftingRecipe & a_Recipe) -{ - // Allow plugins to intercept recipes using a pre-craft hook: - if (cRoot::Get()->GetPluginManager()->CallHookPreCrafting(a_Player, &a_CraftingGrid, &a_Recipe)) - { - return; - } - - // Built-in recipes: - std::auto_ptr Recipe(FindRecipe(a_CraftingGrid.GetItems(), a_CraftingGrid.GetWidth(), a_CraftingGrid.GetHeight())); - a_Recipe.Clear(); - if (Recipe.get() == NULL) - { - // Allow plugins to intercept a no-recipe-found situation: - cRoot::Get()->GetPluginManager()->CallHookCraftingNoRecipe(a_Player, &a_CraftingGrid, &a_Recipe); - return; - } - for (cRecipeSlots::const_iterator itr = Recipe->m_Ingredients.begin(); itr != Recipe->m_Ingredients.end(); ++itr) - { - a_Recipe.SetIngredient(itr->x, itr->y, itr->m_Item); - } // for itr - a_Recipe.SetResult(Recipe->m_Result); - - // Allow plugins to intercept recipes after they are processed: - cRoot::Get()->GetPluginManager()->CallHookPostCrafting(a_Player, &a_CraftingGrid, &a_Recipe); -} - - - - - -void cCraftingRecipes::LoadRecipes(void) -{ - LOG("-- Loading crafting recipes from crafting.txt --"); - ClearRecipes(); - - // Load the crafting.txt file: - cFile f; - if (!f.Open("crafting.txt", cFile::fmRead)) - { - LOGWARNING("Cannot open file \"crafting.txt\", no crafting recipes will be available!"); - return; - } - AString Everything; - f.ReadRestOfFile(Everything); - f.Close(); - - // Split it into lines, then process each line as a single recipe: - AStringVector Split = StringSplit(Everything, "\n"); - int LineNum = 1; - for (AStringVector::const_iterator itr = Split.begin(); itr != Split.end(); ++itr, ++LineNum) - { - // Remove anything after a '#' sign and trim away the whitespace: - AString Recipe = TrimString(itr->substr(0, itr->find('#'))); - if (Recipe.empty()) - { - // Empty recipe - continue; - } - AddRecipeLine(LineNum, Recipe); - } // for itr - Split[] - LOG("-- %d crafting recipes loaded from crafting.txt --", m_Recipes.size()); -} - - - - -void cCraftingRecipes::ClearRecipes(void) -{ - for (cRecipes::iterator itr = m_Recipes.begin(); itr != m_Recipes.end(); ++itr) - { - delete *itr; - } - m_Recipes.clear(); -} - - - - - -void cCraftingRecipes::AddRecipeLine(int a_LineNum, const AString & a_RecipeLine) -{ - AStringVector Sides = StringSplit(a_RecipeLine, "="); - if (Sides.size() != 2) - { - LOGWARNING("crafting.txt: line %d: A single '=' was expected, got %d", a_LineNum, (int)Sides.size() - 1); - return; - } - - std::auto_ptr Recipe(new cCraftingRecipes::cRecipe); - - // Parse the result: - AStringVector ResultSplit = StringSplit(Sides[0], ","); - if (ResultSplit.empty()) - { - LOGWARNING("crafting.txt: line %d: Result is empty, ignoring the recipe.", a_LineNum); - return; - } - if (!ParseItem(ResultSplit[0], Recipe->m_Result)) - { - LOGWARNING("crafting.txt: line %d: Cannot parse result item, ignoring the recipe.", a_LineNum); - return; - } - if (ResultSplit.size() > 1) - { - Recipe->m_Result.m_ItemCount = atoi(ResultSplit[1].c_str()); - if (Recipe->m_Result.m_ItemCount == 0) - { - LOGWARNING("crafting.txt: line %d: Cannot parse result count, ignoring the recipe.", a_LineNum); - return; - } - } - else - { - Recipe->m_Result.m_ItemCount = 1; - } - - // Parse each ingredient: - AStringVector Ingredients = StringSplit(Sides[1], "|"); - int Num = 1; - for (AStringVector::const_iterator itr = Ingredients.begin(); itr != Ingredients.end(); ++itr, ++Num) - { - if (!ParseIngredient(*itr, Recipe.get())) - { - LOGWARNING("crafting.txt: line %d: Cannot parse ingredient #%d, ignoring the recipe.", a_LineNum, Num); - return; - } - } // for itr - Ingredients[] - - NormalizeIngredients(Recipe.get()); - - m_Recipes.push_back(Recipe.release()); -} - - - - - -bool cCraftingRecipes::ParseItem(const AString & a_String, cItem & a_Item) -{ - // The caller provides error logging - - AStringVector Split = StringSplit(a_String, "^"); - if (Split.empty()) - { - return false; - } - - if (!StringToItem(Split[0], a_Item)) - { - return false; - } - - if (Split.size() > 1) - { - AString Damage = TrimString(Split[1]); - a_Item.m_ItemHealth = atoi(Damage.c_str()); - if ((a_Item.m_ItemHealth == 0) && (Damage.compare("0") != 0)) - { - // Parsing the number failed - return false; - } - } - - // Success - return true; -} - - - - - -bool cCraftingRecipes::ParseIngredient(const AString & a_String, cRecipe * a_Recipe) -{ - // a_String is in this format: "ItemType^damage, X:Y, X:Y, X:Y..." - AStringVector Split = StringSplit(a_String, ","); - if (Split.size() < 2) - { - // Not enough split items - return false; - } - cItem Item; - if (!ParseItem(Split[0], Item)) - { - return false; - } - Item.m_ItemCount = 1; - - cCraftingRecipes::cRecipeSlots TempSlots; - for (AStringVector::const_iterator itr = Split.begin() + 1; itr != Split.end(); ++itr) - { - // Parse the coords in the split item: - AStringVector Coords = StringSplit(*itr, ":"); - if ((Coords.size() == 1) && (TrimString(Coords[0]) == "*")) - { - cCraftingRecipes::cRecipeSlot Slot; - Slot.m_Item = Item; - Slot.x = -1; - Slot.y = -1; - TempSlots.push_back(Slot); - continue; - } - if (Coords.size() != 2) - { - return false; - } - Coords[0] = TrimString(Coords[0]); - Coords[1] = TrimString(Coords[1]); - if (Coords[0].empty() || Coords[1].empty()) - { - return false; - } - cCraftingRecipes::cRecipeSlot Slot; - Slot.m_Item = Item; - switch (Coords[0][0]) - { - case '1': Slot.x = 0; break; - case '2': Slot.x = 1; break; - case '3': Slot.x = 2; break; - case '*': Slot.x = -1; break; - default: - { - return false; - } - } - switch (Coords[1][0]) - { - case '1': Slot.y = 0; break; - case '2': Slot.y = 1; break; - case '3': Slot.y = 2; break; - case '*': Slot.y = -1; break; - default: - { - return false; - } - } - TempSlots.push_back(Slot); - } // for itr - Split[] - - // Append the ingredients: - a_Recipe->m_Ingredients.insert(a_Recipe->m_Ingredients.end(), TempSlots.begin(), TempSlots.end()); - return true; -} - - - - - -void cCraftingRecipes::NormalizeIngredients(cCraftingRecipes::cRecipe * a_Recipe) -{ - // Calculate the minimum coords for ingredients, excluding the "anywhere" items: - int MinX = MAX_GRID_WIDTH, MaxX = 0; - int MinY = MAX_GRID_HEIGHT, MaxY = 0; - for (cRecipeSlots::const_iterator itr = a_Recipe->m_Ingredients.begin(); itr != a_Recipe->m_Ingredients.end(); ++itr) - { - if (itr->x >= 0) - { - MinX = std::min(itr->x, MinX); - MaxX = std::max(itr->x, MaxX); - } - if (itr->y >= 0) - { - MinY = std::min(itr->y, MinY); - MaxY = std::max(itr->y, MaxY); - } - } // for itr - a_Recipe->m_Ingredients[] - - // Move ingredients so that the minimum coords are 0:0 - for (cRecipeSlots::iterator itr = a_Recipe->m_Ingredients.begin(); itr != a_Recipe->m_Ingredients.end(); ++itr) - { - if (itr->x >= 0) - { - itr->x -= MinX; - } - if (itr->y >= 0) - { - itr->y -= MinY; - } - } // for itr - a_Recipe->m_Ingredients[] - a_Recipe->m_Width = std::max(MaxX - MinX + 1, 1); - a_Recipe->m_Height = std::max(MaxY - MinY + 1, 1); - - // TODO: Compress two same ingredients with the same coords into a single ingredient with increased item count -} - - - - - -cCraftingRecipes::cRecipe * cCraftingRecipes::FindRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight) -{ - ASSERT(a_GridWidth <= MAX_GRID_WIDTH); - ASSERT(a_GridHeight <= MAX_GRID_HEIGHT); - - // Get the real bounds of the crafting grid: - int GridLeft = MAX_GRID_WIDTH, GridTop = MAX_GRID_HEIGHT; - int GridRight = 0, GridBottom = 0; - for (int y = 0; y < a_GridHeight; y++ ) for(int x = 0; x < a_GridWidth; x++) - { - if (!a_CraftingGrid[x + y * a_GridWidth].IsEmpty()) - { - GridRight = MAX(x, GridRight); - GridBottom = MAX(y, GridBottom); - GridLeft = MIN(x, GridLeft); - GridTop = MIN(y, GridTop); - } - } - int GridWidth = GridRight - GridLeft + 1; - int GridHeight = GridBottom - GridTop + 1; - - // Search in the possibly minimized grid, but keep the stride: - const cItem * Grid = a_CraftingGrid + GridLeft + (a_GridWidth * GridTop); - cRecipe * Recipe = FindRecipeCropped(Grid, GridWidth, GridHeight, a_GridWidth); - if (Recipe == NULL) - { - return NULL; - } - - // A recipe has been found, move it to correspond to the original crafting grid: - for (cRecipeSlots::iterator itrS = Recipe->m_Ingredients.begin(); itrS != Recipe->m_Ingredients.end(); ++itrS) - { - itrS->x += GridLeft; - itrS->y += GridTop; - } // for itrS - Recipe->m_Ingredients[] - - return Recipe; -} - - - - - -cCraftingRecipes::cRecipe * cCraftingRecipes::FindRecipeCropped(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride) -{ - for (cRecipes::const_iterator itr = m_Recipes.begin(); itr != m_Recipes.end(); ++itr) - { - // Both the crafting grid and the recipes are normalized. The only variable possible is the "anywhere" items. - // This still means that the "anywhere" item may be the one that is offsetting the grid contents to the right or downwards, so we need to check all possible positions. - // E. g. recipe "A, * | B, 1:1 | ..." still needs to check grid for B at 2:2 (in case A was in grid's 1:1) - // Calculate the maximum offsets for this recipe relative to the grid size, and iterate through all combinations of offsets. - // Also, this calculation automatically filters out recipes that are too large for the current grid - the loop won't be entered at all. - - int MaxOfsX = a_GridWidth - (*itr)->m_Width; - int MaxOfsY = a_GridHeight - (*itr)->m_Height; - for (int x = 0; x <= MaxOfsX; x++) for (int y = 0; y <= MaxOfsY; y++) - { - cRecipe * Recipe = MatchRecipe(a_CraftingGrid, a_GridWidth, a_GridHeight, a_GridStride, *itr, x, y); - if (Recipe != NULL) - { - return Recipe; - } - } // for y, for x - } // for itr - m_Recipes[] - - // No matching recipe found - return NULL; -} - - - - - -cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride, const cRecipe * a_Recipe, int a_OffsetX, int a_OffsetY) -{ - // Check the regular items first: - bool HasMatched[MAX_GRID_WIDTH][MAX_GRID_HEIGHT]; - memset(HasMatched, 0, sizeof(HasMatched)); - for (cRecipeSlots::const_iterator itrS = a_Recipe->m_Ingredients.begin(); itrS != a_Recipe->m_Ingredients.end(); ++itrS) - { - if ((itrS->x < 0) || (itrS->y < 0)) - { - // "Anywhere" item, process later - continue; - } - ASSERT(itrS->x + a_OffsetX < a_GridWidth); - ASSERT(itrS->y + a_OffsetY < a_GridHeight); - int GridID = (itrS->x + a_OffsetX) + a_GridStride * (itrS->y + a_OffsetY); - if ( - (itrS->x >= a_GridWidth) || - (itrS->y >= a_GridHeight) || - (itrS->m_Item.m_ItemID != a_CraftingGrid[GridID].m_ItemID) || // same item type? - (itrS->m_Item.m_ItemCount > a_CraftingGrid[GridID].m_ItemCount) || // not enough items - ( - (itrS->m_Item.m_ItemHealth > 0) && // should compare damage values? - (itrS->m_Item.m_ItemHealth != a_CraftingGrid[GridID].m_ItemHealth) - ) - ) - { - // Doesn't match - return NULL; - } - HasMatched[itrS->x + a_OffsetX][itrS->y + a_OffsetY] = true; - } // for itrS - Recipe->m_Ingredients[] - - // Process the "Anywhere" items now, and only in the cells that haven't matched yet - // The "anywhere" items are processed on a first-come-first-served basis. - // Do not use a recipe with one horizontal and one vertical "anywhere" ("*:1, 1:*") as it may not match properly! - cRecipeSlots MatchedSlots; // Stores the slots of "anywhere" items that have matched, with the match coords - for (cRecipeSlots::const_iterator itrS = a_Recipe->m_Ingredients.begin(); itrS != a_Recipe->m_Ingredients.end(); ++itrS) - { - if ((itrS->x >= 0) && (itrS->y >= 0)) - { - // Regular item, already processed - continue; - } - int StartX = 0, EndX = a_GridWidth - 1; - int StartY = 0, EndY = a_GridHeight - 1; - if (itrS->x >= 0) - { - StartX = itrS->x; - EndX = itrS->x; - } - else if (itrS->y >= 0) - { - StartY = itrS->y; - EndY = itrS->y; - } - bool Found = false; - for (int x = StartX; x <= EndX; x++) - { - for (int y = StartY; y <= EndY; y++) - { - if (HasMatched[x][y]) - { - // Already matched some other item - continue; - } - int GridIdx = x + a_GridStride * y; - if ( - (a_CraftingGrid[GridIdx].m_ItemID == itrS->m_Item.m_ItemID) && - ( - (itrS->m_Item.m_ItemHealth < 0) || // doesn't want damage comparison - (itrS->m_Item.m_ItemHealth == a_CraftingGrid[GridIdx].m_ItemHealth) // the damage matches - ) - ) - { - HasMatched[x][y] = true; - Found = true; - MatchedSlots.push_back(*itrS); - MatchedSlots.back().x = x; - MatchedSlots.back().y = y; - break; - } - } // for y - if (Found) - { - break; - } - } // for x - if (!Found) - { - return NULL; - } - } // for itrS - a_Recipe->m_Ingredients[] - - // Check if the whole grid has matched: - for (int x = 0; x < a_GridWidth; x++) for (int y = 0; y < a_GridHeight; y++) - { - if (!HasMatched[x][y] && !a_CraftingGrid[x + a_GridStride * y].IsEmpty()) - { - // There's an unmatched item in the grid - return NULL; - } - } // for y, for x - - // The recipe has matched. Create a copy of the recipe and set its coords to match the crafting grid: - std::auto_ptr Recipe(new cRecipe); - Recipe->m_Result = a_Recipe->m_Result; - Recipe->m_Width = a_Recipe->m_Width; - Recipe->m_Height = a_Recipe->m_Height; - for (cRecipeSlots::const_iterator itrS = a_Recipe->m_Ingredients.begin(); itrS != a_Recipe->m_Ingredients.end(); ++itrS) - { - if ((itrS->x < 0) || (itrS->y < 0)) - { - // "Anywhere" item, process later - continue; - } - Recipe->m_Ingredients.push_back(*itrS); - } - Recipe->m_Ingredients.insert(Recipe->m_Ingredients.end(), MatchedSlots.begin(), MatchedSlots.end()); - return Recipe.release(); -} - - - - + +// CraftingRecipes.cpp + +// Interfaces to the cCraftingRecipes class representing the storage of crafting recipes + +#include "Globals.h" +#include "CraftingRecipes.h" +#include "cRoot.h" +#include "cPluginManager.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCraftingGrid: + +cCraftingGrid::cCraftingGrid(int a_Width, int a_Height) : + m_Width(a_Width), + m_Height(a_Height), + m_Items(new cItem[a_Width * a_Height]) +{ +} + + + + + +cCraftingGrid::cCraftingGrid(cItem * a_Items, int a_Width, int a_Height) : + m_Width(a_Width), + m_Height(a_Height), + m_Items(new cItem[a_Width * a_Height]) +{ + for (int i = a_Width * a_Height - 1; i >= 0; i--) + { + m_Items[i] = a_Items[i]; + } +} + + + + + +cCraftingGrid::cCraftingGrid(const cCraftingGrid & a_Original) : + m_Width(a_Original.m_Width), + m_Height(a_Original.m_Height), + m_Items(new cItem[a_Original.m_Width * a_Original.m_Height]) +{ + for (int i = m_Width * m_Height - 1; i >= 0; i--) + { + m_Items[i] = a_Original.m_Items[i]; + } +} + + + + + +cCraftingGrid::~cCraftingGrid() +{ + delete[] m_Items; +} + + + + + +cItem & cCraftingGrid::GetItem(int x, int y) const +{ + // Accessible through scripting, must verify parameters: + if ((x < 0) || (x >= m_Width) || (y < 0) || (y >= m_Height)) + { + LOGERROR("Attempted to get an invalid item from a crafting grid: (%d, %d), grid dimensions: (%d, %d).", + x, y, m_Width, m_Height + ); + return m_Items[0]; + } + return m_Items[x + m_Width * y]; +} + + + + + +void cCraftingGrid::SetItem(int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth) +{ + // Accessible through scripting, must verify parameters: + if ((x < 0) || (x >= m_Width) || (y < 0) || (y >= m_Height)) + { + LOGERROR("Attempted to set an invalid item in a crafting grid: (%d, %d), grid dimensions: (%d, %d).", + x, y, m_Width, m_Height + ); + return; + } + + m_Items[x + m_Width * y] = cItem(a_ItemType, a_ItemCount, a_ItemHealth); +} + + + + + +void cCraftingGrid::SetItem(int x, int y, const cItem & a_Item) +{ + // Accessible through scripting, must verify parameters: + if ((x < 0) || (x >= m_Width) || (y < 0) || (y >= m_Height)) + { + LOGERROR("Attempted to set an invalid item in a crafting grid: (%d, %d), grid dimensions: (%d, %d).", + x, y, m_Width, m_Height + ); + return; + } + + m_Items[x + m_Width * y] = a_Item; +} + + + + + +void cCraftingGrid::Clear(void) +{ + for (int y = 0; y < m_Height; y++) for (int x = 0; x < m_Width; x++) + { + m_Items[x + m_Width * y].Empty(); + } +} + + + + + +void cCraftingGrid::ConsumeGrid(const cCraftingGrid & a_Grid) +{ + if ((a_Grid.m_Width != m_Width) || (a_Grid.m_Height != m_Height)) + { + LOGWARNING("Consuming a grid of different dimensions: (%d, %d) vs (%d, %d)", + a_Grid.m_Width, a_Grid.m_Height, m_Width, m_Height + ); + } + int MinX = std::min(a_Grid.m_Width, m_Width); + int MinY = std::min(a_Grid.m_Height, m_Height); + for (int y = 0; y < MinY; y++) for (int x = 0; x < MinX; x++) + { + int ThatIdx = x + a_Grid.m_Width * y; + if (a_Grid.m_Items[ThatIdx].IsEmpty()) + { + continue; + } + int ThisIdx = x + m_Width * y; + if (a_Grid.m_Items[ThatIdx].m_ItemID != m_Items[ThisIdx].m_ItemID) + { + LOGWARNING("Consuming incompatible grids: item at (%d, %d) is %d in grid and %d in ingredients. Item not consumed.", + x, y, m_Items[ThisIdx].m_ItemID, a_Grid.m_Items[ThatIdx].m_ItemID + ); + continue; + } + char NumWantedItems = a_Grid.m_Items[ThatIdx].m_ItemCount; + if (NumWantedItems > m_Items[ThisIdx].m_ItemCount) + { + LOGWARNING("Consuming more items than there actually are in slot (%d, %d), item %d (want %d, have %d). Item zeroed out.", + x, y, m_Items[ThisIdx].m_ItemID, + NumWantedItems, m_Items[ThisIdx].m_ItemCount + ); + NumWantedItems = m_Items[ThisIdx].m_ItemCount; + } + m_Items[ThisIdx].m_ItemCount -= NumWantedItems; + if (m_Items[ThisIdx].m_ItemCount == 0) + { + m_Items[ThisIdx].Clear(); + } + } // for x, for y +} + + + + + +void cCraftingGrid::CopyToItems(cItem * a_Items) const +{ + for (int i = m_Height * m_Width - 1; i >= 0; i--) + { + a_Items[i] = m_Items[i]; + } // for x, for y +} + + + + + +void cCraftingGrid::Dump(void) +{ + for (int y = 0; y < m_Height; y++) for (int x = 0; x < m_Width; x++) + { + int idx = x + m_Width * y; + LOGD("Slot (%d, %d): Type %d, health %d, count %d", + x, y, m_Items[idx].m_ItemID, m_Items[idx].m_ItemHealth, m_Items[idx].m_ItemCount + ); + } +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCraftingRecipe: + +cCraftingRecipe::cCraftingRecipe(const cCraftingGrid & a_CraftingGrid) : + m_Ingredients(a_CraftingGrid) +{ +} + + + + + +void cCraftingRecipe::Clear(void) +{ + m_Ingredients.Clear(); + m_Result.Clear(); +} + + + + + +void cCraftingRecipe::SetResult(ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth) +{ + m_Result = cItem(a_ItemType, a_ItemCount, a_ItemHealth); +} + + + + + +void cCraftingRecipe::ConsumeIngredients(cCraftingGrid & a_CraftingGrid) +{ + a_CraftingGrid.ConsumeGrid(m_Ingredients); +} + + + + + +void cCraftingRecipe::Dump(void) +{ + LOGD("Recipe ingredients:"); + m_Ingredients.Dump(); + LOGD("Result: Type %d, health %d, count %d", + m_Result.m_ItemID, m_Result.m_ItemHealth, m_Result.m_ItemCount + ); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCraftingRecipes: + +cCraftingRecipes::cCraftingRecipes(void) +{ + LoadRecipes(); +} + + + + + +cCraftingRecipes::~cCraftingRecipes() +{ + ClearRecipes(); +} + + + + + +void cCraftingRecipes::GetRecipe(const cPlayer * a_Player, const cCraftingGrid & a_CraftingGrid, cCraftingRecipe & a_Recipe) +{ + // Allow plugins to intercept recipes using a pre-craft hook: + if (cRoot::Get()->GetPluginManager()->CallHookPreCrafting(a_Player, &a_CraftingGrid, &a_Recipe)) + { + return; + } + + // Built-in recipes: + std::auto_ptr Recipe(FindRecipe(a_CraftingGrid.GetItems(), a_CraftingGrid.GetWidth(), a_CraftingGrid.GetHeight())); + a_Recipe.Clear(); + if (Recipe.get() == NULL) + { + // Allow plugins to intercept a no-recipe-found situation: + cRoot::Get()->GetPluginManager()->CallHookCraftingNoRecipe(a_Player, &a_CraftingGrid, &a_Recipe); + return; + } + for (cRecipeSlots::const_iterator itr = Recipe->m_Ingredients.begin(); itr != Recipe->m_Ingredients.end(); ++itr) + { + a_Recipe.SetIngredient(itr->x, itr->y, itr->m_Item); + } // for itr + a_Recipe.SetResult(Recipe->m_Result); + + // Allow plugins to intercept recipes after they are processed: + cRoot::Get()->GetPluginManager()->CallHookPostCrafting(a_Player, &a_CraftingGrid, &a_Recipe); +} + + + + + +void cCraftingRecipes::LoadRecipes(void) +{ + LOG("-- Loading crafting recipes from crafting.txt --"); + ClearRecipes(); + + // Load the crafting.txt file: + cFile f; + if (!f.Open("crafting.txt", cFile::fmRead)) + { + LOGWARNING("Cannot open file \"crafting.txt\", no crafting recipes will be available!"); + return; + } + AString Everything; + f.ReadRestOfFile(Everything); + f.Close(); + + // Split it into lines, then process each line as a single recipe: + AStringVector Split = StringSplit(Everything, "\n"); + int LineNum = 1; + for (AStringVector::const_iterator itr = Split.begin(); itr != Split.end(); ++itr, ++LineNum) + { + // Remove anything after a '#' sign and trim away the whitespace: + AString Recipe = TrimString(itr->substr(0, itr->find('#'))); + if (Recipe.empty()) + { + // Empty recipe + continue; + } + AddRecipeLine(LineNum, Recipe); + } // for itr - Split[] + LOG("-- %d crafting recipes loaded from crafting.txt --", m_Recipes.size()); +} + + + + +void cCraftingRecipes::ClearRecipes(void) +{ + for (cRecipes::iterator itr = m_Recipes.begin(); itr != m_Recipes.end(); ++itr) + { + delete *itr; + } + m_Recipes.clear(); +} + + + + + +void cCraftingRecipes::AddRecipeLine(int a_LineNum, const AString & a_RecipeLine) +{ + AStringVector Sides = StringSplit(a_RecipeLine, "="); + if (Sides.size() != 2) + { + LOGWARNING("crafting.txt: line %d: A single '=' was expected, got %d", a_LineNum, (int)Sides.size() - 1); + return; + } + + std::auto_ptr Recipe(new cCraftingRecipes::cRecipe); + + // Parse the result: + AStringVector ResultSplit = StringSplit(Sides[0], ","); + if (ResultSplit.empty()) + { + LOGWARNING("crafting.txt: line %d: Result is empty, ignoring the recipe.", a_LineNum); + return; + } + if (!ParseItem(ResultSplit[0], Recipe->m_Result)) + { + LOGWARNING("crafting.txt: line %d: Cannot parse result item, ignoring the recipe.", a_LineNum); + return; + } + if (ResultSplit.size() > 1) + { + Recipe->m_Result.m_ItemCount = atoi(ResultSplit[1].c_str()); + if (Recipe->m_Result.m_ItemCount == 0) + { + LOGWARNING("crafting.txt: line %d: Cannot parse result count, ignoring the recipe.", a_LineNum); + return; + } + } + else + { + Recipe->m_Result.m_ItemCount = 1; + } + + // Parse each ingredient: + AStringVector Ingredients = StringSplit(Sides[1], "|"); + int Num = 1; + for (AStringVector::const_iterator itr = Ingredients.begin(); itr != Ingredients.end(); ++itr, ++Num) + { + if (!ParseIngredient(*itr, Recipe.get())) + { + LOGWARNING("crafting.txt: line %d: Cannot parse ingredient #%d, ignoring the recipe.", a_LineNum, Num); + return; + } + } // for itr - Ingredients[] + + NormalizeIngredients(Recipe.get()); + + m_Recipes.push_back(Recipe.release()); +} + + + + + +bool cCraftingRecipes::ParseItem(const AString & a_String, cItem & a_Item) +{ + // The caller provides error logging + + AStringVector Split = StringSplit(a_String, "^"); + if (Split.empty()) + { + return false; + } + + if (!StringToItem(Split[0], a_Item)) + { + return false; + } + + if (Split.size() > 1) + { + AString Damage = TrimString(Split[1]); + a_Item.m_ItemHealth = atoi(Damage.c_str()); + if ((a_Item.m_ItemHealth == 0) && (Damage.compare("0") != 0)) + { + // Parsing the number failed + return false; + } + } + + // Success + return true; +} + + + + + +bool cCraftingRecipes::ParseIngredient(const AString & a_String, cRecipe * a_Recipe) +{ + // a_String is in this format: "ItemType^damage, X:Y, X:Y, X:Y..." + AStringVector Split = StringSplit(a_String, ","); + if (Split.size() < 2) + { + // Not enough split items + return false; + } + cItem Item; + if (!ParseItem(Split[0], Item)) + { + return false; + } + Item.m_ItemCount = 1; + + cCraftingRecipes::cRecipeSlots TempSlots; + for (AStringVector::const_iterator itr = Split.begin() + 1; itr != Split.end(); ++itr) + { + // Parse the coords in the split item: + AStringVector Coords = StringSplit(*itr, ":"); + if ((Coords.size() == 1) && (TrimString(Coords[0]) == "*")) + { + cCraftingRecipes::cRecipeSlot Slot; + Slot.m_Item = Item; + Slot.x = -1; + Slot.y = -1; + TempSlots.push_back(Slot); + continue; + } + if (Coords.size() != 2) + { + return false; + } + Coords[0] = TrimString(Coords[0]); + Coords[1] = TrimString(Coords[1]); + if (Coords[0].empty() || Coords[1].empty()) + { + return false; + } + cCraftingRecipes::cRecipeSlot Slot; + Slot.m_Item = Item; + switch (Coords[0][0]) + { + case '1': Slot.x = 0; break; + case '2': Slot.x = 1; break; + case '3': Slot.x = 2; break; + case '*': Slot.x = -1; break; + default: + { + return false; + } + } + switch (Coords[1][0]) + { + case '1': Slot.y = 0; break; + case '2': Slot.y = 1; break; + case '3': Slot.y = 2; break; + case '*': Slot.y = -1; break; + default: + { + return false; + } + } + TempSlots.push_back(Slot); + } // for itr - Split[] + + // Append the ingredients: + a_Recipe->m_Ingredients.insert(a_Recipe->m_Ingredients.end(), TempSlots.begin(), TempSlots.end()); + return true; +} + + + + + +void cCraftingRecipes::NormalizeIngredients(cCraftingRecipes::cRecipe * a_Recipe) +{ + // Calculate the minimum coords for ingredients, excluding the "anywhere" items: + int MinX = MAX_GRID_WIDTH, MaxX = 0; + int MinY = MAX_GRID_HEIGHT, MaxY = 0; + for (cRecipeSlots::const_iterator itr = a_Recipe->m_Ingredients.begin(); itr != a_Recipe->m_Ingredients.end(); ++itr) + { + if (itr->x >= 0) + { + MinX = std::min(itr->x, MinX); + MaxX = std::max(itr->x, MaxX); + } + if (itr->y >= 0) + { + MinY = std::min(itr->y, MinY); + MaxY = std::max(itr->y, MaxY); + } + } // for itr - a_Recipe->m_Ingredients[] + + // Move ingredients so that the minimum coords are 0:0 + for (cRecipeSlots::iterator itr = a_Recipe->m_Ingredients.begin(); itr != a_Recipe->m_Ingredients.end(); ++itr) + { + if (itr->x >= 0) + { + itr->x -= MinX; + } + if (itr->y >= 0) + { + itr->y -= MinY; + } + } // for itr - a_Recipe->m_Ingredients[] + a_Recipe->m_Width = std::max(MaxX - MinX + 1, 1); + a_Recipe->m_Height = std::max(MaxY - MinY + 1, 1); + + // TODO: Compress two same ingredients with the same coords into a single ingredient with increased item count +} + + + + + +cCraftingRecipes::cRecipe * cCraftingRecipes::FindRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight) +{ + ASSERT(a_GridWidth <= MAX_GRID_WIDTH); + ASSERT(a_GridHeight <= MAX_GRID_HEIGHT); + + // Get the real bounds of the crafting grid: + int GridLeft = MAX_GRID_WIDTH, GridTop = MAX_GRID_HEIGHT; + int GridRight = 0, GridBottom = 0; + for (int y = 0; y < a_GridHeight; y++ ) for(int x = 0; x < a_GridWidth; x++) + { + if (!a_CraftingGrid[x + y * a_GridWidth].IsEmpty()) + { + GridRight = MAX(x, GridRight); + GridBottom = MAX(y, GridBottom); + GridLeft = MIN(x, GridLeft); + GridTop = MIN(y, GridTop); + } + } + int GridWidth = GridRight - GridLeft + 1; + int GridHeight = GridBottom - GridTop + 1; + + // Search in the possibly minimized grid, but keep the stride: + const cItem * Grid = a_CraftingGrid + GridLeft + (a_GridWidth * GridTop); + cRecipe * Recipe = FindRecipeCropped(Grid, GridWidth, GridHeight, a_GridWidth); + if (Recipe == NULL) + { + return NULL; + } + + // A recipe has been found, move it to correspond to the original crafting grid: + for (cRecipeSlots::iterator itrS = Recipe->m_Ingredients.begin(); itrS != Recipe->m_Ingredients.end(); ++itrS) + { + itrS->x += GridLeft; + itrS->y += GridTop; + } // for itrS - Recipe->m_Ingredients[] + + return Recipe; +} + + + + + +cCraftingRecipes::cRecipe * cCraftingRecipes::FindRecipeCropped(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride) +{ + for (cRecipes::const_iterator itr = m_Recipes.begin(); itr != m_Recipes.end(); ++itr) + { + // Both the crafting grid and the recipes are normalized. The only variable possible is the "anywhere" items. + // This still means that the "anywhere" item may be the one that is offsetting the grid contents to the right or downwards, so we need to check all possible positions. + // E. g. recipe "A, * | B, 1:1 | ..." still needs to check grid for B at 2:2 (in case A was in grid's 1:1) + // Calculate the maximum offsets for this recipe relative to the grid size, and iterate through all combinations of offsets. + // Also, this calculation automatically filters out recipes that are too large for the current grid - the loop won't be entered at all. + + int MaxOfsX = a_GridWidth - (*itr)->m_Width; + int MaxOfsY = a_GridHeight - (*itr)->m_Height; + for (int x = 0; x <= MaxOfsX; x++) for (int y = 0; y <= MaxOfsY; y++) + { + cRecipe * Recipe = MatchRecipe(a_CraftingGrid, a_GridWidth, a_GridHeight, a_GridStride, *itr, x, y); + if (Recipe != NULL) + { + return Recipe; + } + } // for y, for x + } // for itr - m_Recipes[] + + // No matching recipe found + return NULL; +} + + + + + +cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride, const cRecipe * a_Recipe, int a_OffsetX, int a_OffsetY) +{ + // Check the regular items first: + bool HasMatched[MAX_GRID_WIDTH][MAX_GRID_HEIGHT]; + memset(HasMatched, 0, sizeof(HasMatched)); + for (cRecipeSlots::const_iterator itrS = a_Recipe->m_Ingredients.begin(); itrS != a_Recipe->m_Ingredients.end(); ++itrS) + { + if ((itrS->x < 0) || (itrS->y < 0)) + { + // "Anywhere" item, process later + continue; + } + ASSERT(itrS->x + a_OffsetX < a_GridWidth); + ASSERT(itrS->y + a_OffsetY < a_GridHeight); + int GridID = (itrS->x + a_OffsetX) + a_GridStride * (itrS->y + a_OffsetY); + if ( + (itrS->x >= a_GridWidth) || + (itrS->y >= a_GridHeight) || + (itrS->m_Item.m_ItemID != a_CraftingGrid[GridID].m_ItemID) || // same item type? + (itrS->m_Item.m_ItemCount > a_CraftingGrid[GridID].m_ItemCount) || // not enough items + ( + (itrS->m_Item.m_ItemHealth > 0) && // should compare damage values? + (itrS->m_Item.m_ItemHealth != a_CraftingGrid[GridID].m_ItemHealth) + ) + ) + { + // Doesn't match + return NULL; + } + HasMatched[itrS->x + a_OffsetX][itrS->y + a_OffsetY] = true; + } // for itrS - Recipe->m_Ingredients[] + + // Process the "Anywhere" items now, and only in the cells that haven't matched yet + // The "anywhere" items are processed on a first-come-first-served basis. + // Do not use a recipe with one horizontal and one vertical "anywhere" ("*:1, 1:*") as it may not match properly! + cRecipeSlots MatchedSlots; // Stores the slots of "anywhere" items that have matched, with the match coords + for (cRecipeSlots::const_iterator itrS = a_Recipe->m_Ingredients.begin(); itrS != a_Recipe->m_Ingredients.end(); ++itrS) + { + if ((itrS->x >= 0) && (itrS->y >= 0)) + { + // Regular item, already processed + continue; + } + int StartX = 0, EndX = a_GridWidth - 1; + int StartY = 0, EndY = a_GridHeight - 1; + if (itrS->x >= 0) + { + StartX = itrS->x; + EndX = itrS->x; + } + else if (itrS->y >= 0) + { + StartY = itrS->y; + EndY = itrS->y; + } + bool Found = false; + for (int x = StartX; x <= EndX; x++) + { + for (int y = StartY; y <= EndY; y++) + { + if (HasMatched[x][y]) + { + // Already matched some other item + continue; + } + int GridIdx = x + a_GridStride * y; + if ( + (a_CraftingGrid[GridIdx].m_ItemID == itrS->m_Item.m_ItemID) && + ( + (itrS->m_Item.m_ItemHealth < 0) || // doesn't want damage comparison + (itrS->m_Item.m_ItemHealth == a_CraftingGrid[GridIdx].m_ItemHealth) // the damage matches + ) + ) + { + HasMatched[x][y] = true; + Found = true; + MatchedSlots.push_back(*itrS); + MatchedSlots.back().x = x; + MatchedSlots.back().y = y; + break; + } + } // for y + if (Found) + { + break; + } + } // for x + if (!Found) + { + return NULL; + } + } // for itrS - a_Recipe->m_Ingredients[] + + // Check if the whole grid has matched: + for (int x = 0; x < a_GridWidth; x++) for (int y = 0; y < a_GridHeight; y++) + { + if (!HasMatched[x][y] && !a_CraftingGrid[x + a_GridStride * y].IsEmpty()) + { + // There's an unmatched item in the grid + return NULL; + } + } // for y, for x + + // The recipe has matched. Create a copy of the recipe and set its coords to match the crafting grid: + std::auto_ptr Recipe(new cRecipe); + Recipe->m_Result = a_Recipe->m_Result; + Recipe->m_Width = a_Recipe->m_Width; + Recipe->m_Height = a_Recipe->m_Height; + for (cRecipeSlots::const_iterator itrS = a_Recipe->m_Ingredients.begin(); itrS != a_Recipe->m_Ingredients.end(); ++itrS) + { + if ((itrS->x < 0) || (itrS->y < 0)) + { + // "Anywhere" item, process later + continue; + } + Recipe->m_Ingredients.push_back(*itrS); + } + Recipe->m_Ingredients.insert(Recipe->m_Ingredients.end(), MatchedSlots.begin(), MatchedSlots.end()); + return Recipe.release(); +} + + + + diff --git a/source/CraftingRecipes.h b/source/CraftingRecipes.h index 8e4422b1c..25f8fdae2 100644 --- a/source/CraftingRecipes.h +++ b/source/CraftingRecipes.h @@ -1,172 +1,172 @@ - -// CraftingRecipes.h - -// Interfaces to the cCraftingRecipes class representing the storage of crafting recipes - - - - -#pragma once - -#include "cItem.h" - - - - - -// fwd: cPlayer.h -class cPlayer; - - - - - -class cCraftingGrid // tolua_export -{ // tolua_export -public: - cCraftingGrid(const cCraftingGrid & a_Original); - cCraftingGrid(int a_Width, int a_Height); // tolua_export - cCraftingGrid(cItem * a_Items, int a_Width, int a_Height); - ~cCraftingGrid(); - - // tolua_begin - int GetWidth (void) const {return m_Width; } - int GetHeight(void) const {return m_Height; } - cItem & GetItem (int x, int y) const; - void SetItem (int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth); - void SetItem (int x, int y, const cItem & a_Item); - void Clear (void); - - /// Removes items in a_Grid from m_Items[] (used by cCraftingRecipe::ConsumeIngredients()) - void ConsumeGrid(const cCraftingGrid & a_Grid); - - /// Dumps the entire crafting grid using LOGD() - void Dump(void); - - // tolua_end - - cItem * GetItems(void) const {return m_Items; } - - /// Copies internal contents into the item array specified. Assumes that the array has the same dimensions as self - void CopyToItems(cItem * a_Items) const; - -protected: - - int m_Width; - int m_Height; - cItem * m_Items; -} ; // tolua_export - - - - - -class cCraftingRecipe // tolua_export -{ // tolua_export -public: - cCraftingRecipe(const cCraftingGrid & a_CraftingGrid); - - // tolua_begin - void Clear (void); - int GetIngredientsWidth (void) const {return m_Ingredients.GetWidth(); } - int GetIngredientsHeight(void) const {return m_Ingredients.GetHeight(); } - cItem & GetIngredient (int x, int y) const {return m_Ingredients.GetItem(x, y); } - const cItem & GetResult (void) const {return m_Result; } - void SetResult (ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth); - void SetResult (const cItem & a_Item) - { - m_Result = a_Item; - } - - void SetIngredient (int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth) - { - m_Ingredients.SetItem(x, y, a_ItemType, a_ItemCount, a_ItemHealth); - } - - void SetIngredient (int x, int y, const cItem & a_Item) - { - m_Ingredients.SetItem(x, y, a_Item); - } - - /// Consumes ingredients from the crafting grid specified - void ConsumeIngredients(cCraftingGrid & a_CraftingGrid); - - /// Dumps the entire recipe using LOGD() - void Dump(void); - // tolua_end - -protected: - - cCraftingGrid m_Ingredients; // Adjusted to correspond to the input crafting grid! - cItem m_Result; -} ; // tolua_export - - - - - -class cCraftingRecipes -{ -public: - static const int MAX_GRID_WIDTH = 3; - static const int MAX_GRID_HEIGHT = 3; - - cCraftingRecipes(void); - ~cCraftingRecipes(); - - /// Returns the recipe for current crafting grid. Doesn't modify the grid. Clears a_Recipe if no recipe found. - void GetRecipe(const cPlayer * a_Player, const cCraftingGrid & a_CraftingGrid, cCraftingRecipe & a_Recipe); - -protected: - - struct cRecipeSlot - { - cItem m_Item; - int x, y; // 1..3, or -1 for "any" - } ; - typedef std::vector cRecipeSlots; - - /** A single recipe, stored. Each recipe is normalized right after parsing (NormalizeIngredients()) - A normalized recipe starts at (0,0) - */ - struct cRecipe - { - cRecipeSlots m_Ingredients; - cItem m_Result; - - // Size of the regular items in the recipe; "anywhere" items are excluded: - int m_Width; - int m_Height; - } ; - typedef std::vector cRecipes; - - cRecipes m_Recipes; - - void LoadRecipes(void); - void ClearRecipes(void); - - /// Parses the recipe line and adds it into m_Recipes. a_LineNum is used for diagnostic warnings only - void AddRecipeLine(int a_LineNum, const AString & a_RecipeLine); - - /// Parses an item string in the format "[^]", returns true if successful. - bool ParseItem(const AString & a_String, cItem & a_Item); - - /// Parses one ingredient and adds it to the specified recipe. Returns true if successful. - bool ParseIngredient(const AString & a_String, cRecipe * a_Recipe); - - /// Moves the recipe to top-left corner, sets its MinWidth / MinHeight - void NormalizeIngredients(cRecipe * a_Recipe); - - /// Finds a recipe matching the crafting grid. Returns a newly allocated recipe (with all its coords set) or NULL if not found. Caller must delete return value! - cRecipe * FindRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight); - - /// Same as FindRecipe, but the grid is guaranteed to be of minimal dimensions needed - cRecipe * FindRecipeCropped(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride); - - /// Checks if the grid matches the specified recipe, offset by the specified offsets. Returns a matched cRecipe * if so, or NULL if not matching. Caller must delete the return value! - cRecipe * MatchRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride, const cRecipe * a_Recipe, int a_OffsetX, int a_OffsetY); -} ; - - - - + +// CraftingRecipes.h + +// Interfaces to the cCraftingRecipes class representing the storage of crafting recipes + + + + +#pragma once + +#include "cItem.h" + + + + + +// fwd: cPlayer.h +class cPlayer; + + + + + +class cCraftingGrid // tolua_export +{ // tolua_export +public: + cCraftingGrid(const cCraftingGrid & a_Original); + cCraftingGrid(int a_Width, int a_Height); // tolua_export + cCraftingGrid(cItem * a_Items, int a_Width, int a_Height); + ~cCraftingGrid(); + + // tolua_begin + int GetWidth (void) const {return m_Width; } + int GetHeight(void) const {return m_Height; } + cItem & GetItem (int x, int y) const; + void SetItem (int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth); + void SetItem (int x, int y, const cItem & a_Item); + void Clear (void); + + /// Removes items in a_Grid from m_Items[] (used by cCraftingRecipe::ConsumeIngredients()) + void ConsumeGrid(const cCraftingGrid & a_Grid); + + /// Dumps the entire crafting grid using LOGD() + void Dump(void); + + // tolua_end + + cItem * GetItems(void) const {return m_Items; } + + /// Copies internal contents into the item array specified. Assumes that the array has the same dimensions as self + void CopyToItems(cItem * a_Items) const; + +protected: + + int m_Width; + int m_Height; + cItem * m_Items; +} ; // tolua_export + + + + + +class cCraftingRecipe // tolua_export +{ // tolua_export +public: + cCraftingRecipe(const cCraftingGrid & a_CraftingGrid); + + // tolua_begin + void Clear (void); + int GetIngredientsWidth (void) const {return m_Ingredients.GetWidth(); } + int GetIngredientsHeight(void) const {return m_Ingredients.GetHeight(); } + cItem & GetIngredient (int x, int y) const {return m_Ingredients.GetItem(x, y); } + const cItem & GetResult (void) const {return m_Result; } + void SetResult (ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth); + void SetResult (const cItem & a_Item) + { + m_Result = a_Item; + } + + void SetIngredient (int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth) + { + m_Ingredients.SetItem(x, y, a_ItemType, a_ItemCount, a_ItemHealth); + } + + void SetIngredient (int x, int y, const cItem & a_Item) + { + m_Ingredients.SetItem(x, y, a_Item); + } + + /// Consumes ingredients from the crafting grid specified + void ConsumeIngredients(cCraftingGrid & a_CraftingGrid); + + /// Dumps the entire recipe using LOGD() + void Dump(void); + // tolua_end + +protected: + + cCraftingGrid m_Ingredients; // Adjusted to correspond to the input crafting grid! + cItem m_Result; +} ; // tolua_export + + + + + +class cCraftingRecipes +{ +public: + static const int MAX_GRID_WIDTH = 3; + static const int MAX_GRID_HEIGHT = 3; + + cCraftingRecipes(void); + ~cCraftingRecipes(); + + /// Returns the recipe for current crafting grid. Doesn't modify the grid. Clears a_Recipe if no recipe found. + void GetRecipe(const cPlayer * a_Player, const cCraftingGrid & a_CraftingGrid, cCraftingRecipe & a_Recipe); + +protected: + + struct cRecipeSlot + { + cItem m_Item; + int x, y; // 1..3, or -1 for "any" + } ; + typedef std::vector cRecipeSlots; + + /** A single recipe, stored. Each recipe is normalized right after parsing (NormalizeIngredients()) + A normalized recipe starts at (0,0) + */ + struct cRecipe + { + cRecipeSlots m_Ingredients; + cItem m_Result; + + // Size of the regular items in the recipe; "anywhere" items are excluded: + int m_Width; + int m_Height; + } ; + typedef std::vector cRecipes; + + cRecipes m_Recipes; + + void LoadRecipes(void); + void ClearRecipes(void); + + /// Parses the recipe line and adds it into m_Recipes. a_LineNum is used for diagnostic warnings only + void AddRecipeLine(int a_LineNum, const AString & a_RecipeLine); + + /// Parses an item string in the format "[^]", returns true if successful. + bool ParseItem(const AString & a_String, cItem & a_Item); + + /// Parses one ingredient and adds it to the specified recipe. Returns true if successful. + bool ParseIngredient(const AString & a_String, cRecipe * a_Recipe); + + /// Moves the recipe to top-left corner, sets its MinWidth / MinHeight + void NormalizeIngredients(cRecipe * a_Recipe); + + /// Finds a recipe matching the crafting grid. Returns a newly allocated recipe (with all its coords set) or NULL if not found. Caller must delete return value! + cRecipe * FindRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight); + + /// Same as FindRecipe, but the grid is guaranteed to be of minimal dimensions needed + cRecipe * FindRecipeCropped(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride); + + /// Checks if the grid matches the specified recipe, offset by the specified offsets. Returns a matched cRecipe * if so, or NULL if not matching. Caller must delete the return value! + cRecipe * MatchRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride, const cRecipe * a_Recipe, int a_OffsetX, int a_OffsetY); +} ; + + + + diff --git a/source/Defines.h b/source/Defines.h index fae466e4a..d0279875f 100644 --- a/source/Defines.h +++ b/source/Defines.h @@ -1,293 +1,293 @@ -#pragma once - -#include "BlockID.h" - -//tolua_begin -// emissive blocks -extern unsigned char g_BlockLightValue[]; -// whether blocks allow spreading -extern unsigned char g_BlockSpreadLightFalloff[]; -// whether blocks are transparent (light can shine though) -extern bool g_BlockTransparent[]; -// one hit break blocks -extern bool g_BlockOneHitDig[]; -//tolua_end - -//--DO NOT DELETE THIS COMMENT-- //tolua_export - - - - - -inline bool IsValidBlock( int a_BlockID ) //tolua_export -{ //tolua_export - if( a_BlockID > -1 && - a_BlockID <= 126 && //items to 109 are valid for Beta1.8.1.. 1.2.5 is up to 126 - //a_BlockID != 29 && allow pistons - //a_BlockID != 33 && allow pistons - a_BlockID != 34 && - a_BlockID != 36 ) - { - return true; - } - return false; -} //tolua_export - - - - - -// Was old :o -// Changed to fit the style ;) -inline bool IsValidItem( int a_ItemID ) //tolua_export -{ //tolua_export - if( (a_ItemID >= 256 && a_ItemID <= 388) - || (a_ItemID >= 2256 && a_ItemID <= 2266) ) - { - return true; - } - - if( a_ItemID == 0 ) - return false; - - return IsValidBlock( a_ItemID ); -} //tolua_export - - - - - -inline bool IsBlockWater(char a_BlockID) -{ - return (a_BlockID == E_BLOCK_WATER || a_BlockID == E_BLOCK_STATIONARY_WATER); -} - - - - - -inline bool IsBlockLava(char a_BlockID) -{ - return (a_BlockID == E_BLOCK_LAVA || a_BlockID == E_BLOCK_STATIONARY_LAVA); -} - - - - - -inline void AddDirection( int & a_X, int & a_Y, int & a_Z, char a_Direction, bool a_bInverse = false ) -{ - if( !a_bInverse ) - { - switch( a_Direction ) - { - case 0: - a_Y--; - break; - case 1: - a_Y++; - break; - case 2: - a_Z--; - break; - case 3: - a_Z++; - break; - case 4: - a_X--; - break; - case 5: - a_X++; - break; - }; - } - else - { - switch( a_Direction ) // other way around - { - case 0: - a_Y++; - break; - case 1: - a_Y--; - break; - case 2: - a_Z++; - break; - case 3: - a_Z--; - break; - case 4: - a_X++; - break; - case 5: - a_X--; - break; - }; - } -} - - - - - -inline void AddDirection( int & a_X, unsigned char & a_Y, int & a_Z, char a_Direction, bool a_bInverse = false ) //tolua_export -{//tolua_export - int Y = a_Y; - AddDirection( a_X, Y, a_Z, a_Direction, a_bInverse ); - if( Y < 0 ) a_Y = 0; - else if( Y > 255 ) a_Y = 255; - else a_Y = (unsigned char)Y; -}//tolua_export - - - - - -#include -#define PI 3.14159265358979323846264338327950288419716939937510582097494459072381640628620899862803482534211706798f -#define MIN(a,b) (((a)>(b))?(b):(a)) -#define MAX(a,b) (((a)>(b))?(a):(b)) -inline void EulerToVector( float a_Pan, float a_Pitch, float & a_X, float & a_Y, float & a_Z ) -{ - // a_X = sinf ( a_Pan / 180 * PI ) * cosf ( a_Pitch / 180 * PI ); - // a_Y = -sinf ( a_Pitch / 180 * PI ); - // a_Z = -cosf ( a_Pan / 180 * PI ) * cosf ( a_Pitch / 180 * PI ); - a_X = cos(a_Pan / 180 * PI)*cos(a_Pitch / 180 * PI); - a_Y = sin(a_Pan / 180 * PI)*cos(a_Pitch / 180 * PI); - a_Z = sin(a_Pitch / 180 * PI); -} - - - - - -inline void VectorToEuler( float a_X, float a_Y, float a_Z, float & a_Pan, float & a_Pitch ) -{ - if( a_X != 0 ) - a_Pan = atan2( a_Z, a_X ) * 180 / PI - 90; - else - a_Pan = 0; - a_Pitch = atan2(a_Y, sqrtf((a_X * a_X) + (a_Z * a_Z))) * 180 / PI; -} - - - - - -inline float GetSignf( float a_Val ) -{ - return (a_Val < 0.f)?-1.f:1.f; -} - - - - - -inline float GetSpecialSignf( float a_Val ) -{ - return (a_Val <= 0.f)?-1.f:1.f; -} - - - - -//tolua_begin -namespace ItemCategory -{ - inline bool IsPickaxe(ENUM_ITEM_ID a_ItemID) - { - return (a_ItemID == E_ITEM_WOODEN_PICKAXE) - || (a_ItemID == E_ITEM_STONE_PICKAXE) - || (a_ItemID == E_ITEM_IRON_PICKAXE) - || (a_ItemID == E_ITEM_GOLD_PICKAXE) - || (a_ItemID == E_ITEM_DIAMOND_PICKAXE); - } - - - - inline bool IsAxe(ENUM_ITEM_ID a_ItemID) - { - return (a_ItemID == E_ITEM_WOODEN_AXE) - || (a_ItemID == E_ITEM_STONE_AXE) - || (a_ItemID == E_ITEM_IRON_AXE) - || (a_ItemID == E_ITEM_GOLD_AXE) - || (a_ItemID == E_ITEM_DIAMOND_AXE); - } - - - - inline bool IsSword(ENUM_ITEM_ID a_ItemID) - { - return (a_ItemID == E_ITEM_WOODEN_SWORD) - || (a_ItemID == E_ITEM_STONE_SWORD) - || (a_ItemID == E_ITEM_IRON_SWORD) - || (a_ItemID == E_ITEM_GOLD_SWORD) - || (a_ItemID == E_ITEM_DIAMOND_SWORD); - } - - - - inline bool IsHoe(ENUM_ITEM_ID a_ItemID) - { - return (a_ItemID == E_ITEM_WOODEN_HOE) - || (a_ItemID == E_ITEM_STONE_HOE) - || (a_ItemID == E_ITEM_IRON_HOE) - || (a_ItemID == E_ITEM_GOLD_HOE) - || (a_ItemID == E_ITEM_DIAMOND_HOE); - } - - - - inline bool IsShovel(ENUM_ITEM_ID a_ItemID) - { - return (a_ItemID == E_ITEM_WOODEN_SHOVEL) - || (a_ItemID == E_ITEM_STONE_SHOVEL) - || (a_ItemID == E_ITEM_IRON_SHOVEL) - || (a_ItemID == E_ITEM_GOLD_SHOVEL) - || (a_ItemID == E_ITEM_DIAMOND_SHOVEL); - } - - - - inline bool IsTool(ENUM_ITEM_ID a_ItemID) - { - return IsPickaxe( a_ItemID ) - || IsAxe ( a_ItemID ) - || IsSword ( a_ItemID ) - || IsHoe ( a_ItemID ) - || IsShovel ( a_ItemID ); - } -} -//tolua_end - - - - -//tolua_begin -enum eGameMode -{ - eGameMode_Survival = 0, - eGameMode_Creative = 1, -}; - - - - - -enum eWeather -{ - eWeather_Sunny = 0, - eWeather_Rain = 1, - eWeather_ThunderStorm = 2, - -}; - - - - -//tolua_end - - - - +#pragma once + +#include "BlockID.h" + +//tolua_begin +// emissive blocks +extern unsigned char g_BlockLightValue[]; +// whether blocks allow spreading +extern unsigned char g_BlockSpreadLightFalloff[]; +// whether blocks are transparent (light can shine though) +extern bool g_BlockTransparent[]; +// one hit break blocks +extern bool g_BlockOneHitDig[]; +//tolua_end + +//--DO NOT DELETE THIS COMMENT-- //tolua_export + + + + + +inline bool IsValidBlock( int a_BlockID ) //tolua_export +{ //tolua_export + if( a_BlockID > -1 && + a_BlockID <= 126 && //items to 109 are valid for Beta1.8.1.. 1.2.5 is up to 126 + //a_BlockID != 29 && allow pistons + //a_BlockID != 33 && allow pistons + a_BlockID != 34 && + a_BlockID != 36 ) + { + return true; + } + return false; +} //tolua_export + + + + + +// Was old :o +// Changed to fit the style ;) +inline bool IsValidItem( int a_ItemID ) //tolua_export +{ //tolua_export + if( (a_ItemID >= 256 && a_ItemID <= 388) + || (a_ItemID >= 2256 && a_ItemID <= 2266) ) + { + return true; + } + + if( a_ItemID == 0 ) + return false; + + return IsValidBlock( a_ItemID ); +} //tolua_export + + + + + +inline bool IsBlockWater(char a_BlockID) +{ + return (a_BlockID == E_BLOCK_WATER || a_BlockID == E_BLOCK_STATIONARY_WATER); +} + + + + + +inline bool IsBlockLava(char a_BlockID) +{ + return (a_BlockID == E_BLOCK_LAVA || a_BlockID == E_BLOCK_STATIONARY_LAVA); +} + + + + + +inline void AddDirection( int & a_X, int & a_Y, int & a_Z, char a_Direction, bool a_bInverse = false ) +{ + if( !a_bInverse ) + { + switch( a_Direction ) + { + case 0: + a_Y--; + break; + case 1: + a_Y++; + break; + case 2: + a_Z--; + break; + case 3: + a_Z++; + break; + case 4: + a_X--; + break; + case 5: + a_X++; + break; + }; + } + else + { + switch( a_Direction ) // other way around + { + case 0: + a_Y++; + break; + case 1: + a_Y--; + break; + case 2: + a_Z++; + break; + case 3: + a_Z--; + break; + case 4: + a_X++; + break; + case 5: + a_X--; + break; + }; + } +} + + + + + +inline void AddDirection( int & a_X, unsigned char & a_Y, int & a_Z, char a_Direction, bool a_bInverse = false ) //tolua_export +{//tolua_export + int Y = a_Y; + AddDirection( a_X, Y, a_Z, a_Direction, a_bInverse ); + if( Y < 0 ) a_Y = 0; + else if( Y > 255 ) a_Y = 255; + else a_Y = (unsigned char)Y; +}//tolua_export + + + + + +#include +#define PI 3.14159265358979323846264338327950288419716939937510582097494459072381640628620899862803482534211706798f +#define MIN(a,b) (((a)>(b))?(b):(a)) +#define MAX(a,b) (((a)>(b))?(a):(b)) +inline void EulerToVector( float a_Pan, float a_Pitch, float & a_X, float & a_Y, float & a_Z ) +{ + // a_X = sinf ( a_Pan / 180 * PI ) * cosf ( a_Pitch / 180 * PI ); + // a_Y = -sinf ( a_Pitch / 180 * PI ); + // a_Z = -cosf ( a_Pan / 180 * PI ) * cosf ( a_Pitch / 180 * PI ); + a_X = cos(a_Pan / 180 * PI)*cos(a_Pitch / 180 * PI); + a_Y = sin(a_Pan / 180 * PI)*cos(a_Pitch / 180 * PI); + a_Z = sin(a_Pitch / 180 * PI); +} + + + + + +inline void VectorToEuler( float a_X, float a_Y, float a_Z, float & a_Pan, float & a_Pitch ) +{ + if( a_X != 0 ) + a_Pan = atan2( a_Z, a_X ) * 180 / PI - 90; + else + a_Pan = 0; + a_Pitch = atan2(a_Y, sqrtf((a_X * a_X) + (a_Z * a_Z))) * 180 / PI; +} + + + + + +inline float GetSignf( float a_Val ) +{ + return (a_Val < 0.f)?-1.f:1.f; +} + + + + + +inline float GetSpecialSignf( float a_Val ) +{ + return (a_Val <= 0.f)?-1.f:1.f; +} + + + + +//tolua_begin +namespace ItemCategory +{ + inline bool IsPickaxe(ENUM_ITEM_ID a_ItemID) + { + return (a_ItemID == E_ITEM_WOODEN_PICKAXE) + || (a_ItemID == E_ITEM_STONE_PICKAXE) + || (a_ItemID == E_ITEM_IRON_PICKAXE) + || (a_ItemID == E_ITEM_GOLD_PICKAXE) + || (a_ItemID == E_ITEM_DIAMOND_PICKAXE); + } + + + + inline bool IsAxe(ENUM_ITEM_ID a_ItemID) + { + return (a_ItemID == E_ITEM_WOODEN_AXE) + || (a_ItemID == E_ITEM_STONE_AXE) + || (a_ItemID == E_ITEM_IRON_AXE) + || (a_ItemID == E_ITEM_GOLD_AXE) + || (a_ItemID == E_ITEM_DIAMOND_AXE); + } + + + + inline bool IsSword(ENUM_ITEM_ID a_ItemID) + { + return (a_ItemID == E_ITEM_WOODEN_SWORD) + || (a_ItemID == E_ITEM_STONE_SWORD) + || (a_ItemID == E_ITEM_IRON_SWORD) + || (a_ItemID == E_ITEM_GOLD_SWORD) + || (a_ItemID == E_ITEM_DIAMOND_SWORD); + } + + + + inline bool IsHoe(ENUM_ITEM_ID a_ItemID) + { + return (a_ItemID == E_ITEM_WOODEN_HOE) + || (a_ItemID == E_ITEM_STONE_HOE) + || (a_ItemID == E_ITEM_IRON_HOE) + || (a_ItemID == E_ITEM_GOLD_HOE) + || (a_ItemID == E_ITEM_DIAMOND_HOE); + } + + + + inline bool IsShovel(ENUM_ITEM_ID a_ItemID) + { + return (a_ItemID == E_ITEM_WOODEN_SHOVEL) + || (a_ItemID == E_ITEM_STONE_SHOVEL) + || (a_ItemID == E_ITEM_IRON_SHOVEL) + || (a_ItemID == E_ITEM_GOLD_SHOVEL) + || (a_ItemID == E_ITEM_DIAMOND_SHOVEL); + } + + + + inline bool IsTool(ENUM_ITEM_ID a_ItemID) + { + return IsPickaxe( a_ItemID ) + || IsAxe ( a_ItemID ) + || IsSword ( a_ItemID ) + || IsHoe ( a_ItemID ) + || IsShovel ( a_ItemID ); + } +} +//tolua_end + + + + +//tolua_begin +enum eGameMode +{ + eGameMode_Survival = 0, + eGameMode_Creative = 1, +}; + + + + + +enum eWeather +{ + eWeather_Sunny = 0, + eWeather_Rain = 1, + eWeather_ThunderStorm = 2, + +}; + + + + +//tolua_end + + + + diff --git a/source/Endianness.h b/source/Endianness.h index d2c6a8a0a..86eb369f5 100644 --- a/source/Endianness.h +++ b/source/Endianness.h @@ -1,70 +1,70 @@ - -#pragma once - - - - - -// Changes endianness -inline unsigned long long HostToNetwork8(const void* a_Value ) -{ - unsigned long long __HostToNetwork8; - memcpy( &__HostToNetwork8, a_Value, sizeof( __HostToNetwork8 ) ); - __HostToNetwork8 = (( ( (unsigned long long)htonl((u_long)__HostToNetwork8) ) << 32) + htonl(__HostToNetwork8 >> 32)); - return __HostToNetwork8; -} - - - - - -inline unsigned int HostToNetwork4(const void* a_Value ) -{ - unsigned int __HostToNetwork4; - memcpy( &__HostToNetwork4, a_Value, sizeof( __HostToNetwork4 ) ); - __HostToNetwork4 = ntohl( __HostToNetwork4 ); - return __HostToNetwork4; -} - - - - - -inline double NetworkToHostDouble8(const void* a_Value ) -{ -#define ntohll(x) ((((unsigned long long)ntohl((u_long)x)) << 32) + ntohl(x >> 32)) - unsigned long long buf = 0;//(*(unsigned long long*)a_Value); - memcpy( &buf, a_Value, 8 ); - buf = ntohll(buf); - double x; - memcpy(&x, &buf, sizeof(double)); - return x; -} - - - - - -inline long long NetworkToHostLong8(const void * a_Value ) -{ - unsigned long long buf = *(unsigned long long*)a_Value; - buf = ntohll(buf); - return *reinterpret_cast(&buf); -} - - - - - -inline float NetworkToHostFloat4(const void* a_Value ) -{ - u_long buf = *(u_long*)a_Value; - buf = ntohl( buf ); - float x = 0; - memcpy( &x, &buf, sizeof(float) ); - return x; -} - - - - + +#pragma once + + + + + +// Changes endianness +inline unsigned long long HostToNetwork8(const void* a_Value ) +{ + unsigned long long __HostToNetwork8; + memcpy( &__HostToNetwork8, a_Value, sizeof( __HostToNetwork8 ) ); + __HostToNetwork8 = (( ( (unsigned long long)htonl((u_long)__HostToNetwork8) ) << 32) + htonl(__HostToNetwork8 >> 32)); + return __HostToNetwork8; +} + + + + + +inline unsigned int HostToNetwork4(const void* a_Value ) +{ + unsigned int __HostToNetwork4; + memcpy( &__HostToNetwork4, a_Value, sizeof( __HostToNetwork4 ) ); + __HostToNetwork4 = ntohl( __HostToNetwork4 ); + return __HostToNetwork4; +} + + + + + +inline double NetworkToHostDouble8(const void* a_Value ) +{ +#define ntohll(x) ((((unsigned long long)ntohl((u_long)x)) << 32) + ntohl(x >> 32)) + unsigned long long buf = 0;//(*(unsigned long long*)a_Value); + memcpy( &buf, a_Value, 8 ); + buf = ntohll(buf); + double x; + memcpy(&x, &buf, sizeof(double)); + return x; +} + + + + + +inline long long NetworkToHostLong8(const void * a_Value ) +{ + unsigned long long buf = *(unsigned long long*)a_Value; + buf = ntohll(buf); + return *reinterpret_cast(&buf); +} + + + + + +inline float NetworkToHostFloat4(const void* a_Value ) +{ + u_long buf = *(u_long*)a_Value; + buf = ntohl( buf ); + float x = 0; + memcpy( &x, &buf, sizeof(float) ); + return x; +} + + + + diff --git a/source/FastNBT.cpp b/source/FastNBT.cpp index 9854fe3bc..773aecf62 100644 --- a/source/FastNBT.cpp +++ b/source/FastNBT.cpp @@ -1,530 +1,530 @@ - -// FastNBT.cpp - -// Implements the fast NBT parser and writer - -#include "Globals.h" -#include "FastNBT.h" - - - - - -#define RETURN_FALSE_IF_FALSE(X) do { if (!X) return false; } while (0) - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cParsedNBT: - -#define NEEDBYTES(N) \ - if (m_Length - m_Pos < N) \ - { \ - return false; \ - } - - - - - -cParsedNBT::cParsedNBT(const char * a_Data, int a_Length) : - m_Data(a_Data), - m_Length(a_Length), - m_Pos(0) -{ - m_IsValid = Parse(); -} - - - - - -bool cParsedNBT::Parse(void) -{ - if (m_Length < 3) - { - // Data too short - return false; - } - if (m_Data[0] != TAG_Compound) - { - // The top-level tag must be a Compound - return false; - } - - m_Tags.reserve(200); - - m_Tags.push_back(cFastNBTTag(TAG_Compound, -1)); - - m_Pos = 1; - - RETURN_FALSE_IF_FALSE(ReadString(m_Tags.back().m_NameStart, m_Tags.back().m_NameLength)); - RETURN_FALSE_IF_FALSE(ReadCompound()); - - return true; -} - - - - - -bool cParsedNBT::ReadString(int & a_StringStart, int & a_StringLen) -{ - NEEDBYTES(2); - a_StringStart = m_Pos + 2; - a_StringLen = ntohs(*((short *)(m_Data + m_Pos))); - if (a_StringLen < 0) - { - // Invalid string length - return false; - } - m_Pos += 2 + a_StringLen; - return true; -} - - - - - -bool cParsedNBT::ReadCompound(void) -{ - // Reads the latest tag as a compound - int ParentIdx = m_Tags.size() - 1; - int PrevSibling = -1; - while (true) - { - NEEDBYTES(1); - eTagType TagType = (eTagType)(m_Data[m_Pos]); - m_Pos++; - if (TagType == TAG_End) - { - break; - } - m_Tags.push_back(cFastNBTTag(TagType, ParentIdx, PrevSibling)); - if (PrevSibling >= 0) - { - m_Tags[PrevSibling].m_NextSibling = m_Tags.size() - 1; - } - else - { - m_Tags[ParentIdx].m_FirstChild = m_Tags.size() - 1; - } - PrevSibling = m_Tags.size() - 1; - RETURN_FALSE_IF_FALSE(ReadString(m_Tags.back().m_NameStart, m_Tags.back().m_NameLength)); - RETURN_FALSE_IF_FALSE(ReadTag()); - } // while (true) - m_Tags[ParentIdx].m_LastChild = PrevSibling; - return true; -} - - - - - -bool cParsedNBT::ReadList(eTagType a_ChildrenType) -{ - // Reads the latest tag as a list of items of type a_ChildrenType - - // Read the count: - NEEDBYTES(4); - int Count = ntohl(*((int *)(m_Data + m_Pos))); - m_Pos += 4; - if (Count < 0) - { - return false; - } - - // Read items: - int ParentIdx = m_Tags.size() - 1; - int PrevSibling = -1; - for (int i = 0; i < Count; i++) - { - m_Tags.push_back(cFastNBTTag(a_ChildrenType, ParentIdx, PrevSibling)); - if (PrevSibling >= 0) - { - m_Tags[PrevSibling].m_NextSibling = m_Tags.size() - 1; - } - else - { - m_Tags[ParentIdx].m_FirstChild = m_Tags.size() - 1; - } - PrevSibling = m_Tags.size() - 1; - RETURN_FALSE_IF_FALSE(ReadTag()); - } // for (i) - m_Tags[ParentIdx].m_LastChild = PrevSibling; - return true; -} - - - - - -#define CASE_SIMPLE_TAG(TAGTYPE, LEN) \ - case TAG_##TAGTYPE: \ - { \ - NEEDBYTES(LEN); \ - Tag.m_DataStart = m_Pos; \ - Tag.m_DataLength = LEN; \ - m_Pos += LEN; \ - return true; \ - } - -bool cParsedNBT::ReadTag(void) -{ - cFastNBTTag & Tag = m_Tags.back(); - switch (Tag.m_Type) - { - CASE_SIMPLE_TAG(Byte, 1) - CASE_SIMPLE_TAG(Short, 2) - CASE_SIMPLE_TAG(Int, 4) - CASE_SIMPLE_TAG(Long, 8) - CASE_SIMPLE_TAG(Float, 4) - CASE_SIMPLE_TAG(Double, 8) - - case TAG_String: - { - return ReadString(Tag.m_DataStart, Tag.m_DataLength); - } - - case TAG_ByteArray: - { - NEEDBYTES(4); - int len = ntohl(*((int *)(m_Data + m_Pos))); - m_Pos += 4; - if (len < 0) - { - // Invalid length - return false; - } - NEEDBYTES(len); - Tag.m_DataLength = len; - Tag.m_DataStart = m_Pos; - m_Pos += len; - return true; - } - - case TAG_List: - { - NEEDBYTES(1); - eTagType ItemType = (eTagType)m_Data[m_Pos]; - m_Pos++; - RETURN_FALSE_IF_FALSE(ReadList(ItemType)); - return true; - } - - case TAG_Compound: - { - RETURN_FALSE_IF_FALSE(ReadCompound()); - return true; - } - - case TAG_IntArray: - { - NEEDBYTES(4); - int len = ntohl(*((int *)(m_Data + m_Pos))); - m_Pos += 4; - if (len < 0) - { - // Invalid length - return false; - } - len *= 4; - NEEDBYTES(len); - Tag.m_DataLength = len; - Tag.m_DataStart = m_Pos; - m_Pos += len; - return true; - } - - default: - { - ASSERT(!"Unhandled NBT tag type"); - return false; - } - } // switch (iType) -} - -#undef CASE_SIMPLE_TAG - - - - - -int cParsedNBT::FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLength) const -{ - if (a_Tag < 0) - { - return -1; - } - if (m_Tags[a_Tag].m_Type != TAG_Compound) - { - return -1; - } - - if (a_NameLength == 0) - { - a_NameLength = strlen(a_Name); - } - for (int Child = m_Tags[a_Tag].m_FirstChild; Child != -1; Child = m_Tags[Child].m_NextSibling) - { - if ( - (m_Tags[Child].m_NameLength == a_NameLength) && - (memcmp(m_Data + m_Tags[Child].m_NameStart, a_Name, a_NameLength) == 0) - ) - { - return Child; - } - } // for Child - children of a_Tag - return -1; -} - - - - - -int cParsedNBT::FindTagByPath(int a_Tag, const AString & a_Path) const -{ - if (a_Tag < 0) - { - return -1; - } - size_t Begin = 0; - size_t Length = a_Path.length(); - int Tag = a_Tag; - for (size_t i = 0; i < Length; i++) - { - if (a_Path[i] != '\\') - { - continue; - } - Tag = FindChildByName(Tag, a_Path.c_str() + Begin, i - Begin - 1); - if (Tag < 0) - { - return -1; - } - Begin = i + 1; - } // for i - a_Path[] - - if (Begin < Length) - { - Tag = FindChildByName(Tag, a_Path.c_str() + Begin, Length - Begin); - } - return Tag; -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cFastNBTWriter: - -cFastNBTWriter::cFastNBTWriter(void) : - m_CurrentStack(0) -{ - m_Stack[0].m_Type = TAG_Compound; - m_Result.reserve(100 * 1024); - m_Result.push_back(TAG_Compound); - WriteString("", 0); -} - - - - - -void cFastNBTWriter::BeginCompound(const AString & a_Name) -{ - if (m_CurrentStack >= MAX_STACK) - { - ASSERT(!"Stack overflow"); - return; - } - - TagCommon(a_Name, TAG_Compound); - - ++m_CurrentStack; - m_Stack[m_CurrentStack].m_Type = TAG_Compound; -} - - - - - -void cFastNBTWriter::EndCompound(void) -{ - ASSERT(m_CurrentStack > 0); - ASSERT(IsStackTopCompound()); - - m_Result.push_back(TAG_End); - --m_CurrentStack; -} - - - - - -void cFastNBTWriter::BeginList(const AString & a_Name, eTagType a_ChildrenType) -{ - if (m_CurrentStack >= MAX_STACK) - { - ASSERT(!"Stack overflow"); - return; - } - - TagCommon(a_Name, TAG_List); - - m_Result.push_back((char)a_ChildrenType); - m_Result.append(4, (char)0); - - ++m_CurrentStack; - m_Stack[m_CurrentStack].m_Type = TAG_List; - m_Stack[m_CurrentStack].m_Pos = m_Result.size() - 4; - m_Stack[m_CurrentStack].m_Count = 0; -} - - - - - -void cFastNBTWriter::EndList(void) -{ - ASSERT(m_CurrentStack > 0); - ASSERT(m_Stack[m_CurrentStack].m_Type == TAG_List); - - // Update the list count: - *((int *)(m_Result.c_str() + m_Stack[m_CurrentStack].m_Pos)) = htonl(m_Stack[m_CurrentStack].m_Count); - - --m_CurrentStack; -} - - - - - -void cFastNBTWriter::AddByte(const AString & a_Name, unsigned char a_Value) -{ - TagCommon(a_Name, TAG_Byte); - m_Result.push_back(a_Value); -} - - - - - -void cFastNBTWriter::AddShort(const AString & a_Name, Int16 a_Value) -{ - TagCommon(a_Name, TAG_Short); - Int16 Value = htons(a_Value); - m_Result.append((const char *)&Value, 2); -} - - - - - -void cFastNBTWriter::AddInt(const AString & a_Name, Int32 a_Value) -{ - TagCommon(a_Name, TAG_Int); - Int32 Value = htonl(a_Value); - m_Result.append((const char *)&Value, 4); -} - - - - - -void cFastNBTWriter::AddLong(const AString & a_Name, Int64 a_Value) -{ - TagCommon(a_Name, TAG_Long); - Int64 Value = HostToNetwork8(&a_Value); - m_Result.append((const char *)&Value, 8); -} - - - - - -void cFastNBTWriter::AddFloat(const AString & a_Name, float a_Value) -{ - TagCommon(a_Name, TAG_Float); - Int32 Value = HostToNetwork4(&a_Value); - m_Result.append((const char *)&Value, 4); -} - - - - - -void cFastNBTWriter::AddDouble(const AString & a_Name, double a_Value) -{ - TagCommon(a_Name, TAG_Double); - Int64 Value = HostToNetwork8(&a_Value); - m_Result.append((const char *)&Value, 8); -} - - - - - -void cFastNBTWriter::AddString(const AString & a_Name, const AString & a_Value) -{ - TagCommon(a_Name, TAG_String); - Int16 len = htons((short)(a_Value.size())); - m_Result.append((const char *)&len, 2); - m_Result.append(a_Value.c_str(), a_Value.size()); -} - - - - - -void cFastNBTWriter::AddByteArray(const AString & a_Name, const char * a_Value, size_t a_NumElements) -{ - TagCommon(a_Name, TAG_ByteArray); - Int32 len = htonl(a_NumElements); - m_Result.append((const char *)&len, 4); - m_Result.append(a_Value, a_NumElements); -} - - - - - -void cFastNBTWriter::AddIntArray(const AString & a_Name, const int * a_Value, size_t a_NumElements) -{ - TagCommon(a_Name, TAG_IntArray); - Int32 len = htonl(a_NumElements); - m_Result.append((const char *)&len, 2); - int * Elements = (int *)(m_Result.data() + m_Result.size()); - m_Result.append(a_NumElements * 4, (char)0); - for (size_t i = 0; i < a_NumElements; i++) - { - Elements[i] = htonl(a_Value[i]); - } -} - - - - -void cFastNBTWriter::Finish(void) -{ - ASSERT(m_CurrentStack == 0); - m_Result.push_back(TAG_End); -} - - - - - -void cFastNBTWriter::WriteString(const char * a_Data, short a_Length) -{ - Int16 Len = htons(a_Length); - m_Result.append((const char *)&Len, 2); - m_Result.append(a_Data, a_Length); -} - - - - + +// FastNBT.cpp + +// Implements the fast NBT parser and writer + +#include "Globals.h" +#include "FastNBT.h" + + + + + +#define RETURN_FALSE_IF_FALSE(X) do { if (!X) return false; } while (0) + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cParsedNBT: + +#define NEEDBYTES(N) \ + if (m_Length - m_Pos < N) \ + { \ + return false; \ + } + + + + + +cParsedNBT::cParsedNBT(const char * a_Data, int a_Length) : + m_Data(a_Data), + m_Length(a_Length), + m_Pos(0) +{ + m_IsValid = Parse(); +} + + + + + +bool cParsedNBT::Parse(void) +{ + if (m_Length < 3) + { + // Data too short + return false; + } + if (m_Data[0] != TAG_Compound) + { + // The top-level tag must be a Compound + return false; + } + + m_Tags.reserve(200); + + m_Tags.push_back(cFastNBTTag(TAG_Compound, -1)); + + m_Pos = 1; + + RETURN_FALSE_IF_FALSE(ReadString(m_Tags.back().m_NameStart, m_Tags.back().m_NameLength)); + RETURN_FALSE_IF_FALSE(ReadCompound()); + + return true; +} + + + + + +bool cParsedNBT::ReadString(int & a_StringStart, int & a_StringLen) +{ + NEEDBYTES(2); + a_StringStart = m_Pos + 2; + a_StringLen = ntohs(*((short *)(m_Data + m_Pos))); + if (a_StringLen < 0) + { + // Invalid string length + return false; + } + m_Pos += 2 + a_StringLen; + return true; +} + + + + + +bool cParsedNBT::ReadCompound(void) +{ + // Reads the latest tag as a compound + int ParentIdx = m_Tags.size() - 1; + int PrevSibling = -1; + while (true) + { + NEEDBYTES(1); + eTagType TagType = (eTagType)(m_Data[m_Pos]); + m_Pos++; + if (TagType == TAG_End) + { + break; + } + m_Tags.push_back(cFastNBTTag(TagType, ParentIdx, PrevSibling)); + if (PrevSibling >= 0) + { + m_Tags[PrevSibling].m_NextSibling = m_Tags.size() - 1; + } + else + { + m_Tags[ParentIdx].m_FirstChild = m_Tags.size() - 1; + } + PrevSibling = m_Tags.size() - 1; + RETURN_FALSE_IF_FALSE(ReadString(m_Tags.back().m_NameStart, m_Tags.back().m_NameLength)); + RETURN_FALSE_IF_FALSE(ReadTag()); + } // while (true) + m_Tags[ParentIdx].m_LastChild = PrevSibling; + return true; +} + + + + + +bool cParsedNBT::ReadList(eTagType a_ChildrenType) +{ + // Reads the latest tag as a list of items of type a_ChildrenType + + // Read the count: + NEEDBYTES(4); + int Count = ntohl(*((int *)(m_Data + m_Pos))); + m_Pos += 4; + if (Count < 0) + { + return false; + } + + // Read items: + int ParentIdx = m_Tags.size() - 1; + int PrevSibling = -1; + for (int i = 0; i < Count; i++) + { + m_Tags.push_back(cFastNBTTag(a_ChildrenType, ParentIdx, PrevSibling)); + if (PrevSibling >= 0) + { + m_Tags[PrevSibling].m_NextSibling = m_Tags.size() - 1; + } + else + { + m_Tags[ParentIdx].m_FirstChild = m_Tags.size() - 1; + } + PrevSibling = m_Tags.size() - 1; + RETURN_FALSE_IF_FALSE(ReadTag()); + } // for (i) + m_Tags[ParentIdx].m_LastChild = PrevSibling; + return true; +} + + + + + +#define CASE_SIMPLE_TAG(TAGTYPE, LEN) \ + case TAG_##TAGTYPE: \ + { \ + NEEDBYTES(LEN); \ + Tag.m_DataStart = m_Pos; \ + Tag.m_DataLength = LEN; \ + m_Pos += LEN; \ + return true; \ + } + +bool cParsedNBT::ReadTag(void) +{ + cFastNBTTag & Tag = m_Tags.back(); + switch (Tag.m_Type) + { + CASE_SIMPLE_TAG(Byte, 1) + CASE_SIMPLE_TAG(Short, 2) + CASE_SIMPLE_TAG(Int, 4) + CASE_SIMPLE_TAG(Long, 8) + CASE_SIMPLE_TAG(Float, 4) + CASE_SIMPLE_TAG(Double, 8) + + case TAG_String: + { + return ReadString(Tag.m_DataStart, Tag.m_DataLength); + } + + case TAG_ByteArray: + { + NEEDBYTES(4); + int len = ntohl(*((int *)(m_Data + m_Pos))); + m_Pos += 4; + if (len < 0) + { + // Invalid length + return false; + } + NEEDBYTES(len); + Tag.m_DataLength = len; + Tag.m_DataStart = m_Pos; + m_Pos += len; + return true; + } + + case TAG_List: + { + NEEDBYTES(1); + eTagType ItemType = (eTagType)m_Data[m_Pos]; + m_Pos++; + RETURN_FALSE_IF_FALSE(ReadList(ItemType)); + return true; + } + + case TAG_Compound: + { + RETURN_FALSE_IF_FALSE(ReadCompound()); + return true; + } + + case TAG_IntArray: + { + NEEDBYTES(4); + int len = ntohl(*((int *)(m_Data + m_Pos))); + m_Pos += 4; + if (len < 0) + { + // Invalid length + return false; + } + len *= 4; + NEEDBYTES(len); + Tag.m_DataLength = len; + Tag.m_DataStart = m_Pos; + m_Pos += len; + return true; + } + + default: + { + ASSERT(!"Unhandled NBT tag type"); + return false; + } + } // switch (iType) +} + +#undef CASE_SIMPLE_TAG + + + + + +int cParsedNBT::FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLength) const +{ + if (a_Tag < 0) + { + return -1; + } + if (m_Tags[a_Tag].m_Type != TAG_Compound) + { + return -1; + } + + if (a_NameLength == 0) + { + a_NameLength = strlen(a_Name); + } + for (int Child = m_Tags[a_Tag].m_FirstChild; Child != -1; Child = m_Tags[Child].m_NextSibling) + { + if ( + (m_Tags[Child].m_NameLength == a_NameLength) && + (memcmp(m_Data + m_Tags[Child].m_NameStart, a_Name, a_NameLength) == 0) + ) + { + return Child; + } + } // for Child - children of a_Tag + return -1; +} + + + + + +int cParsedNBT::FindTagByPath(int a_Tag, const AString & a_Path) const +{ + if (a_Tag < 0) + { + return -1; + } + size_t Begin = 0; + size_t Length = a_Path.length(); + int Tag = a_Tag; + for (size_t i = 0; i < Length; i++) + { + if (a_Path[i] != '\\') + { + continue; + } + Tag = FindChildByName(Tag, a_Path.c_str() + Begin, i - Begin - 1); + if (Tag < 0) + { + return -1; + } + Begin = i + 1; + } // for i - a_Path[] + + if (Begin < Length) + { + Tag = FindChildByName(Tag, a_Path.c_str() + Begin, Length - Begin); + } + return Tag; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cFastNBTWriter: + +cFastNBTWriter::cFastNBTWriter(void) : + m_CurrentStack(0) +{ + m_Stack[0].m_Type = TAG_Compound; + m_Result.reserve(100 * 1024); + m_Result.push_back(TAG_Compound); + WriteString("", 0); +} + + + + + +void cFastNBTWriter::BeginCompound(const AString & a_Name) +{ + if (m_CurrentStack >= MAX_STACK) + { + ASSERT(!"Stack overflow"); + return; + } + + TagCommon(a_Name, TAG_Compound); + + ++m_CurrentStack; + m_Stack[m_CurrentStack].m_Type = TAG_Compound; +} + + + + + +void cFastNBTWriter::EndCompound(void) +{ + ASSERT(m_CurrentStack > 0); + ASSERT(IsStackTopCompound()); + + m_Result.push_back(TAG_End); + --m_CurrentStack; +} + + + + + +void cFastNBTWriter::BeginList(const AString & a_Name, eTagType a_ChildrenType) +{ + if (m_CurrentStack >= MAX_STACK) + { + ASSERT(!"Stack overflow"); + return; + } + + TagCommon(a_Name, TAG_List); + + m_Result.push_back((char)a_ChildrenType); + m_Result.append(4, (char)0); + + ++m_CurrentStack; + m_Stack[m_CurrentStack].m_Type = TAG_List; + m_Stack[m_CurrentStack].m_Pos = m_Result.size() - 4; + m_Stack[m_CurrentStack].m_Count = 0; +} + + + + + +void cFastNBTWriter::EndList(void) +{ + ASSERT(m_CurrentStack > 0); + ASSERT(m_Stack[m_CurrentStack].m_Type == TAG_List); + + // Update the list count: + *((int *)(m_Result.c_str() + m_Stack[m_CurrentStack].m_Pos)) = htonl(m_Stack[m_CurrentStack].m_Count); + + --m_CurrentStack; +} + + + + + +void cFastNBTWriter::AddByte(const AString & a_Name, unsigned char a_Value) +{ + TagCommon(a_Name, TAG_Byte); + m_Result.push_back(a_Value); +} + + + + + +void cFastNBTWriter::AddShort(const AString & a_Name, Int16 a_Value) +{ + TagCommon(a_Name, TAG_Short); + Int16 Value = htons(a_Value); + m_Result.append((const char *)&Value, 2); +} + + + + + +void cFastNBTWriter::AddInt(const AString & a_Name, Int32 a_Value) +{ + TagCommon(a_Name, TAG_Int); + Int32 Value = htonl(a_Value); + m_Result.append((const char *)&Value, 4); +} + + + + + +void cFastNBTWriter::AddLong(const AString & a_Name, Int64 a_Value) +{ + TagCommon(a_Name, TAG_Long); + Int64 Value = HostToNetwork8(&a_Value); + m_Result.append((const char *)&Value, 8); +} + + + + + +void cFastNBTWriter::AddFloat(const AString & a_Name, float a_Value) +{ + TagCommon(a_Name, TAG_Float); + Int32 Value = HostToNetwork4(&a_Value); + m_Result.append((const char *)&Value, 4); +} + + + + + +void cFastNBTWriter::AddDouble(const AString & a_Name, double a_Value) +{ + TagCommon(a_Name, TAG_Double); + Int64 Value = HostToNetwork8(&a_Value); + m_Result.append((const char *)&Value, 8); +} + + + + + +void cFastNBTWriter::AddString(const AString & a_Name, const AString & a_Value) +{ + TagCommon(a_Name, TAG_String); + Int16 len = htons((short)(a_Value.size())); + m_Result.append((const char *)&len, 2); + m_Result.append(a_Value.c_str(), a_Value.size()); +} + + + + + +void cFastNBTWriter::AddByteArray(const AString & a_Name, const char * a_Value, size_t a_NumElements) +{ + TagCommon(a_Name, TAG_ByteArray); + Int32 len = htonl(a_NumElements); + m_Result.append((const char *)&len, 4); + m_Result.append(a_Value, a_NumElements); +} + + + + + +void cFastNBTWriter::AddIntArray(const AString & a_Name, const int * a_Value, size_t a_NumElements) +{ + TagCommon(a_Name, TAG_IntArray); + Int32 len = htonl(a_NumElements); + m_Result.append((const char *)&len, 2); + int * Elements = (int *)(m_Result.data() + m_Result.size()); + m_Result.append(a_NumElements * 4, (char)0); + for (size_t i = 0; i < a_NumElements; i++) + { + Elements[i] = htonl(a_Value[i]); + } +} + + + + +void cFastNBTWriter::Finish(void) +{ + ASSERT(m_CurrentStack == 0); + m_Result.push_back(TAG_End); +} + + + + + +void cFastNBTWriter::WriteString(const char * a_Data, short a_Length) +{ + Int16 Len = htons(a_Length); + m_Result.append((const char *)&Len, 2); + m_Result.append(a_Data, a_Length); +} + + + + diff --git a/source/FastNBT.h b/source/FastNBT.h index f38bfcdbd..ca801b36f 100644 --- a/source/FastNBT.h +++ b/source/FastNBT.h @@ -1,274 +1,274 @@ - -// FastNBT.h - -// Interfaces to the fast NBT parser and writer - -/* -The fast parser parses the data into a vector of cFastNBTTag structures. These structures describe the NBT tree, -but themselves are allocated in a vector, thus minimizing reallocation. -The structures have a minimal constructor, setting all member "pointers" to "invalid". - -The fast writer doesn't need a NBT tree structure built beforehand, it is commanded to open, append and close tags -(just like XML); it keeps the internal tag stack and reports errors in usage. -It directly outputs a string containing the serialized NBT data. -*/ - - - - - -#pragma once - -#include "Endianness.h" - - - - - -enum eTagType -{ - TAG_Min = 0, // The minimum value for a tag type - TAG_End = 0, - TAG_Byte = 1, - TAG_Short = 2, - TAG_Int = 3, - TAG_Long = 4, - TAG_Float = 5, - TAG_Double = 6, - TAG_ByteArray = 7, - TAG_String = 8, - TAG_List = 9, - TAG_Compound = 10, - TAG_IntArray = 11, - TAG_Max = 11, // The maximum value for a tag type -} ; - - - - - -/** This structure is used for all NBT tags. -It contains indices to the parent array of tags, building the NBT tree this way. -Also contains indices into the data stream being parsed, used for values; -NO dynamically allocated memory is used! -Structure (all with the tree structure it describes) supports moving in memory (std::vector reallocation) -*/ -struct cFastNBTTag -{ -public: - - eTagType m_Type; - - // The following members are indices into the data stream. m_DataLength == 0 if no data available - // They must not be pointers, because the datastream may be copied into another AString object in the meantime. - int m_NameStart; - int m_NameLength; - int m_DataStart; - int m_DataLength; - - // The following members are indices into the array returned; -1 if not valid - // They must not be pointers, because pointers would not survive std::vector reallocation - int m_Parent; - int m_PrevSibling; - int m_NextSibling; - int m_FirstChild; - int m_LastChild; - - cFastNBTTag(eTagType a_Type, int a_Parent) : - m_Type(a_Type), - m_NameLength(0), - m_DataLength(0), - m_Parent(a_Parent), - m_PrevSibling(-1), - m_NextSibling(-1), - m_FirstChild(-1), - m_LastChild(-1) - { - } - - cFastNBTTag(eTagType a_Type, int a_Parent, int a_PrevSibling) : - m_Type(a_Type), - m_NameLength(0), - m_DataLength(0), - m_Parent(a_Parent), - m_PrevSibling(a_PrevSibling), - m_NextSibling(-1), - m_FirstChild(-1), - m_LastChild(-1) - { - } -} ; - - - - - -/** Parses and contains the parsed data -Also implements data accessor functions for tree traversal and value getters -The data pointer passed in the constructor is assumed to be valid throughout the object's life. Care must be taken not to initialize from a temporary. -*/ -class cParsedNBT -{ -public: - cParsedNBT(const char * a_Data, int a_Length); - - bool IsValid(void) const {return m_IsValid; } - - int GetRoot(void) const {return 0; } - int GetFirstChild (int a_Tag) const { return m_Tags[a_Tag].m_FirstChild; } - int GetLastChild (int a_Tag) const { return m_Tags[a_Tag].m_LastChild; } - int GetNextSibling(int a_Tag) const { return m_Tags[a_Tag].m_NextSibling; } - int GetPrevSibling(int a_Tag) const { return m_Tags[a_Tag].m_PrevSibling; } - int GetDataLength (int a_Tag) const { return m_Tags[a_Tag].m_DataLength; } - - const char * GetData(int a_Tag) const - { - ASSERT(m_Tags[a_Tag].m_Type != TAG_List); - ASSERT(m_Tags[a_Tag].m_Type != TAG_Compound); - return m_Data + m_Tags[a_Tag].m_DataStart; - } - - int FindChildByName(int a_Tag, const AString & a_Name) const - { - return FindChildByName(a_Tag, a_Name.c_str(), a_Name.length()); - } - - int FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLength = 0) const; - int FindTagByPath (int a_Tag, const AString & a_Path) const; - - eTagType GetType(int a_Tag) const { return m_Tags[a_Tag].m_Type; } - - /// Returns the children type for a list tag; undefined on other tags. If list empty, returns TAG_End - eTagType GetChildrenType(int a_Tag) const - { - ASSERT(m_Tags[a_Tag].m_Type == TAG_List); - return (m_Tags[a_Tag].m_FirstChild < 0) ? TAG_End : m_Tags[m_Tags[a_Tag].m_FirstChild].m_Type; - } - - inline unsigned char GetByte(int a_Tag) const - { - ASSERT(m_Tags[a_Tag].m_Type == TAG_Byte); - return (unsigned char)(m_Data[m_Tags[a_Tag].m_DataStart]); - } - - inline Int16 GetShort(int a_Tag) const - { - ASSERT(m_Tags[a_Tag].m_Type == TAG_Short); - return ntohs(*((Int16 *)(m_Data + m_Tags[a_Tag].m_DataStart))); - } - - inline Int32 GetInt(int a_Tag) const - { - ASSERT(m_Tags[a_Tag].m_Type == TAG_Int); - return ntohl(*((Int32 *)(m_Data + m_Tags[a_Tag].m_DataStart))); - } - - inline Int64 GetLong(int a_Tag) const - { - ASSERT(m_Tags[a_Tag].m_Type == TAG_Long); - return NetworkToHostLong8(m_Data + m_Tags[a_Tag].m_DataStart); - } - - inline float GetFloat(int a_Tag) const - { - ASSERT(m_Tags[a_Tag].m_Type == TAG_Float); - Int32 tmp = ntohl(*((Int32 *)(m_Data + m_Tags[a_Tag].m_DataStart))); - return *((float *)&tmp); - } - - inline double GetDouble(int a_Tag) const - { - ASSERT(m_Tags[a_Tag].m_Type == TAG_Double); - return NetworkToHostDouble8(m_Data + m_Tags[a_Tag].m_DataStart); - } - -protected: - const char * m_Data; - int m_Length; - std::vector m_Tags; - bool m_IsValid; // True if parsing succeeded - - // Used while parsing: - int m_Pos; - - bool Parse(void); - bool ReadString(int & a_StringStart, int & a_StringLen); // Reads a simple string (2 bytes length + data), sets the string descriptors - bool ReadCompound(void); // Reads the latest tag as a compound - bool ReadList(eTagType a_ChildrenType); // Reads the latest tag as a list of items of type a_ChildrenType - bool ReadTag(void); // Reads the latest tag, depending on its m_Type setting -} ; - - - - - -class cFastNBTWriter -{ -public: - cFastNBTWriter(void); - - void BeginCompound(const AString & a_Name); - void EndCompound(void); - - void BeginList(const AString & a_Name, eTagType a_ChildrenType); - void EndList(void); - - void AddByte (const AString & a_Name, unsigned char a_Value); - void AddShort (const AString & a_Name, Int16 a_Value); - void AddInt (const AString & a_Name, Int32 a_Value); - void AddLong (const AString & a_Name, Int64 a_Value); - void AddFloat (const AString & a_Name, float a_Value); - void AddDouble (const AString & a_Name, double a_Value); - void AddString (const AString & a_Name, const AString & a_Value); - void AddByteArray(const AString & a_Name, const char * a_Value, size_t a_NumElements); - void AddIntArray (const AString & a_Name, const int * a_Value, size_t a_NumElements); - - void AddByteArray(const AString & a_Name, const AString & a_Value) - { - AddByteArray(a_Name, a_Value.data(), a_Value.size()); - } - - const AString & GetResult(void) const {return m_Result; } - - void Finish(void); - -protected: - - struct sParent - { - int m_Type; // TAG_Compound or TAG_List - int m_Pos; // for TAG_List, the position of the list count - int m_Count; // for TAG_List, the element count - } ; - - static const int MAX_STACK = 50; // Highliy doubtful that an NBT would be constructed this many levels deep - - // These two fields emulate a stack. A raw array is used due to speed issues - no reallocations are allowed. - sParent m_Stack[MAX_STACK]; - int m_CurrentStack; - - AString m_Result; - - bool IsStackTopCompound(void) const { return (m_Stack[m_CurrentStack].m_Type == TAG_Compound); } - - void WriteString(const char * a_Data, short a_Length); - - inline void TagCommon(const AString & a_Name, eTagType a_Type) - { - if (IsStackTopCompound()) - { - // Compound: add the type and name: - m_Result.push_back((char)a_Type); - WriteString(a_Name.c_str(), (short)a_Name.length()); - } - else - { - // List: add to the counter - m_Stack[m_CurrentStack].m_Count++; - } - } -} ; - - - - + +// FastNBT.h + +// Interfaces to the fast NBT parser and writer + +/* +The fast parser parses the data into a vector of cFastNBTTag structures. These structures describe the NBT tree, +but themselves are allocated in a vector, thus minimizing reallocation. +The structures have a minimal constructor, setting all member "pointers" to "invalid". + +The fast writer doesn't need a NBT tree structure built beforehand, it is commanded to open, append and close tags +(just like XML); it keeps the internal tag stack and reports errors in usage. +It directly outputs a string containing the serialized NBT data. +*/ + + + + + +#pragma once + +#include "Endianness.h" + + + + + +enum eTagType +{ + TAG_Min = 0, // The minimum value for a tag type + TAG_End = 0, + TAG_Byte = 1, + TAG_Short = 2, + TAG_Int = 3, + TAG_Long = 4, + TAG_Float = 5, + TAG_Double = 6, + TAG_ByteArray = 7, + TAG_String = 8, + TAG_List = 9, + TAG_Compound = 10, + TAG_IntArray = 11, + TAG_Max = 11, // The maximum value for a tag type +} ; + + + + + +/** This structure is used for all NBT tags. +It contains indices to the parent array of tags, building the NBT tree this way. +Also contains indices into the data stream being parsed, used for values; +NO dynamically allocated memory is used! +Structure (all with the tree structure it describes) supports moving in memory (std::vector reallocation) +*/ +struct cFastNBTTag +{ +public: + + eTagType m_Type; + + // The following members are indices into the data stream. m_DataLength == 0 if no data available + // They must not be pointers, because the datastream may be copied into another AString object in the meantime. + int m_NameStart; + int m_NameLength; + int m_DataStart; + int m_DataLength; + + // The following members are indices into the array returned; -1 if not valid + // They must not be pointers, because pointers would not survive std::vector reallocation + int m_Parent; + int m_PrevSibling; + int m_NextSibling; + int m_FirstChild; + int m_LastChild; + + cFastNBTTag(eTagType a_Type, int a_Parent) : + m_Type(a_Type), + m_NameLength(0), + m_DataLength(0), + m_Parent(a_Parent), + m_PrevSibling(-1), + m_NextSibling(-1), + m_FirstChild(-1), + m_LastChild(-1) + { + } + + cFastNBTTag(eTagType a_Type, int a_Parent, int a_PrevSibling) : + m_Type(a_Type), + m_NameLength(0), + m_DataLength(0), + m_Parent(a_Parent), + m_PrevSibling(a_PrevSibling), + m_NextSibling(-1), + m_FirstChild(-1), + m_LastChild(-1) + { + } +} ; + + + + + +/** Parses and contains the parsed data +Also implements data accessor functions for tree traversal and value getters +The data pointer passed in the constructor is assumed to be valid throughout the object's life. Care must be taken not to initialize from a temporary. +*/ +class cParsedNBT +{ +public: + cParsedNBT(const char * a_Data, int a_Length); + + bool IsValid(void) const {return m_IsValid; } + + int GetRoot(void) const {return 0; } + int GetFirstChild (int a_Tag) const { return m_Tags[a_Tag].m_FirstChild; } + int GetLastChild (int a_Tag) const { return m_Tags[a_Tag].m_LastChild; } + int GetNextSibling(int a_Tag) const { return m_Tags[a_Tag].m_NextSibling; } + int GetPrevSibling(int a_Tag) const { return m_Tags[a_Tag].m_PrevSibling; } + int GetDataLength (int a_Tag) const { return m_Tags[a_Tag].m_DataLength; } + + const char * GetData(int a_Tag) const + { + ASSERT(m_Tags[a_Tag].m_Type != TAG_List); + ASSERT(m_Tags[a_Tag].m_Type != TAG_Compound); + return m_Data + m_Tags[a_Tag].m_DataStart; + } + + int FindChildByName(int a_Tag, const AString & a_Name) const + { + return FindChildByName(a_Tag, a_Name.c_str(), a_Name.length()); + } + + int FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLength = 0) const; + int FindTagByPath (int a_Tag, const AString & a_Path) const; + + eTagType GetType(int a_Tag) const { return m_Tags[a_Tag].m_Type; } + + /// Returns the children type for a list tag; undefined on other tags. If list empty, returns TAG_End + eTagType GetChildrenType(int a_Tag) const + { + ASSERT(m_Tags[a_Tag].m_Type == TAG_List); + return (m_Tags[a_Tag].m_FirstChild < 0) ? TAG_End : m_Tags[m_Tags[a_Tag].m_FirstChild].m_Type; + } + + inline unsigned char GetByte(int a_Tag) const + { + ASSERT(m_Tags[a_Tag].m_Type == TAG_Byte); + return (unsigned char)(m_Data[m_Tags[a_Tag].m_DataStart]); + } + + inline Int16 GetShort(int a_Tag) const + { + ASSERT(m_Tags[a_Tag].m_Type == TAG_Short); + return ntohs(*((Int16 *)(m_Data + m_Tags[a_Tag].m_DataStart))); + } + + inline Int32 GetInt(int a_Tag) const + { + ASSERT(m_Tags[a_Tag].m_Type == TAG_Int); + return ntohl(*((Int32 *)(m_Data + m_Tags[a_Tag].m_DataStart))); + } + + inline Int64 GetLong(int a_Tag) const + { + ASSERT(m_Tags[a_Tag].m_Type == TAG_Long); + return NetworkToHostLong8(m_Data + m_Tags[a_Tag].m_DataStart); + } + + inline float GetFloat(int a_Tag) const + { + ASSERT(m_Tags[a_Tag].m_Type == TAG_Float); + Int32 tmp = ntohl(*((Int32 *)(m_Data + m_Tags[a_Tag].m_DataStart))); + return *((float *)&tmp); + } + + inline double GetDouble(int a_Tag) const + { + ASSERT(m_Tags[a_Tag].m_Type == TAG_Double); + return NetworkToHostDouble8(m_Data + m_Tags[a_Tag].m_DataStart); + } + +protected: + const char * m_Data; + int m_Length; + std::vector m_Tags; + bool m_IsValid; // True if parsing succeeded + + // Used while parsing: + int m_Pos; + + bool Parse(void); + bool ReadString(int & a_StringStart, int & a_StringLen); // Reads a simple string (2 bytes length + data), sets the string descriptors + bool ReadCompound(void); // Reads the latest tag as a compound + bool ReadList(eTagType a_ChildrenType); // Reads the latest tag as a list of items of type a_ChildrenType + bool ReadTag(void); // Reads the latest tag, depending on its m_Type setting +} ; + + + + + +class cFastNBTWriter +{ +public: + cFastNBTWriter(void); + + void BeginCompound(const AString & a_Name); + void EndCompound(void); + + void BeginList(const AString & a_Name, eTagType a_ChildrenType); + void EndList(void); + + void AddByte (const AString & a_Name, unsigned char a_Value); + void AddShort (const AString & a_Name, Int16 a_Value); + void AddInt (const AString & a_Name, Int32 a_Value); + void AddLong (const AString & a_Name, Int64 a_Value); + void AddFloat (const AString & a_Name, float a_Value); + void AddDouble (const AString & a_Name, double a_Value); + void AddString (const AString & a_Name, const AString & a_Value); + void AddByteArray(const AString & a_Name, const char * a_Value, size_t a_NumElements); + void AddIntArray (const AString & a_Name, const int * a_Value, size_t a_NumElements); + + void AddByteArray(const AString & a_Name, const AString & a_Value) + { + AddByteArray(a_Name, a_Value.data(), a_Value.size()); + } + + const AString & GetResult(void) const {return m_Result; } + + void Finish(void); + +protected: + + struct sParent + { + int m_Type; // TAG_Compound or TAG_List + int m_Pos; // for TAG_List, the position of the list count + int m_Count; // for TAG_List, the element count + } ; + + static const int MAX_STACK = 50; // Highliy doubtful that an NBT would be constructed this many levels deep + + // These two fields emulate a stack. A raw array is used due to speed issues - no reallocations are allowed. + sParent m_Stack[MAX_STACK]; + int m_CurrentStack; + + AString m_Result; + + bool IsStackTopCompound(void) const { return (m_Stack[m_CurrentStack].m_Type == TAG_Compound); } + + void WriteString(const char * a_Data, short a_Length); + + inline void TagCommon(const AString & a_Name, eTagType a_Type) + { + if (IsStackTopCompound()) + { + // Compound: add the type and name: + m_Result.push_back((char)a_Type); + WriteString(a_Name.c_str(), (short)a_Name.length()); + } + else + { + // List: add to the counter + m_Stack[m_CurrentStack].m_Count++; + } + } +} ; + + + + diff --git a/source/FileDefine.h b/source/FileDefine.h index 826d6dd75..c75fb3110 100644 --- a/source/FileDefine.h +++ b/source/FileDefine.h @@ -1,21 +1,21 @@ -#pragma once - -// So we don't have to include fstream :P -#ifdef _WIN32 -#ifndef _FILE_DEFINED -struct _iobuf { - char *_ptr; - int _cnt; - char *_base; - int _flag; - int _file; - int _charbuf; - int _bufsiz; - char *_tmpfname; -}; -typedef struct _iobuf FILE; -#define _FILE_DEFINED -#endif -#else -#include +#pragma once + +// So we don't have to include fstream :P +#ifdef _WIN32 +#ifndef _FILE_DEFINED +struct _iobuf { + char *_ptr; + int _cnt; + char *_base; + int _flag; + int _file; + int _charbuf; + int _bufsiz; + char *_tmpfname; +}; +typedef struct _iobuf FILE; +#define _FILE_DEFINED +#endif +#else +#include #endif \ No newline at end of file diff --git a/source/FinishGen.cpp b/source/FinishGen.cpp index 9761d4373..eac4a6c02 100644 --- a/source/FinishGen.cpp +++ b/source/FinishGen.cpp @@ -1,285 +1,285 @@ - -// FinishGen.cpp - -/* Implements the various finishing generators: - - cFinishGenSnow - - cFinishGenIce - - cFinishGenSprinkleFoliage -*/ - -#include "Globals.h" - -#include "FinishGen.h" -#include "cNoise.h" -#include "BlockID.h" - - - - - -static inline bool IsWater(BLOCKTYPE a_BlockType) -{ - return (a_BlockType == E_BLOCK_STATIONARY_WATER) || (a_BlockType == E_BLOCK_WATER); -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cFinishGenSprinkleFoliage: - -bool cFinishGenSprinkleFoliage::TryAddSugarcane( - int a_ChunkX, int a_ChunkZ, - int a_RelX, int a_RelY, int a_RelZ, - cChunkDef::BlockTypes & a_BlockTypes, - cChunkDef::BlockNibbles & a_BlockMeta -) -{ - // We'll be doing comparison to neighbors, so require the coords to be 1 block away from the chunk edges: - if ( - (a_RelX < 1) || (a_RelX >= cChunkDef::Width - 1) || - (a_RelY < 1) || (a_RelY >= cChunkDef::Height - 2) || - (a_RelZ < 1) || (a_RelZ >= cChunkDef::Width - 1) - ) - { - return false; - } - - // Only allow dirt, grass or sand below sugarcane: - switch (cChunkDef::GetBlock(a_BlockTypes, a_RelX, a_RelY, a_RelZ)) - { - case E_BLOCK_DIRT: - case E_BLOCK_GRASS: - case E_BLOCK_SAND: - { - break; - } - default: - { - return false; - } - } - - // Water is required next to the block below the sugarcane: - if ( - !IsWater(cChunkDef::GetBlock(a_BlockTypes, a_RelX - 1, a_RelY, a_RelZ)) && - !IsWater(cChunkDef::GetBlock(a_BlockTypes, a_RelX + 1, a_RelY, a_RelZ)) && - !IsWater(cChunkDef::GetBlock(a_BlockTypes, a_RelX , a_RelY, a_RelZ - 1)) && - !IsWater(cChunkDef::GetBlock(a_BlockTypes, a_RelX , a_RelY, a_RelZ + 1)) - ) - { - return false; - } - - // All conditions met, place a sugarcane here: - cChunkDef::SetBlock(a_BlockTypes, a_RelX, a_RelY + 1, a_RelZ, E_BLOCK_SUGARCANE); - return true; -} - - - - - -void cFinishGenSprinkleFoliage::GenFinish( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change - cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change - cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data - const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to - cEntityList & a_Entities, // Entities may be added or deleted - cBlockEntityList & a_BlockEntities // Block entities may be added or deleted - ) -{ - // Generate small foliage (1-block): - - // TODO: Update heightmap with 1-block-tall foliage - cNoise Noise(m_Seed); - for (int z = 0; z < cChunkDef::Width; z++) - { - int BlockZ = a_ChunkZ * cChunkDef::Width + z; - const float zz = (float)BlockZ; - for (int x = 0; x < cChunkDef::Width; x++) - { - int BlockX = a_ChunkX * cChunkDef::Width + x; - if (((Noise.IntNoise2DInt(BlockX, BlockZ) / 8) % 128) < 124) - { - continue; - } - int Top = cChunkDef::GetHeight(a_HeightMap, x, z); - if (Top > 250) - { - // Nothing grows above Y=250 - continue; - } - if (cChunkDef::GetBlock(a_BlockTypes, x, Top + 1, z) != E_BLOCK_AIR) - { - // Space already taken by something else, don't grow here - // WEIRD, since we're using heightmap, so there should NOT be anything above it - continue; - } - - const float xx = (float)BlockX; - float val1 = Noise.CubicNoise2D(xx * 0.1f, zz * 0.1f ); - float val2 = Noise.CubicNoise2D(xx * 0.01f, zz * 0.01f ); - switch (cChunkDef::GetBlock(a_BlockTypes, x, Top, z)) - { - case E_BLOCK_GRASS: - { - float val3 = Noise.CubicNoise2D(xx * 0.01f + 10, zz * 0.01f + 10 ); - float val4 = Noise.CubicNoise2D(xx * 0.05f + 20, zz * 0.05f + 20 ); - if (val1 + val2 > 0.2f) - { - cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_YELLOW_FLOWER); - } - else if (val2 + val3 > 0.2f) - { - cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_RED_ROSE); - } - else if (val3 + val4 > 0.2f) - { - cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_RED_MUSHROOM); - } - else if (val1 + val4 > 0.2f) - { - cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_BROWN_MUSHROOM); - } - else if (val1 + val2 + val3 + val4 < -0.1) - { - cChunkDef::SetBlock (a_BlockTypes, x, ++Top, z, E_BLOCK_TALL_GRASS); - cChunkDef::SetNibble(a_BlockMeta, x, Top, z, E_META_TALL_GRASS_GRASS); - } - else if (TryAddSugarcane(a_ChunkX, a_ChunkZ, x, Top, z, a_BlockTypes, a_BlockMeta)) - { - ++Top; - } - else if ((val1 > 0.5) && (val2 < -0.5)) - { - cChunkDef::SetBlock (a_BlockTypes, x, ++Top, z, E_BLOCK_PUMPKIN); - cChunkDef::SetNibble(a_BlockMeta, x, Top, z, (int)(val3 * 8) % 4); - } - break; - } // case E_BLOCK_GRASS - - case E_BLOCK_SAND: - { - int y = Top + 1; - if ( - (x > 0) && (x < cChunkDef::Width - 1) && - (z > 0) && (z < cChunkDef::Width - 1) && - (val1 + val2 > 0.5f) && - (cChunkDef::GetBlock(a_BlockTypes, x + 1, y, z) == E_BLOCK_AIR) && - (cChunkDef::GetBlock(a_BlockTypes, x - 1, y, z) == E_BLOCK_AIR) && - (cChunkDef::GetBlock(a_BlockTypes, x, y, z + 1) == E_BLOCK_AIR) && - (cChunkDef::GetBlock(a_BlockTypes, x, y, z - 1) == E_BLOCK_AIR) - ) - { - cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_CACTUS); - } - else if (TryAddSugarcane(a_ChunkX, a_ChunkZ, x, Top, z, a_BlockTypes, a_BlockMeta)) - { - ++Top; - } - break; - } - } // switch (TopBlock) - cChunkDef::SetHeight(a_HeightMap, x, z, Top); - } // for y - } // for z -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cFinishGenSnow: - -void cFinishGenSnow::GenFinish( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change - cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change - cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data - const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to - cEntityList & a_Entities, // Entities may be added or deleted - cBlockEntityList & a_BlockEntities // Block entities may be added or deleted - ) -{ - // Add a snow block in snowy biomes onto blocks that can be snowed over - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int x = 0; x < cChunkDef::Width; x++) - { - switch (cChunkDef::GetBiome(a_BiomeMap, x, z)) - { - case biIcePlains: - case biIceMountains: - case biTaiga: - case biTaigaHills: - case biFrozenRiver: - case biFrozenOcean: - { - int Height = cChunkDef::GetHeight(a_HeightMap, x, z); - if (g_BlockIsSnowable[cChunkDef::GetBlock(a_BlockTypes, x, Height, z)]) - { - cChunkDef::SetBlock(a_BlockTypes, x, Height + 1, z, E_BLOCK_SNOW); - cChunkDef::SetHeight(a_HeightMap, x, z, Height + 1); - } - break; - } - } - } - } // for z -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cFinishGenIce: - -void cFinishGenIce::GenFinish( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change - cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change - cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data - const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to - cEntityList & a_Entities, // Entities may be added or deleted - cBlockEntityList & a_BlockEntities // Block entities may be added or deleted - ) -{ - // Turn surface water into ice in icy biomes - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int x = 0; x < cChunkDef::Width; x++) - { - switch (cChunkDef::GetBiome(a_BiomeMap, x, z)) - { - case biIcePlains: - case biIceMountains: - case biTaiga: - case biTaigaHills: - case biFrozenRiver: - case biFrozenOcean: - { - int Height = cChunkDef::GetHeight(a_HeightMap, x, z); - switch (cChunkDef::GetBlock(a_BlockTypes, x, Height, z)) - { - case E_BLOCK_WATER: - case E_BLOCK_STATIONARY_WATER: - { - cChunkDef::SetBlock(a_BlockTypes, x, Height, z, E_BLOCK_ICE); - break; - } - } - break; - } - } - } - } // for z -} - - - - + +// FinishGen.cpp + +/* Implements the various finishing generators: + - cFinishGenSnow + - cFinishGenIce + - cFinishGenSprinkleFoliage +*/ + +#include "Globals.h" + +#include "FinishGen.h" +#include "cNoise.h" +#include "BlockID.h" + + + + + +static inline bool IsWater(BLOCKTYPE a_BlockType) +{ + return (a_BlockType == E_BLOCK_STATIONARY_WATER) || (a_BlockType == E_BLOCK_WATER); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cFinishGenSprinkleFoliage: + +bool cFinishGenSprinkleFoliage::TryAddSugarcane( + int a_ChunkX, int a_ChunkZ, + int a_RelX, int a_RelY, int a_RelZ, + cChunkDef::BlockTypes & a_BlockTypes, + cChunkDef::BlockNibbles & a_BlockMeta +) +{ + // We'll be doing comparison to neighbors, so require the coords to be 1 block away from the chunk edges: + if ( + (a_RelX < 1) || (a_RelX >= cChunkDef::Width - 1) || + (a_RelY < 1) || (a_RelY >= cChunkDef::Height - 2) || + (a_RelZ < 1) || (a_RelZ >= cChunkDef::Width - 1) + ) + { + return false; + } + + // Only allow dirt, grass or sand below sugarcane: + switch (cChunkDef::GetBlock(a_BlockTypes, a_RelX, a_RelY, a_RelZ)) + { + case E_BLOCK_DIRT: + case E_BLOCK_GRASS: + case E_BLOCK_SAND: + { + break; + } + default: + { + return false; + } + } + + // Water is required next to the block below the sugarcane: + if ( + !IsWater(cChunkDef::GetBlock(a_BlockTypes, a_RelX - 1, a_RelY, a_RelZ)) && + !IsWater(cChunkDef::GetBlock(a_BlockTypes, a_RelX + 1, a_RelY, a_RelZ)) && + !IsWater(cChunkDef::GetBlock(a_BlockTypes, a_RelX , a_RelY, a_RelZ - 1)) && + !IsWater(cChunkDef::GetBlock(a_BlockTypes, a_RelX , a_RelY, a_RelZ + 1)) + ) + { + return false; + } + + // All conditions met, place a sugarcane here: + cChunkDef::SetBlock(a_BlockTypes, a_RelX, a_RelY + 1, a_RelZ, E_BLOCK_SUGARCANE); + return true; +} + + + + + +void cFinishGenSprinkleFoliage::GenFinish( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) +{ + // Generate small foliage (1-block): + + // TODO: Update heightmap with 1-block-tall foliage + cNoise Noise(m_Seed); + for (int z = 0; z < cChunkDef::Width; z++) + { + int BlockZ = a_ChunkZ * cChunkDef::Width + z; + const float zz = (float)BlockZ; + for (int x = 0; x < cChunkDef::Width; x++) + { + int BlockX = a_ChunkX * cChunkDef::Width + x; + if (((Noise.IntNoise2DInt(BlockX, BlockZ) / 8) % 128) < 124) + { + continue; + } + int Top = cChunkDef::GetHeight(a_HeightMap, x, z); + if (Top > 250) + { + // Nothing grows above Y=250 + continue; + } + if (cChunkDef::GetBlock(a_BlockTypes, x, Top + 1, z) != E_BLOCK_AIR) + { + // Space already taken by something else, don't grow here + // WEIRD, since we're using heightmap, so there should NOT be anything above it + continue; + } + + const float xx = (float)BlockX; + float val1 = Noise.CubicNoise2D(xx * 0.1f, zz * 0.1f ); + float val2 = Noise.CubicNoise2D(xx * 0.01f, zz * 0.01f ); + switch (cChunkDef::GetBlock(a_BlockTypes, x, Top, z)) + { + case E_BLOCK_GRASS: + { + float val3 = Noise.CubicNoise2D(xx * 0.01f + 10, zz * 0.01f + 10 ); + float val4 = Noise.CubicNoise2D(xx * 0.05f + 20, zz * 0.05f + 20 ); + if (val1 + val2 > 0.2f) + { + cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_YELLOW_FLOWER); + } + else if (val2 + val3 > 0.2f) + { + cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_RED_ROSE); + } + else if (val3 + val4 > 0.2f) + { + cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_RED_MUSHROOM); + } + else if (val1 + val4 > 0.2f) + { + cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_BROWN_MUSHROOM); + } + else if (val1 + val2 + val3 + val4 < -0.1) + { + cChunkDef::SetBlock (a_BlockTypes, x, ++Top, z, E_BLOCK_TALL_GRASS); + cChunkDef::SetNibble(a_BlockMeta, x, Top, z, E_META_TALL_GRASS_GRASS); + } + else if (TryAddSugarcane(a_ChunkX, a_ChunkZ, x, Top, z, a_BlockTypes, a_BlockMeta)) + { + ++Top; + } + else if ((val1 > 0.5) && (val2 < -0.5)) + { + cChunkDef::SetBlock (a_BlockTypes, x, ++Top, z, E_BLOCK_PUMPKIN); + cChunkDef::SetNibble(a_BlockMeta, x, Top, z, (int)(val3 * 8) % 4); + } + break; + } // case E_BLOCK_GRASS + + case E_BLOCK_SAND: + { + int y = Top + 1; + if ( + (x > 0) && (x < cChunkDef::Width - 1) && + (z > 0) && (z < cChunkDef::Width - 1) && + (val1 + val2 > 0.5f) && + (cChunkDef::GetBlock(a_BlockTypes, x + 1, y, z) == E_BLOCK_AIR) && + (cChunkDef::GetBlock(a_BlockTypes, x - 1, y, z) == E_BLOCK_AIR) && + (cChunkDef::GetBlock(a_BlockTypes, x, y, z + 1) == E_BLOCK_AIR) && + (cChunkDef::GetBlock(a_BlockTypes, x, y, z - 1) == E_BLOCK_AIR) + ) + { + cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_CACTUS); + } + else if (TryAddSugarcane(a_ChunkX, a_ChunkZ, x, Top, z, a_BlockTypes, a_BlockMeta)) + { + ++Top; + } + break; + } + } // switch (TopBlock) + cChunkDef::SetHeight(a_HeightMap, x, z, Top); + } // for y + } // for z +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cFinishGenSnow: + +void cFinishGenSnow::GenFinish( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) +{ + // Add a snow block in snowy biomes onto blocks that can be snowed over + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + switch (cChunkDef::GetBiome(a_BiomeMap, x, z)) + { + case biIcePlains: + case biIceMountains: + case biTaiga: + case biTaigaHills: + case biFrozenRiver: + case biFrozenOcean: + { + int Height = cChunkDef::GetHeight(a_HeightMap, x, z); + if (g_BlockIsSnowable[cChunkDef::GetBlock(a_BlockTypes, x, Height, z)]) + { + cChunkDef::SetBlock(a_BlockTypes, x, Height + 1, z, E_BLOCK_SNOW); + cChunkDef::SetHeight(a_HeightMap, x, z, Height + 1); + } + break; + } + } + } + } // for z +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cFinishGenIce: + +void cFinishGenIce::GenFinish( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) +{ + // Turn surface water into ice in icy biomes + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + switch (cChunkDef::GetBiome(a_BiomeMap, x, z)) + { + case biIcePlains: + case biIceMountains: + case biTaiga: + case biTaigaHills: + case biFrozenRiver: + case biFrozenOcean: + { + int Height = cChunkDef::GetHeight(a_HeightMap, x, z); + switch (cChunkDef::GetBlock(a_BlockTypes, x, Height, z)) + { + case E_BLOCK_WATER: + case E_BLOCK_STATIONARY_WATER: + { + cChunkDef::SetBlock(a_BlockTypes, x, Height, z, E_BLOCK_ICE); + break; + } + } + break; + } + } + } + } // for z +} + + + + diff --git a/source/FinishGen.h b/source/FinishGen.h index 816e2ca7c..1684e5eea 100644 --- a/source/FinishGen.h +++ b/source/FinishGen.h @@ -1,90 +1,90 @@ - -// FinishGen.h - -/* Interfaces to the various finishing generators: - - cFinishGenSnow - - cFinishGenIce - - cFinishGenSprinkleFoliage -*/ - - - - - -#include "cChunkGenerator.h" - - - - - -class cFinishGenSnow : - public cFinishGen -{ -protected: - // cFinishGen override: - virtual void GenFinish( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change - cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change - cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data - const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to - cEntityList & a_Entities, // Entities may be added or deleted - cBlockEntityList & a_BlockEntities // Block entities may be added or deleted - ) override; -} ; - - - - - -class cFinishGenIce : - public cFinishGen -{ -protected: - // cFinishGen override: - virtual void GenFinish( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change - cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change - cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data - const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to - cEntityList & a_Entities, // Entities may be added or deleted - cBlockEntityList & a_BlockEntities // Block entities may be added or deleted - ) override; -} ; - - - - -class cFinishGenSprinkleFoliage : - public cFinishGen -{ -public: - cFinishGenSprinkleFoliage(int a_Seed) : m_Seed(a_Seed) {} - -protected: - int m_Seed; - - /// Tries to place sugarcane at the coords specified, returns true if successful - bool TryAddSugarcane( - int a_ChunkX, int a_ChunkZ, - int a_RelX, int a_RelY, int a_RelZ, // relative block coords of the sugarcane's base - cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change - cChunkDef::BlockNibbles & a_BlockMeta // Block meta to read and change - ); - - // cFinishGen override: - virtual void GenFinish( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change - cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change - cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data - const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to - cEntityList & a_Entities, // Entities may be added or deleted - cBlockEntityList & a_BlockEntities // Block entities may be added or deleted - ) override; -} ; - - - - + +// FinishGen.h + +/* Interfaces to the various finishing generators: + - cFinishGenSnow + - cFinishGenIce + - cFinishGenSprinkleFoliage +*/ + + + + + +#include "cChunkGenerator.h" + + + + + +class cFinishGenSnow : + public cFinishGen +{ +protected: + // cFinishGen override: + virtual void GenFinish( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) override; +} ; + + + + + +class cFinishGenIce : + public cFinishGen +{ +protected: + // cFinishGen override: + virtual void GenFinish( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) override; +} ; + + + + +class cFinishGenSprinkleFoliage : + public cFinishGen +{ +public: + cFinishGenSprinkleFoliage(int a_Seed) : m_Seed(a_Seed) {} + +protected: + int m_Seed; + + /// Tries to place sugarcane at the coords specified, returns true if successful + bool TryAddSugarcane( + int a_ChunkX, int a_ChunkZ, + int a_RelX, int a_RelY, int a_RelZ, // relative block coords of the sugarcane's base + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta // Block meta to read and change + ); + + // cFinishGen override: + virtual void GenFinish( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) override; +} ; + + + + diff --git a/source/Globals.cpp b/source/Globals.cpp index 2c60fd698..13c6ae709 100644 --- a/source/Globals.cpp +++ b/source/Globals.cpp @@ -1,10 +1,10 @@ - -// Globals.cpp - -// This file is used for precompiled header generation in MSVC environments - -#include "Globals.h" - - - - + +// Globals.cpp + +// This file is used for precompiled header generation in MSVC environments + +#include "Globals.h" + + + + diff --git a/source/Globals.h b/source/Globals.h index 78f847e2e..65db1b436 100644 --- a/source/Globals.h +++ b/source/Globals.h @@ -1,202 +1,202 @@ - -// Globals.h - -// This file gets included from every module in the project, so that global symbols may be introduced easily -// Also used for precompiled header generation in MSVC environments - - - - - -// Compiler-dependent stuff: -#if defined(_MSC_VER) - // MSVC produces warning C4481 on the override keyword usage, so disable the warning altogether - #pragma warning(disable:4481) - - // Disable some warnings that we don't care about: - #pragma warning(disable:4100) - - #define OBSOLETE __declspec(deprecated) - - // No alignment needed in MSVC - #define ALIGN_8 - #define ALIGN_16 - -#elif defined(__GNUC__) - - // TODO: Can GCC explicitly mark classes as abstract (no instances can be created)? - #define abstract - - // TODO: Can GCC mark virtual methods as overriding (forcing them to have a virtual function of the same signature in the base class) - #define override - - #define OBSOLETE __attribute__((deprecated)) - - #define ALIGN_8 __attribute__((aligned(8))) - #define ALIGN_16 __attribute__((aligned(16))) - - // Some portability macros :) - #define stricmp strcasecmp - -#else - - #error "You are using an unsupported compiler, you might need to #define some stuff here for your compiler" - - /* - // Copy and uncomment this into another #elif section based on your compiler identification - - // Explicitly mark classes as abstract (no instances can be created) - #define abstract - - // Mark virtual methods as overriding (forcing them to have a virtual function of the same signature in the base class) - #define override - - // Mark functions as obsolete, so that their usage results in a compile-time warning - #define OBSOLETE - - // Mark types / variables for alignment. Do the platforms need it? - #define ALIGN_8 - #define ALIGN_16 - */ - -#endif - - - - - -// Integral types with predefined sizes: -typedef long long Int64; -typedef int Int32; -typedef short Int16; - - - - - -// A macro to disallow the copy constructor and operator= functions -// This should be used in the private: declarations for any class that shouldn't allow copying itself -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName &); \ - void operator=(const TypeName &) - - - - - -// OS-dependent stuff: -#ifdef _WIN32 - #define WIN32_LEAN_AND_MEAN - #include - #include - - // Windows SDK defines min and max macros, messing up with our std::min and std::max usage - #undef min - #undef max -#else - #include - #include // for mkdir - #include - #include - #include - #include - #include - #include - #include - #include - #include - - #include - #include - #include - #include - #include - #include - #include -#endif - - - - - -// CRT stuff: -#include -#include -#include -#include - - - - - -// STL stuff: -#include -#include -#include -#include -#include -#include -#include - - - - - -// Common headers (part 1, without macros): -#include "StringUtils.h" -#include "cSleep.h" -#include "cCriticalSection.h" -#include "cSemaphore.h" -#include "cEvent.h" -#include "cThread.h" -#include "cFile.h" -#include "cMCLogger.h" - - - - - -// Common definitions: - -/// Evaluates to the number of elements in an array (compile-time!) -#define ARRAYCOUNT(X) (sizeof(X) / sizeof(*(X))) - -/// Allows arithmetic expressions like "32 KiB" (but consider using parenthesis around it, "(32 KiB)" ) -#define KiB * 1024 - -/// Faster than (int)floorf((float)x / (float)div) -#define FAST_FLOOR_DIV( x, div ) ( (x) < 0 ? (((int)x / div) - 1) : ((int)x / div) ) - -// Own version of assert() that writes failed assertions to the log for review -#ifdef NDEBUG - #define ASSERT(x) ((void)0) -#else - #define ASSERT( x ) ( !!(x) || ( LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), assert(0), 0 ) ) -#endif - -// Pretty much the same as ASSERT() but stays in Release builds -#define VERIFY( x ) ( !!(x) || ( LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), exit(1), 0 ) ) - - - - - -/// A generic interface used mainly in ForEach() functions -template 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; -} ; - - - - - -// Common headers (part 2, with macros): -#include "ChunkDef.h" -#include "BlockID.h" - - - - + +// Globals.h + +// This file gets included from every module in the project, so that global symbols may be introduced easily +// Also used for precompiled header generation in MSVC environments + + + + + +// Compiler-dependent stuff: +#if defined(_MSC_VER) + // MSVC produces warning C4481 on the override keyword usage, so disable the warning altogether + #pragma warning(disable:4481) + + // Disable some warnings that we don't care about: + #pragma warning(disable:4100) + + #define OBSOLETE __declspec(deprecated) + + // No alignment needed in MSVC + #define ALIGN_8 + #define ALIGN_16 + +#elif defined(__GNUC__) + + // TODO: Can GCC explicitly mark classes as abstract (no instances can be created)? + #define abstract + + // TODO: Can GCC mark virtual methods as overriding (forcing them to have a virtual function of the same signature in the base class) + #define override + + #define OBSOLETE __attribute__((deprecated)) + + #define ALIGN_8 __attribute__((aligned(8))) + #define ALIGN_16 __attribute__((aligned(16))) + + // Some portability macros :) + #define stricmp strcasecmp + +#else + + #error "You are using an unsupported compiler, you might need to #define some stuff here for your compiler" + + /* + // Copy and uncomment this into another #elif section based on your compiler identification + + // Explicitly mark classes as abstract (no instances can be created) + #define abstract + + // Mark virtual methods as overriding (forcing them to have a virtual function of the same signature in the base class) + #define override + + // Mark functions as obsolete, so that their usage results in a compile-time warning + #define OBSOLETE + + // Mark types / variables for alignment. Do the platforms need it? + #define ALIGN_8 + #define ALIGN_16 + */ + +#endif + + + + + +// Integral types with predefined sizes: +typedef long long Int64; +typedef int Int32; +typedef short Int16; + + + + + +// A macro to disallow the copy constructor and operator= functions +// This should be used in the private: declarations for any class that shouldn't allow copying itself +#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName &); \ + void operator=(const TypeName &) + + + + + +// OS-dependent stuff: +#ifdef _WIN32 + #define WIN32_LEAN_AND_MEAN + #include + #include + + // Windows SDK defines min and max macros, messing up with our std::min and std::max usage + #undef min + #undef max +#else + #include + #include // for mkdir + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + #include +#endif + + + + + +// CRT stuff: +#include +#include +#include +#include + + + + + +// STL stuff: +#include +#include +#include +#include +#include +#include +#include + + + + + +// Common headers (part 1, without macros): +#include "StringUtils.h" +#include "cSleep.h" +#include "cCriticalSection.h" +#include "cSemaphore.h" +#include "cEvent.h" +#include "cThread.h" +#include "cFile.h" +#include "cMCLogger.h" + + + + + +// Common definitions: + +/// Evaluates to the number of elements in an array (compile-time!) +#define ARRAYCOUNT(X) (sizeof(X) / sizeof(*(X))) + +/// Allows arithmetic expressions like "32 KiB" (but consider using parenthesis around it, "(32 KiB)" ) +#define KiB * 1024 + +/// Faster than (int)floorf((float)x / (float)div) +#define FAST_FLOOR_DIV( x, div ) ( (x) < 0 ? (((int)x / div) - 1) : ((int)x / div) ) + +// Own version of assert() that writes failed assertions to the log for review +#ifdef NDEBUG + #define ASSERT(x) ((void)0) +#else + #define ASSERT( x ) ( !!(x) || ( LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), assert(0), 0 ) ) +#endif + +// Pretty much the same as ASSERT() but stays in Release builds +#define VERIFY( x ) ( !!(x) || ( LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), exit(1), 0 ) ) + + + + + +/// A generic interface used mainly in ForEach() functions +template 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; +} ; + + + + + +// Common headers (part 2, with macros): +#include "ChunkDef.h" +#include "BlockID.h" + + + + diff --git a/source/HeiGen.cpp b/source/HeiGen.cpp index 551ae8804..ed353751c 100644 --- a/source/HeiGen.cpp +++ b/source/HeiGen.cpp @@ -1,302 +1,302 @@ - -// HeiGen.cpp - -// Implements the various terrain height generators - -#include "Globals.h" -#include "HeiGen.h" - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cHeiGenFlat: - -void cHeiGenFlat::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) -{ - for (int i = 0; i < ARRAYCOUNT(a_HeightMap); i++) - { - a_HeightMap[i] = m_Height; - } -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cHeiGenCache: - -cHeiGenCache::cHeiGenCache(cTerrainHeightGen * a_HeiGenToCache, int a_CacheSize) : - m_HeiGenToCache(a_HeiGenToCache), - m_CacheSize(a_CacheSize), - m_CacheOrder(new int[a_CacheSize]), - m_CacheData(new sCacheData[a_CacheSize]), - m_NumHits(0), - m_NumMisses(0), - m_TotalChain(0) -{ - for (int i = 0; i < m_CacheSize; i++) - { - m_CacheOrder[i] = i; - m_CacheData[i].m_ChunkX = 0x7fffffff; - m_CacheData[i].m_ChunkZ = 0x7fffffff; - } -} - - - - - -cHeiGenCache::~cHeiGenCache() -{ - delete m_CacheData; - delete m_CacheOrder; - delete m_HeiGenToCache; -} - - - - - -void cHeiGenCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) -{ - if (((m_NumHits + m_NumMisses) % 1024) == 10) - { - LOGD("HeiGenCache: %d hits, %d misses, saved %.2f %%", m_NumHits, m_NumMisses, 100.0 * m_NumHits / (m_NumHits + m_NumMisses)); - LOGD("HeiGenCache: Avg cache chain length: %.2f", (float)m_TotalChain / m_NumHits); - } - - for (int i = 0; i < m_CacheSize; i++) - { - if ( - (m_CacheData[m_CacheOrder[i]].m_ChunkX != a_ChunkX) || - (m_CacheData[m_CacheOrder[i]].m_ChunkZ != a_ChunkZ) - ) - { - continue; - } - // Found it in the cache - int Idx = m_CacheOrder[i]; - - // Move to front: - for (int j = i; j > 0; j--) - { - m_CacheOrder[j] = m_CacheOrder[j - 1]; - } - m_CacheOrder[0] = Idx; - - // Use the cached data: - memcpy(a_HeightMap, m_CacheData[Idx].m_HeightMap, sizeof(a_HeightMap)); - - m_NumHits++; - m_TotalChain += i; - return; - } // for i - cache - - // Not in the cache: - m_NumMisses++; - m_HeiGenToCache->GenHeightMap(a_ChunkX, a_ChunkZ, a_HeightMap); - - // Insert it as the first item in the MRU order: - int Idx = m_CacheOrder[m_CacheSize - 1]; - for (int i = m_CacheSize - 1; i > 0; i--) - { - m_CacheOrder[i] = m_CacheOrder[i - 1]; - } // for i - m_CacheOrder[] - m_CacheOrder[0] = Idx; - memcpy(m_CacheData[Idx].m_HeightMap, a_HeightMap, sizeof(a_HeightMap)); - m_CacheData[Idx].m_ChunkX = a_ChunkX; - m_CacheData[Idx].m_ChunkZ = a_ChunkZ; -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cHeiGenClassic: - -cHeiGenClassic::cHeiGenClassic(int a_Seed, float a_HeightFreq1, float a_HeightAmp1, float a_HeightFreq2, float a_HeightAmp2, float a_HeightFreq3, float a_HeightAmp3) : - m_Seed(a_Seed), - m_Noise(a_Seed), - m_HeightFreq1(a_HeightFreq1), - m_HeightAmp1 (a_HeightAmp1), - m_HeightFreq2(a_HeightFreq2), - m_HeightAmp2 (a_HeightAmp2), - m_HeightFreq3(a_HeightFreq3), - m_HeightAmp3 (a_HeightAmp3) -{ - // Nothing needed yet -} - - - - - -float cHeiGenClassic::GetNoise(float x, float y) -{ - float oct1 = m_Noise.CubicNoise2D(x * m_HeightFreq1, y * m_HeightFreq1) * m_HeightAmp1; - float oct2 = m_Noise.CubicNoise2D(x * m_HeightFreq2, y * m_HeightFreq2) * m_HeightAmp2; - float oct3 = m_Noise.CubicNoise2D(x * m_HeightFreq3, y * m_HeightFreq3) * m_HeightAmp3; - - float height = m_Noise.CubicNoise2D(x * 0.1f, y * 0.1f ) * 2; - - float flatness = ((m_Noise.CubicNoise2D(x * 0.5f, y * 0.5f) + 1.f) * 0.5f) * 1.1f; // 0 ... 1.5 - flatness *= flatness * flatness; - - return (oct1 + oct2 + oct3) * flatness + height; -} - - - - - -void cHeiGenClassic::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) -{ - for (int z = 0; z < cChunkDef::Width; z++) - { - const float zz = (float)(a_ChunkZ * cChunkDef::Width + z); - for (int x = 0; x < cChunkDef::Width; x++) - { - const float xx = (float)(a_ChunkX * cChunkDef::Width + x); - - int hei = 64 + (int)(GetNoise(xx * 0.05f, zz * 0.05f) * 16); - if (hei < 10) - { - hei = 10; - } - if (hei > 250) - { - hei = 250; - } - cChunkDef::SetHeight(a_HeightMap, x , z, hei); - } // for x - } // for z -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cHeiGenBiomal: - -const cHeiGenBiomal::sGenParam cHeiGenBiomal::m_GenParam[biNumBiomes] = -{ - /* Fast-changing | Middle-changing | Slow-changing |*/ - /* Biome | Freq1 | Amp1 | Freq2 | Amp2 | Freq3 | Amp3 | BaseHeight */ - /* biOcean */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // done - /* biPlains */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68}, // done - /* biDesert */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68}, // done - /* biExtremeHills */ { 0.2f, 4.0f, 0.05f, 20.0f, 0.01f, 16.0f, 100}, // done - /* biForest */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // done - /* biTaiga */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // done - /* biSwampland */ { 0.1f, 1.1f, 0.05f, 1.5f, 0.02f, 2.5f, 61.5}, // done - /* biRiver */ { 0.2f, 3.0f, 0.05f, 1.0f, 0.01f, 1.0f, 56}, // done - /* biNether */ { 0.1f, 0.0f, 0.01f, 0.0f, 0.01f, 0.0f, 0}, // Unused, but must be here due to indexing - /* biSky */ { 0.1f, 0.0f, 0.01f, 0.0f, 0.01f, 0.0f, 0}, // Unused, but must be here due to indexing - /* biFrozenOcean */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // done - /* biFrozenRiver */ { 0.2f, 3.0f, 0.05f, 1.0f, 0.01f, 1.0f, 56}, // done - /* biIcePlains */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68}, // done - /* biIceMountains */ { 0.2f, 2.0f, 0.05f, 10.0f, 0.01f, 8.0f, 80}, // done - /* biMushroomIsland */ { 0.1f, 2.0f, 0.05f, 8.0f, 0.01f, 6.0f, 80}, // done - /* biMushroomShore */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 64}, // done - /* biBeach */ { 0.1f, 0.5f, 0.05f, 1.0f, 0.01f, 1.0f, 64}, // done - /* biDesertHills */ { 0.2f, 2.0f, 0.05f, 5.0f, 0.01f, 4.0f, 75}, // done - /* biForestHills */ { 0.2f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80}, // done - /* biTaigaHills */ { 0.2f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80}, // done - /* biExtremeHillsEdge */ { 0.2f, 3.0f, 0.05f, 16.0f, 0.01f, 12.0f, 80}, // done - /* biJungle */ { 0.1f, 3.0f, 0.05f, 6.0f, 0.01f, 6.0f, 70}, // done - /* biJungleHills */ { 0.2f, 3.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80}, // done -} ; - - - - - -void cHeiGenBiomal::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) -{ - // Generate a 3x3 chunk area of biomes around this chunk: - BiomeNeighbors Biomes; - for (int z = -1; z <= 1; z++) - { - for (int x = -1; x <= 1; x++) - { - m_BiomeGen.GenBiomes(a_ChunkX + x, a_ChunkZ + z, Biomes[x + 1][z + 1]); - } // for x - } // for z - - // For each height, go through neighboring biomes and add up their idea of height: - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int x = 0; x < cChunkDef::Width; x++) - { - cChunkDef::SetHeight(a_HeightMap, x, z, GetHeightAt(x, z, a_ChunkX, a_ChunkZ, Biomes)); - } // for x - } -} - - - - - -HEIGHTTYPE cHeiGenBiomal::GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, int a_ChunkZ, const cHeiGenBiomal::BiomeNeighbors & a_BiomeNeighbors) -{ - // Sum up how many biomes of each type there are in the neighborhood: - int BiomeCounts[biNumBiomes]; - memset(BiomeCounts, 0, sizeof(BiomeCounts)); - int Sum = 0; - for (int z = -8; z <= 8; z++) - { - int FinalZ = a_RelZ + z + cChunkDef::Width; - int IdxZ = FinalZ / cChunkDef::Width; - int ModZ = FinalZ % cChunkDef::Width; - int WeightZ = 9 - abs(z); - for (int x = -8; x <= 8; x++) - { - int FinalX = a_RelX + x + cChunkDef::Width; - int IdxX = FinalX / cChunkDef::Width; - int ModX = FinalX % cChunkDef::Width; - EMCSBiome Biome = cChunkDef::GetBiome(a_BiomeNeighbors[IdxX][IdxZ], ModX, ModZ); - if ((Biome < 0) || (Biome >= ARRAYCOUNT(BiomeCounts))) - { - continue; - } - int WeightX = 9 - abs(x); - BiomeCounts[Biome] += WeightX + WeightZ; - Sum += WeightX + WeightZ; - } // for x - } // for z - - // For each biome type that has a nonzero count, calc its height and add it: - if (Sum > 0) - { - int Height = 0; - int BlockX = a_ChunkX * cChunkDef::Width + a_RelX; - int BlockZ = a_ChunkZ * cChunkDef::Width + a_RelZ; - for (int i = 0; i < ARRAYCOUNT(BiomeCounts); i++) - { - if (BiomeCounts[i] == 0) - { - continue; - } - float oct1 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq1, BlockZ * m_GenParam[i].m_HeightFreq1) * m_GenParam[i].m_HeightAmp1; - float oct2 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq2, BlockZ * m_GenParam[i].m_HeightFreq2) * m_GenParam[i].m_HeightAmp2; - float oct3 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq3, BlockZ * m_GenParam[i].m_HeightFreq3) * m_GenParam[i].m_HeightAmp3; - Height += BiomeCounts[i] * (int)(m_GenParam[i].m_BaseHeight + oct1 + oct2 + oct3); - } - int res = (HEIGHTTYPE)(Height / Sum); - return std::min(250, std::max(res, 5)); - } - - // No known biome around? Weird. Return a bogus value: - ASSERT(!"cHeiGenBiomal: Biome sum failed, no known biome around"); - return 5; -} - - - - - + +// HeiGen.cpp + +// Implements the various terrain height generators + +#include "Globals.h" +#include "HeiGen.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cHeiGenFlat: + +void cHeiGenFlat::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) +{ + for (int i = 0; i < ARRAYCOUNT(a_HeightMap); i++) + { + a_HeightMap[i] = m_Height; + } +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cHeiGenCache: + +cHeiGenCache::cHeiGenCache(cTerrainHeightGen * a_HeiGenToCache, int a_CacheSize) : + m_HeiGenToCache(a_HeiGenToCache), + m_CacheSize(a_CacheSize), + m_CacheOrder(new int[a_CacheSize]), + m_CacheData(new sCacheData[a_CacheSize]), + m_NumHits(0), + m_NumMisses(0), + m_TotalChain(0) +{ + for (int i = 0; i < m_CacheSize; i++) + { + m_CacheOrder[i] = i; + m_CacheData[i].m_ChunkX = 0x7fffffff; + m_CacheData[i].m_ChunkZ = 0x7fffffff; + } +} + + + + + +cHeiGenCache::~cHeiGenCache() +{ + delete m_CacheData; + delete m_CacheOrder; + delete m_HeiGenToCache; +} + + + + + +void cHeiGenCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) +{ + if (((m_NumHits + m_NumMisses) % 1024) == 10) + { + LOGD("HeiGenCache: %d hits, %d misses, saved %.2f %%", m_NumHits, m_NumMisses, 100.0 * m_NumHits / (m_NumHits + m_NumMisses)); + LOGD("HeiGenCache: Avg cache chain length: %.2f", (float)m_TotalChain / m_NumHits); + } + + for (int i = 0; i < m_CacheSize; i++) + { + if ( + (m_CacheData[m_CacheOrder[i]].m_ChunkX != a_ChunkX) || + (m_CacheData[m_CacheOrder[i]].m_ChunkZ != a_ChunkZ) + ) + { + continue; + } + // Found it in the cache + int Idx = m_CacheOrder[i]; + + // Move to front: + for (int j = i; j > 0; j--) + { + m_CacheOrder[j] = m_CacheOrder[j - 1]; + } + m_CacheOrder[0] = Idx; + + // Use the cached data: + memcpy(a_HeightMap, m_CacheData[Idx].m_HeightMap, sizeof(a_HeightMap)); + + m_NumHits++; + m_TotalChain += i; + return; + } // for i - cache + + // Not in the cache: + m_NumMisses++; + m_HeiGenToCache->GenHeightMap(a_ChunkX, a_ChunkZ, a_HeightMap); + + // Insert it as the first item in the MRU order: + int Idx = m_CacheOrder[m_CacheSize - 1]; + for (int i = m_CacheSize - 1; i > 0; i--) + { + m_CacheOrder[i] = m_CacheOrder[i - 1]; + } // for i - m_CacheOrder[] + m_CacheOrder[0] = Idx; + memcpy(m_CacheData[Idx].m_HeightMap, a_HeightMap, sizeof(a_HeightMap)); + m_CacheData[Idx].m_ChunkX = a_ChunkX; + m_CacheData[Idx].m_ChunkZ = a_ChunkZ; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cHeiGenClassic: + +cHeiGenClassic::cHeiGenClassic(int a_Seed, float a_HeightFreq1, float a_HeightAmp1, float a_HeightFreq2, float a_HeightAmp2, float a_HeightFreq3, float a_HeightAmp3) : + m_Seed(a_Seed), + m_Noise(a_Seed), + m_HeightFreq1(a_HeightFreq1), + m_HeightAmp1 (a_HeightAmp1), + m_HeightFreq2(a_HeightFreq2), + m_HeightAmp2 (a_HeightAmp2), + m_HeightFreq3(a_HeightFreq3), + m_HeightAmp3 (a_HeightAmp3) +{ + // Nothing needed yet +} + + + + + +float cHeiGenClassic::GetNoise(float x, float y) +{ + float oct1 = m_Noise.CubicNoise2D(x * m_HeightFreq1, y * m_HeightFreq1) * m_HeightAmp1; + float oct2 = m_Noise.CubicNoise2D(x * m_HeightFreq2, y * m_HeightFreq2) * m_HeightAmp2; + float oct3 = m_Noise.CubicNoise2D(x * m_HeightFreq3, y * m_HeightFreq3) * m_HeightAmp3; + + float height = m_Noise.CubicNoise2D(x * 0.1f, y * 0.1f ) * 2; + + float flatness = ((m_Noise.CubicNoise2D(x * 0.5f, y * 0.5f) + 1.f) * 0.5f) * 1.1f; // 0 ... 1.5 + flatness *= flatness * flatness; + + return (oct1 + oct2 + oct3) * flatness + height; +} + + + + + +void cHeiGenClassic::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) +{ + for (int z = 0; z < cChunkDef::Width; z++) + { + const float zz = (float)(a_ChunkZ * cChunkDef::Width + z); + for (int x = 0; x < cChunkDef::Width; x++) + { + const float xx = (float)(a_ChunkX * cChunkDef::Width + x); + + int hei = 64 + (int)(GetNoise(xx * 0.05f, zz * 0.05f) * 16); + if (hei < 10) + { + hei = 10; + } + if (hei > 250) + { + hei = 250; + } + cChunkDef::SetHeight(a_HeightMap, x , z, hei); + } // for x + } // for z +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cHeiGenBiomal: + +const cHeiGenBiomal::sGenParam cHeiGenBiomal::m_GenParam[biNumBiomes] = +{ + /* Fast-changing | Middle-changing | Slow-changing |*/ + /* Biome | Freq1 | Amp1 | Freq2 | Amp2 | Freq3 | Amp3 | BaseHeight */ + /* biOcean */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // done + /* biPlains */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68}, // done + /* biDesert */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68}, // done + /* biExtremeHills */ { 0.2f, 4.0f, 0.05f, 20.0f, 0.01f, 16.0f, 100}, // done + /* biForest */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // done + /* biTaiga */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // done + /* biSwampland */ { 0.1f, 1.1f, 0.05f, 1.5f, 0.02f, 2.5f, 61.5}, // done + /* biRiver */ { 0.2f, 3.0f, 0.05f, 1.0f, 0.01f, 1.0f, 56}, // done + /* biNether */ { 0.1f, 0.0f, 0.01f, 0.0f, 0.01f, 0.0f, 0}, // Unused, but must be here due to indexing + /* biSky */ { 0.1f, 0.0f, 0.01f, 0.0f, 0.01f, 0.0f, 0}, // Unused, but must be here due to indexing + /* biFrozenOcean */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // done + /* biFrozenRiver */ { 0.2f, 3.0f, 0.05f, 1.0f, 0.01f, 1.0f, 56}, // done + /* biIcePlains */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68}, // done + /* biIceMountains */ { 0.2f, 2.0f, 0.05f, 10.0f, 0.01f, 8.0f, 80}, // done + /* biMushroomIsland */ { 0.1f, 2.0f, 0.05f, 8.0f, 0.01f, 6.0f, 80}, // done + /* biMushroomShore */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 64}, // done + /* biBeach */ { 0.1f, 0.5f, 0.05f, 1.0f, 0.01f, 1.0f, 64}, // done + /* biDesertHills */ { 0.2f, 2.0f, 0.05f, 5.0f, 0.01f, 4.0f, 75}, // done + /* biForestHills */ { 0.2f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80}, // done + /* biTaigaHills */ { 0.2f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80}, // done + /* biExtremeHillsEdge */ { 0.2f, 3.0f, 0.05f, 16.0f, 0.01f, 12.0f, 80}, // done + /* biJungle */ { 0.1f, 3.0f, 0.05f, 6.0f, 0.01f, 6.0f, 70}, // done + /* biJungleHills */ { 0.2f, 3.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80}, // done +} ; + + + + + +void cHeiGenBiomal::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) +{ + // Generate a 3x3 chunk area of biomes around this chunk: + BiomeNeighbors Biomes; + for (int z = -1; z <= 1; z++) + { + for (int x = -1; x <= 1; x++) + { + m_BiomeGen.GenBiomes(a_ChunkX + x, a_ChunkZ + z, Biomes[x + 1][z + 1]); + } // for x + } // for z + + // For each height, go through neighboring biomes and add up their idea of height: + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + cChunkDef::SetHeight(a_HeightMap, x, z, GetHeightAt(x, z, a_ChunkX, a_ChunkZ, Biomes)); + } // for x + } +} + + + + + +HEIGHTTYPE cHeiGenBiomal::GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, int a_ChunkZ, const cHeiGenBiomal::BiomeNeighbors & a_BiomeNeighbors) +{ + // Sum up how many biomes of each type there are in the neighborhood: + int BiomeCounts[biNumBiomes]; + memset(BiomeCounts, 0, sizeof(BiomeCounts)); + int Sum = 0; + for (int z = -8; z <= 8; z++) + { + int FinalZ = a_RelZ + z + cChunkDef::Width; + int IdxZ = FinalZ / cChunkDef::Width; + int ModZ = FinalZ % cChunkDef::Width; + int WeightZ = 9 - abs(z); + for (int x = -8; x <= 8; x++) + { + int FinalX = a_RelX + x + cChunkDef::Width; + int IdxX = FinalX / cChunkDef::Width; + int ModX = FinalX % cChunkDef::Width; + EMCSBiome Biome = cChunkDef::GetBiome(a_BiomeNeighbors[IdxX][IdxZ], ModX, ModZ); + if ((Biome < 0) || (Biome >= ARRAYCOUNT(BiomeCounts))) + { + continue; + } + int WeightX = 9 - abs(x); + BiomeCounts[Biome] += WeightX + WeightZ; + Sum += WeightX + WeightZ; + } // for x + } // for z + + // For each biome type that has a nonzero count, calc its height and add it: + if (Sum > 0) + { + int Height = 0; + int BlockX = a_ChunkX * cChunkDef::Width + a_RelX; + int BlockZ = a_ChunkZ * cChunkDef::Width + a_RelZ; + for (int i = 0; i < ARRAYCOUNT(BiomeCounts); i++) + { + if (BiomeCounts[i] == 0) + { + continue; + } + float oct1 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq1, BlockZ * m_GenParam[i].m_HeightFreq1) * m_GenParam[i].m_HeightAmp1; + float oct2 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq2, BlockZ * m_GenParam[i].m_HeightFreq2) * m_GenParam[i].m_HeightAmp2; + float oct3 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq3, BlockZ * m_GenParam[i].m_HeightFreq3) * m_GenParam[i].m_HeightAmp3; + Height += BiomeCounts[i] * (int)(m_GenParam[i].m_BaseHeight + oct1 + oct2 + oct3); + } + int res = (HEIGHTTYPE)(Height / Sum); + return std::min(250, std::max(res, 5)); + } + + // No known biome around? Weird. Return a bogus value: + ASSERT(!"cHeiGenBiomal: Biome sum failed, no known biome around"); + return 5; +} + + + + + diff --git a/source/HeiGen.h b/source/HeiGen.h index d3074487f..e5b20c334 100644 --- a/source/HeiGen.h +++ b/source/HeiGen.h @@ -1,137 +1,137 @@ - -// HeiGen.h - -/* -Interfaces to the various height generators: - - cHeiGenFlat - - cHeiGenClassic - - cHeiGenBiomal -*/ - - - - - -#pragma once - -#include "cChunkGenerator.h" -#include "cNoise.h" - - - - - -class cHeiGenFlat : - public cTerrainHeightGen -{ -public: - cHeiGenFlat(int a_Height) : m_Height(a_Height) {} - -protected: - - int m_Height; - - // cTerrainHeightGen override: - virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; -} ; - - - - - -/// A simple cache that stores N most recently generated chunks' heightmaps; N being settable upon creation -class cHeiGenCache : - public cTerrainHeightGen -{ -public: - cHeiGenCache(cTerrainHeightGen * a_HeiGenToCache, int a_CacheSize); // Takes ownership of a_HeiGenToCache - ~cHeiGenCache(); - -protected: - - cTerrainHeightGen * m_HeiGenToCache; - - struct sCacheData - { - int m_ChunkX; - int m_ChunkZ; - cChunkDef::HeightMap m_HeightMap; - } ; - - // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data - int m_CacheSize; - int * m_CacheOrder; // MRU-ized order, indices into m_CacheData array - sCacheData * m_CacheData; // m_CacheData[m_CacheOrder[0]] is the most recently used - - // Cache statistics - int m_NumHits; - int m_NumMisses; - int m_TotalChain; // Number of cache items walked to get to a hit (only added for hits) - - virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; -} ; - - - - - -class cHeiGenClassic : - public cTerrainHeightGen -{ -public: - cHeiGenClassic(int a_Seed, float a_HeightFreq1, float a_HeightAmp1, float a_HeightFreq2, float a_HeightAmp2, float a_HeightFreq3, float a_HeightAmp3); - -protected: - - int m_Seed; - cNoise m_Noise; - float m_HeightFreq1, m_HeightAmp1; - float m_HeightFreq2, m_HeightAmp2; - float m_HeightFreq3, m_HeightAmp3; - - float GetNoise(float x, float y); - - // cTerrainHeightGen override: - virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; -} ; - - - - - -class cHeiGenBiomal : - public cTerrainHeightGen -{ -public: - cHeiGenBiomal(int a_Seed, cBiomeGen & a_BiomeGen) : - m_Noise(a_Seed), - m_BiomeGen(a_BiomeGen) - { - } - -protected: - - typedef cChunkDef::BiomeMap BiomeNeighbors[3][3]; - - cNoise m_Noise; - cBiomeGen & m_BiomeGen; - - // Per-biome terrain generator parameters: - struct sGenParam - { - float m_HeightFreq1, m_HeightAmp1; - float m_HeightFreq2, m_HeightAmp2; - float m_HeightFreq3, m_HeightAmp3; - float m_BaseHeight; - } ; - static const sGenParam m_GenParam[biNumBiomes]; - - // cTerrainHeightGen override: - virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; - - HEIGHTTYPE GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, int a_ChunkZ, const BiomeNeighbors & a_BiomeNeighbors); -} ; - - - - + +// HeiGen.h + +/* +Interfaces to the various height generators: + - cHeiGenFlat + - cHeiGenClassic + - cHeiGenBiomal +*/ + + + + + +#pragma once + +#include "cChunkGenerator.h" +#include "cNoise.h" + + + + + +class cHeiGenFlat : + public cTerrainHeightGen +{ +public: + cHeiGenFlat(int a_Height) : m_Height(a_Height) {} + +protected: + + int m_Height; + + // cTerrainHeightGen override: + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; +} ; + + + + + +/// A simple cache that stores N most recently generated chunks' heightmaps; N being settable upon creation +class cHeiGenCache : + public cTerrainHeightGen +{ +public: + cHeiGenCache(cTerrainHeightGen * a_HeiGenToCache, int a_CacheSize); // Takes ownership of a_HeiGenToCache + ~cHeiGenCache(); + +protected: + + cTerrainHeightGen * m_HeiGenToCache; + + struct sCacheData + { + int m_ChunkX; + int m_ChunkZ; + cChunkDef::HeightMap m_HeightMap; + } ; + + // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data + int m_CacheSize; + int * m_CacheOrder; // MRU-ized order, indices into m_CacheData array + sCacheData * m_CacheData; // m_CacheData[m_CacheOrder[0]] is the most recently used + + // Cache statistics + int m_NumHits; + int m_NumMisses; + int m_TotalChain; // Number of cache items walked to get to a hit (only added for hits) + + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; +} ; + + + + + +class cHeiGenClassic : + public cTerrainHeightGen +{ +public: + cHeiGenClassic(int a_Seed, float a_HeightFreq1, float a_HeightAmp1, float a_HeightFreq2, float a_HeightAmp2, float a_HeightFreq3, float a_HeightAmp3); + +protected: + + int m_Seed; + cNoise m_Noise; + float m_HeightFreq1, m_HeightAmp1; + float m_HeightFreq2, m_HeightAmp2; + float m_HeightFreq3, m_HeightAmp3; + + float GetNoise(float x, float y); + + // cTerrainHeightGen override: + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; +} ; + + + + + +class cHeiGenBiomal : + public cTerrainHeightGen +{ +public: + cHeiGenBiomal(int a_Seed, cBiomeGen & a_BiomeGen) : + m_Noise(a_Seed), + m_BiomeGen(a_BiomeGen) + { + } + +protected: + + typedef cChunkDef::BiomeMap BiomeNeighbors[3][3]; + + cNoise m_Noise; + cBiomeGen & m_BiomeGen; + + // Per-biome terrain generator parameters: + struct sGenParam + { + float m_HeightFreq1, m_HeightAmp1; + float m_HeightFreq2, m_HeightAmp2; + float m_HeightFreq3, m_HeightAmp3; + float m_BaseHeight; + } ; + static const sGenParam m_GenParam[biNumBiomes]; + + // cTerrainHeightGen override: + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; + + HEIGHTTYPE GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, int a_ChunkZ, const BiomeNeighbors & a_BiomeNeighbors); +} ; + + + + diff --git a/source/LeakFinder.cpp b/source/LeakFinder.cpp index 1490025f8..769b52222 100644 --- a/source/LeakFinder.cpp +++ b/source/LeakFinder.cpp @@ -1,1040 +1,1040 @@ - -// LeakFinder.cpp - -// Finds memory leaks rather effectively - -// _X: downloaded from http://www.codeproject.com/Articles/3134/Memory-Leak-and-Exception-Trace-CRT-and-COM-Leaks - the real link is in the comments, RC11 version - - - - - -/********************************************************************** - * - * LEAKFINDER.CPP - * - * - * - * History: - * 2010-04-15 RC10 - Updated to VC10 RTM - * Fixed Bug: Application Verifier, thanks to handsinmypocket! - * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=3439751#xx3439751xx - * 2008-08-04 RC6 - Updated to VC9 RTM - * Fixed Bug: Missing "ole32.lib" LIB - * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=2253980#xx2253980xx - * Fixed Bug: Compiled with "WIN32_LEAN_AND_MEAN" - * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=1824718#xx1824718xx - * Fixed Bug: Compiling with "/Wall" - * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=2638243#xx2638243xx - * Removed "#pragma init_seg (compiler)" from h-file - * - * 2005-12-30 RC5 - Now again VC8 RTM compatible - * - Added Xml-Output (like in the old Leakfinder) - * YOu need to define XML_LEAK_FINDER to activate it - * So you can use the LeakAnalyseTool from - * http://www.codeproject.com/tools/leakfinder.asp - * - * 2005-12-13 RC4 - Merged with the new "StackWalker"-project on - * http://www.codeproject.com/threads/StackWalker.asp - * - * 2005-08-01 RC3 - Merged with the new "StackWalker"-project on - * http://www.codeproject.com/threads/StackWalker.asp - * - * 2005-07-05 RC2 - First version with x86, IA64 and x64 support - * - * 2005-07-04 RC1 - Added "OutputOptions" - * - New define "INIT_LEAK_FINDER_VERBOSE" to - * display more info (for error reporting) - * - * 2005-07-01 Beta3 - Workaround for a bug in the new dbghelp.dll - * (version 6.5.3.7 from 2005-05-30; StakWalk64 no - * refused to produce an callstack on x86 systems - * if the context is NULL or has some registers set - * to 0 (for example Esp). This is against the - * documented behaviour of StackWalk64...) - * - First version with x64-support - * - * 2005-06-16 Beta1 First public release with the following features: - * - Completely rewritten in C++ (object oriented) - * - CRT-Leak-Report - * - COM-Leak-Report - * - Report is done via "OutputDebugString" so - * the line can directly selected in the debugger - * and is opening the corresponding file/line of - * the allocation - * - Tried to support x64 systems, bud had some - * trouble wih StackWalk64 - * See: http://blog.kalmbachnet.de/?postid=43 - * - * LICENSE (http://www.opensource.org/licenses/bsd-license.php) - * - * Copyright (c) 2005-2010, Jochen Kalmbach - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * Neither the name of Jochen Kalmbach nor the names of its contributors may be - * used to endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - **********************************************************************/ - -#include -#include // Needed if compiled with "WIN32_LEAN_AND_MEAN" -#include -#include -#include - -#include -#include - - -#include "LeakFinder.h" - -// Currently only tested with MS VC++ 5 to 10 -#if (_MSC_VER < 1100) || (_MSC_VER > 1600) -#error Only MS VC++ 5/6/7/7.1/8/9 supported. Check if the '_CrtMemBlockHeader' has not changed with this compiler! -#endif - - -// Controlling the callstack depth -#define MAX_CALLSTACK_LEN_BUF 0x2000 - -#define IGNORE_CRT_ALLOC - -// disable 64-bit compatibility-checks (because we explicite have here either x86 or x64!) -#pragma warning(disable:4312) // warning C4312: 'type cast' : conversion from 'DWORD' to 'LPCVOID' of greater size -#pragma warning(disable:4826) - - -// secure-CRT_functions are only available starting with VC8 -#if _MSC_VER < 1400 -#define _snprintf_s _snprintf -#define _tcscat_s _tcscat -#endif - -static std::string SimpleXMLEncode(LPCSTR szText) -{ - std::string szRet; - for (size_t i=0; i': - szRet.append(">"); - break; - case '"': - szRet.append("""); - break; - case '\'': - szRet.append("'"); - break; - default: - szRet += szText[i]; - } - } - return szRet; -} - - -LeakFinderOutput::LeakFinderOutput(int options, LPCSTR szSymPath) - : StackWalker(options, szSymPath) -{ -} -void LeakFinderOutput::OnLeakSearchStart(LPCSTR szLeakFinderName) -{ - CHAR buffer[1024]; - _snprintf_s(buffer, 1024, "######## %s ########\n", szLeakFinderName); - this->OnOutput(buffer); -} -void LeakFinderOutput::OnLeakStartEntry(LPCSTR szKeyName, SIZE_T nDataSize) -{ - CHAR buffer[1024]; - _snprintf_s(buffer, 1024, "--------------- Key: %s, %d bytes ---------\n", szKeyName, nDataSize); - this->OnOutput(buffer); -} -void LeakFinderOutput::OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry) -{ - if ( (eType != lastEntry) && (entry.offset != 0) ) - { - if ( ((this->m_options & LeakFinderShowCompleteCallstack) == 0) && ( - (strstr(entry.lineFileName, "afxmem.cpp") != NULL) || - (strstr(entry.lineFileName, "dbgheap.c") != NULL) || - (strstr(entry.lineFileName, "new.cpp") != NULL) || - (strstr(entry.lineFileName, "newop.cpp") != NULL) || - (strstr(entry.lineFileName, "leakfinder.cpp") != NULL) || - (strstr(entry.lineFileName, "stackwalker.cpp") != NULL) - ) ) - { - return; - } - } - StackWalker::OnCallstackEntry(eType, entry); -} - - -// #################################################################### -// XML-Output -LeakFinderXmlOutput::LeakFinderXmlOutput() -{ - TCHAR szXMLFileName[1024]; - - GetModuleFileName(NULL, szXMLFileName, sizeof(szXMLFileName) / sizeof(TCHAR)); - _tcscat_s(szXMLFileName, _T(".mem.xml-leaks")); -#if _MSC_VER < 1400 - m_fXmlFile = _tfopen(szXMLFileName, _T("w")); -#else - m_fXmlFile = NULL; - _tfopen_s(&m_fXmlFile, szXMLFileName, _T("w")); -#endif - if (m_fXmlFile != NULL) - { - SYSTEMTIME st; - GetLocalTime(&st); - fprintf(m_fXmlFile, "\n", - st.wMonth, st.wDay, st.wYear, - st.wHour, st.wMinute, st.wSecond); - } - else - { - MessageBox(NULL, _T("Could not open xml-logfile for leakfinder!"), _T("Warning"), MB_ICONHAND); - } -} -LeakFinderXmlOutput::LeakFinderXmlOutput(LPCTSTR szFileName) -{ -#if _MSC_VER < 1400 - m_fXmlFile = _tfopen(szFileName, _T("w")); -#else - m_fXmlFile = NULL; - _tfopen_s(&m_fXmlFile, szFileName, _T("w")); -#endif - if (m_fXmlFile == NULL) - { - MessageBox(NULL, _T("Could not open xml-logfile for leakfinder!"), _T("Warning"), MB_ICONHAND); - } -} -LeakFinderXmlOutput::~LeakFinderXmlOutput() -{ - if (m_fXmlFile != NULL) - { - // Write the ending-tags and close the file - fprintf(m_fXmlFile, "\n"); - fclose(m_fXmlFile); - } - m_fXmlFile = NULL; -} -void LeakFinderXmlOutput::OnLeakSearchStart(LPCSTR sszLeakFinderName) -{ -} -void LeakFinderXmlOutput::OnLeakStartEntry(LPCSTR szKeyName, SIZE_T nDataSize) -{ - if (m_fXmlFile != NULL) - { - fprintf(m_fXmlFile, " \n", SimpleXMLEncode(szKeyName).c_str(), nDataSize); - } -} -void LeakFinderXmlOutput::OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry) -{ - if (m_fXmlFile != NULL) - { - if (eType != lastEntry) - { - fprintf(m_fXmlFile, " \n"); - } - else - { - fprintf(m_fXmlFile, " \n"); - } - } -} - -// ########################################################################## -// ########################################################################## -// ########################################################################## -// Base class for storing contexts in a hashtable -template class ContextHashtableBase -{ -public: - ContextHashtableBase(SIZE_T sizeOfHastable, LPCSTR finderName) - { - SIZE_T s = sizeOfHastable*sizeof(AllocHashEntryType); - m_hHeap = HeapCreate(0, 10*1024 + s, 0); - if (m_hHeap == NULL) - throw; - pAllocHashTable = (AllocHashEntryType*) own_malloc(s); - sAllocEntries = sizeOfHastable; - m_finderName = own_strdup(finderName); - } - -protected: - virtual ~ContextHashtableBase() - { - if (pAllocHashTable != NULL) - own_free(pAllocHashTable); - pAllocHashTable = NULL; - - own_free(m_finderName); - m_finderName = NULL; - - if (m_hHeap != NULL) - HeapDestroy(m_hHeap); - } - - __inline LPVOID own_malloc(SIZE_T size) - { - return HeapAlloc(m_hHeap, HEAP_ZERO_MEMORY, size); - } - __inline VOID own_free(LPVOID memblock) - { - HeapFree(m_hHeap, 0, memblock); - } - __inline CHAR *own_strdup(const char *str) - { - size_t len = strlen(str)+1; - CHAR *c = (CHAR*)own_malloc(len); -#if _MSC_VER >= 1400 - strcpy_s(c, len, str); -#else - strcpy(c, str); -#endif - return c; - } - - // Disables this leak-finder - virtual LONG Disable() = 0; - // enables the leak-finder again... - virtual LONG Enable() = 0; - -private: - // Entry for each allocation - typedef struct AllocHashEntryType { - HASHTABLE_KEY key; - SIZE_T nDataSize; // Size of the allocated memory - struct AllocHashEntryType *Next; - CONTEXT c; - PVOID pStackBaseAddr; - SIZE_T nMaxStackSize; - - PVOID pCallstackOffset; - SIZE_T nCallstackLen; - char pcCallstackAddr[MAX_CALLSTACK_LEN_BUF]; // min of both values... - } AllocHashEntryType; - -protected: - virtual SIZE_T HashFunction(HASHTABLE_KEY &key) = 0; - virtual BOOL IsKeyEmpty(HASHTABLE_KEY &key) = 0; - virtual VOID SetEmptyKey(HASHTABLE_KEY &key) = 0; - virtual VOID GetKeyAsString(HASHTABLE_KEY &key, CHAR *szName, SIZE_T nBufferLen) = 0; - //virtual SIZE_T GetNativeBytes(HASHTABLE_KEY &key, CHAR *szName, SIZE_T nBufferLen) { return 0; } - -public: - VOID Insert(HASHTABLE_KEY &key, CONTEXT &context, SIZE_T nDataSize) - { - SIZE_T HashIdx; - AllocHashEntryType *pHashEntry; - - // generate hash-value - HashIdx = HashFunction(key); - - pHashEntry = &pAllocHashTable[HashIdx]; - if (IsKeyEmpty(pHashEntry->key) != FALSE) { - // Entry is empty... - } - else { - // Entry is not empy! make a list of entries for this hash value... - while(pHashEntry->Next != NULL) { - pHashEntry = pHashEntry->Next; - } - - pHashEntry->Next = (AllocHashEntryType*) own_malloc(sizeof(AllocHashEntryType)); - pHashEntry = pHashEntry->Next; - } - pHashEntry->key = key; - pHashEntry->nDataSize = nDataSize; - pHashEntry->Next = NULL; -#ifdef _M_IX86 - pHashEntry->pCallstackOffset = (LPVOID) min(context.Ebp, context.Esp); -#elif _M_X64 - pHashEntry->pCallstackOffset = (LPVOID) min(context.Rdi, context.Rsp); -#elif _M_IA64 - pHashEntry->pCallstackOffset = (LPVOID) min(context.IntSp, context.RsBSP); -#else -#error "Platform not supported!" -#endif - pHashEntry->c = context; - - // Query the max. stack-area: - MEMORY_BASIC_INFORMATION MemBuffer; - if(VirtualQuery((LPCVOID) pHashEntry->pCallstackOffset, &MemBuffer, sizeof(MemBuffer)) > 0) - { - pHashEntry->pStackBaseAddr = MemBuffer.BaseAddress; - pHashEntry->nMaxStackSize = MemBuffer.RegionSize; - } - else - { - pHashEntry->pStackBaseAddr = 0; - pHashEntry->nMaxStackSize = 0; - } - - SIZE_T bytesToRead = MAX_CALLSTACK_LEN_BUF; - if (pHashEntry->nMaxStackSize > 0) - { - SIZE_T len = ((SIZE_T) pHashEntry->pStackBaseAddr + pHashEntry->nMaxStackSize) - (SIZE_T)pHashEntry->pCallstackOffset; - bytesToRead = min(len, MAX_CALLSTACK_LEN_BUF); - } - // Now read the callstack: - if (ReadProcessMemory(GetCurrentProcess(), (LPCVOID) pHashEntry->pCallstackOffset, &(pHashEntry->pcCallstackAddr), bytesToRead, &(pHashEntry->nCallstackLen)) == 0) - { - // Could not read memory... - pHashEntry->nCallstackLen = 0; - pHashEntry->pCallstackOffset = 0; - } // read callstack - } // Insert - - BOOL Remove(HASHTABLE_KEY &key) - { - SIZE_T HashIdx; - AllocHashEntryType *pHashEntry, *pHashEntryLast; - - // get the Hash-Value - HashIdx = HashFunction(key); - - pHashEntryLast = NULL; - pHashEntry = &pAllocHashTable[HashIdx]; - while(pHashEntry != NULL) { - if (pHashEntry->key == key) { - // release my memory - if (pHashEntryLast == NULL) { - // It is an entry in the table, so do not release this memory - if (pHashEntry->Next == NULL) { - // It was the last entry, so empty the table entry - SetEmptyKey(pAllocHashTable[HashIdx].key); - //memset(&pAllocHashTable[HashIdx], 0, sizeof(pAllocHashTable[HashIdx])); - } - else { - // There are some more entries, so shorten the list - AllocHashEntryType *pTmp = pHashEntry->Next; - *pHashEntry = *(pHashEntry->Next); - own_free(pTmp); - } - return TRUE; - } - else { - // now, I am in an dynamic allocated entry (it was a collision) - pHashEntryLast->Next = pHashEntry->Next; - own_free(pHashEntry); - return TRUE; - } - } - pHashEntryLast = pHashEntry; - pHashEntry = pHashEntry->Next; - } - - // if we are here, we could not find the RequestID - return FALSE; - } - - AllocHashEntryType *Find(HASHTABLE_KEY &key) - { - SIZE_T HashIdx; - AllocHashEntryType *pHashEntry; - - // get the Hash-Value - HashIdx = HashFunction(key); - - pHashEntry = &pAllocHashTable[HashIdx]; - while(pHashEntry != NULL) { - if (pHashEntry->key == key) { - return pHashEntry; - } - pHashEntry = pHashEntry->Next; - } - - // entry was not found! - return NULL; - } - - // For the followong static-var See comment in "ShowCallstack"... - static BOOL CALLBACK ReadProcessMemoryFromHashEntry64( - HANDLE hProcess, // hProcess must be a pointer to an hash-entry! - DWORD64 lpBaseAddress, - PVOID lpBuffer, - DWORD nSize, - LPDWORD lpNumberOfBytesRead, - LPVOID pUserData // optional data, which was passed in "ShowCallstack" - ) - { - *lpNumberOfBytesRead = 0; - AllocHashEntryType *pHashEntry = (AllocHashEntryType*) pUserData; - if (pHashEntry == NULL) - { - return FALSE; - } - - if ( ( (DWORD64)lpBaseAddress >= (DWORD64)pHashEntry->pCallstackOffset) && ((DWORD64)lpBaseAddress <= ((DWORD64)pHashEntry->pCallstackOffset+pHashEntry->nCallstackLen)) ) { - // Memory is located in saved Callstack: - // Calculate the offset - DWORD dwOffset = (DWORD) ((DWORD64)lpBaseAddress - (DWORD64)pHashEntry->pCallstackOffset); - DWORD dwSize = __min(nSize, MAX_CALLSTACK_LEN_BUF-dwOffset); - memcpy(lpBuffer, &(pHashEntry->pcCallstackAddr[dwOffset]), dwSize); - *lpNumberOfBytesRead = dwSize; - if (dwSize != nSize) - { - return FALSE; - } - *lpNumberOfBytesRead = nSize; - return TRUE; - } - - if (*lpNumberOfBytesRead == 0) // Memory could not be found - { - if ( ( (DWORD64)lpBaseAddress < (DWORD64)pHashEntry->pStackBaseAddr) || ((DWORD64)lpBaseAddress > ((DWORD64)pHashEntry->pStackBaseAddr+pHashEntry->nMaxStackSize)) ) - { - // Stackwalking is done by reading the "real memory" (normally this happens when the StackWalk64 tries to read some code) - SIZE_T st = 0; - BOOL bRet = ReadProcessMemory(hProcess, (LPCVOID) lpBaseAddress, lpBuffer, nSize, &st); - *lpNumberOfBytesRead = (DWORD) st; - return bRet; - } - } - - return TRUE; - } - - VOID ShowLeaks(LeakFinderOutput &leakFinderOutput) - { - SIZE_T ulTemp; - AllocHashEntryType *pHashEntry; - ULONG ulCount = 0; - SIZE_T ulLeaksByte = 0; - - leakFinderOutput.OnLeakSearchStart(this->m_finderName); - - // Move throu every entry - CHAR keyName[1024]; - for(ulTemp = 0; ulTemp < this->sAllocEntries; ulTemp++) { - pHashEntry = &pAllocHashTable[ulTemp]; - if (IsKeyEmpty(pHashEntry->key) == FALSE) { - while(pHashEntry != NULL) { - ulCount++; - CONTEXT c; - memcpy(&c, &(pHashEntry->c), sizeof(CONTEXT)); - - this->GetKeyAsString(pHashEntry->key, keyName, 1024); - - leakFinderOutput.OnLeakStartEntry(keyName, pHashEntry->nDataSize); - leakFinderOutput.ShowCallstack(GetCurrentThread(), &c, ReadProcessMemoryFromHashEntry64, pHashEntry); - - // Count the number of leaky bytes - ulLeaksByte += pHashEntry->nDataSize; - - pHashEntry = pHashEntry->Next; - } // while - } - } - } - - AllocHashEntryType *pAllocHashTable; - SIZE_T sAllocEntries; - HANDLE m_hHeap; - LPSTR m_finderName; - bool m_bSupressUselessLines; -}; // template class ContextHashtableBase - - -// ########################################################################## -// ########################################################################## -// ########################################################################## -// Specialization for CRT-Leaks: -// VC5 has excluded all types in release-builds -#ifdef _DEBUG - -// The follwoing is copied from dbgint.h: -// -/* -* For diagnostic purpose, blocks are allocated with extra information and -* stored in a doubly-linked list. This makes all blocks registered with -* how big they are, when they were allocated, and what they are used for. -*/ - -// forward declaration: -#ifndef _M_CEE_PURE -#define MyAllocHookCallingConvention __cdecl -#endif -#if _MSC_VER >= 1400 -#ifdef _M_CEE -#define MyAllocHookCallingConvention __clrcall -#endif -#endif - -static int MyAllocHookCallingConvention MyAllocHook(int nAllocType, void *pvData, - size_t nSize, int nBlockUse, long lRequest, -#if _MSC_VER <= 1100 // Special case for VC 5 and before - const char * szFileName, -#else - const unsigned char * szFileName, -#endif - int nLine); - -static _CRT_ALLOC_HOOK s_pfnOldCrtAllocHook = NULL; -static LONG s_CrtDisableCount = 0; -static LONG s_lMallocCalled = 0; - - -class CRTTable : public ContextHashtableBase -{ -public: - CRTTable() : ContextHashtableBase(1021, "CRT-Leaks") - { - // save the previous alloc hook - s_pfnOldCrtAllocHook = _CrtSetAllocHook(MyAllocHook); - } - - virtual ~CRTTable() - { - _CrtSetAllocHook(s_pfnOldCrtAllocHook); - } - - virtual LONG Disable() - { - return InterlockedIncrement(&s_CrtDisableCount); - } - virtual LONG Enable() - { - return InterlockedDecrement(&s_CrtDisableCount); - } - - virtual SIZE_T HashFunction(LONG &key) - { - // I couldn´t find any better and faster - return key % sAllocEntries; - } - virtual BOOL IsKeyEmpty(LONG &key) - { - if (key == 0) - return TRUE; - return FALSE; - } - virtual VOID SetEmptyKey(LONG &key) - { - key = 0; - } - virtual VOID GetKeyAsString(LONG &key, CHAR *szName, SIZE_T nBufferLen) - { -#if _MSC_VER < 1400 - _snprintf_s(szName, nBufferLen, "%d", key); -#else - _snprintf_s(szName, nBufferLen, nBufferLen, "%d", key); -#endif - } - -protected: - CHAR *m_pBuffer; - SIZE_T m_maxBufferLen; - SIZE_T m_bufferLen; -}; // class CRTTable - - -#define nNoMansLandSize 4 - -typedef struct _CrtMemBlockHeader -{ - struct _CrtMemBlockHeader * pBlockHeaderNext; - struct _CrtMemBlockHeader * pBlockHeaderPrev; - char * szFileName; - int nLine; -#ifdef _WIN64 - /* These items are reversed on Win64 to eliminate gaps in the struct - * and ensure that sizeof(struct)%16 == 0, so 16-byte alignment is - * maintained in the debug heap. - */ - int nBlockUse; - size_t nDataSize; -#else /* _WIN64 */ - size_t nDataSize; - int nBlockUse; -#endif /* _WIN64 */ - long lRequest; - unsigned char gap[nNoMansLandSize]; - /* followed by: - * unsigned char data[nDataSize]; - * unsigned char anotherGap[nNoMansLandSize]; - */ -} _CrtMemBlockHeader; -#define pbData(pblock) ((unsigned char *)((_CrtMemBlockHeader *)pblock + 1)) -#define pHdr(pbData) (((_CrtMemBlockHeader *)pbData)-1) -// - -static CRTTable *g_pCRTTable = NULL; - - -// MyAllocHook is Single-Threaded, that means the the calls are serialized in the calling function! -static int MyAllocHook(int nAllocType, void *pvData, - size_t nSize, int nBlockUse, long lRequest, -#if _MSC_VER <= 1100 // Special case for VC 5 - const char * szFileName, -#else - const unsigned char * szFileName, -#endif - int nLine) -{ - //static TCHAR *operation[] = { _T(""), _T("ALLOCATIONG"), _T("RE-ALLOCATING"), _T("FREEING") }; - //static TCHAR *blockType[] = { _T("Free"), _T("Normal"), _T("CRT"), _T("Ignore"), _T("Client") }; - -#ifdef IGNORE_CRT_ALLOC - if (_BLOCK_TYPE(nBlockUse) == _CRT_BLOCK) // Ignore internal C runtime library allocations - return TRUE; -#endif - extern int _crtDbgFlag; - if ( ((_CRTDBG_ALLOC_MEM_DF & _crtDbgFlag) == 0) && ( (nAllocType == _HOOK_ALLOC) || (nAllocType == _HOOK_REALLOC) ) ) - { - // Someone has disabled that the runtime should log this allocation - // so we do not log this allocation - if (s_pfnOldCrtAllocHook != NULL) - s_pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); - return TRUE; - } - - // Handle the Disable/Enable setting - if (InterlockedExchangeAdd(&s_CrtDisableCount, 0) != 0) - return TRUE; - - // Prevent from reentrat calls - if (InterlockedIncrement(&s_lMallocCalled) > 1) { // I was already called - InterlockedDecrement(&s_lMallocCalled); - // call the previous alloc hook - if (s_pfnOldCrtAllocHook != NULL) - s_pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); - return TRUE; - } - - _ASSERT( (nAllocType == _HOOK_ALLOC) || (nAllocType == _HOOK_REALLOC) || (nAllocType == _HOOK_FREE) ); - _ASSERT( ( _BLOCK_TYPE(nBlockUse) >= 0 ) && ( _BLOCK_TYPE(nBlockUse) < 5 ) ); - - if (nAllocType == _HOOK_FREE) { // freeing - // Try to get the header information - if (_CrtIsValidHeapPointer(pvData)) { // it is a valid Heap-Pointer - // get the ID - _CrtMemBlockHeader *pHead; - // get a pointer to memory block header - pHead = pHdr(pvData); - nSize = pHead->nDataSize; - lRequest = pHead->lRequest; // This is the ID! - - if (pHead->nBlockUse == _IGNORE_BLOCK) - { - InterlockedDecrement(&s_lMallocCalled); - if (s_pfnOldCrtAllocHook != NULL) - s_pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); - return TRUE; - } - } - if (lRequest != 0) { // RequestID was found - g_pCRTTable->Remove(lRequest); - } - } // freeing - - if (nAllocType == _HOOK_REALLOC) { // re-allocating - // Try to get the header information - if (_CrtIsValidHeapPointer(pvData)) { // it is a valid Heap-Pointer - BOOL bRet; - LONG lReallocRequest; - // get the ID - _CrtMemBlockHeader *pHead; - // get a pointer to memory block header - pHead = pHdr(pvData); - // Try to find the RequestID in the Hash-Table, mark it that it was freed - lReallocRequest = pHead->lRequest; - bRet = g_pCRTTable->Remove(lReallocRequest); - } // ValidHeapPointer - } // re-allocating - - //if ( (g_ulShowStackAtAlloc < 3) && (nAllocType == _HOOK_FREE) ) { - if (nAllocType == _HOOK_FREE) { - InterlockedDecrement(&s_lMallocCalled); - // call the previous alloc hook - if (s_pfnOldCrtAllocHook != NULL) - s_pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); - return TRUE; - } - - CONTEXT c; - GET_CURRENT_CONTEXT(c, CONTEXT_FULL); - - // Only insert in the Hash-Table if it is not a "freeing" - if (nAllocType != _HOOK_FREE) { - if(lRequest != 0) // Always a valid RequestID should be provided (see comments in the header) - g_pCRTTable->Insert(lRequest, c, nSize); - } - - InterlockedDecrement(&s_lMallocCalled); - // call the previous alloc hook - if (s_pfnOldCrtAllocHook != NULL) - s_pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); - return TRUE; // allow the memory operation to proceed -} // MyAllocHook - -#endif // _DEBUG - - -// ########################################################################## -// ########################################################################## -// ########################################################################## -// Specialization for COM-Leaks: - -// forwards: -class COMTable; -class CMallocSpy : public IMallocSpy -{ -public: - CMallocSpy() { m_cbRequest = 0; m_cRef = 0; m_disableCount = 0; } - virtual ~CMallocSpy() {} - // IUnknown methods - STDMETHOD(QueryInterface) (REFIID riid, LPVOID *ppUnk); - STDMETHOD_(ULONG, AddRef) (); - STDMETHOD_(ULONG, Release) (); - // IMallocSpy methods - STDMETHOD_(SIZE_T, PreAlloc) (SIZE_T cbRequest); - STDMETHOD_(void *, PostAlloc) (void *pActual); - STDMETHOD_(void *, PreFree) (void *pRequest, BOOL fSpyed); - STDMETHOD_(void, PostFree) (BOOL fSpyed) { return; }; - STDMETHOD_(SIZE_T, PreRealloc) (void *pRequest, SIZE_T cbRequest, void **ppNewRequest, BOOL fSpyed); - STDMETHOD_(void *, PostRealloc) (void *pActual, BOOL fSpyed); - STDMETHOD_(void *, PreGetSize) (void *pRequest, BOOL fSpyed) { return pRequest; } - STDMETHOD_(SIZE_T, PostGetSize) (SIZE_T cbActual, BOOL fSpyed) { return cbActual; } - STDMETHOD_(void *, PreDidAlloc) (void *pRequest, BOOL fSpyed) { return pRequest; } - STDMETHOD_(BOOL, PostDidAlloc) (void *pRequest, BOOL fSpyed, BOOL fActual) { return fActual; } - STDMETHOD_(void, PreHeapMinimize) (void) { return; } - STDMETHOD_(void, PostHeapMinimize) (void) { return; } -private: - LONG m_cRef; - SIZE_T m_cbRequest; -protected: - COMTable *m_pComTable; - LONG m_disableCount; - friend COMTable; -}; - -class COMTable : public ContextHashtableBase -{ -public: - COMTable() : ContextHashtableBase(1021, "COM-Leaks") - { - m_pMallocSpy = new CMallocSpy(); // wird später durch Release freigegeben - if (m_pMallocSpy != NULL) - { - m_pMallocSpy->m_pComTable = this; - // CoInitilize(); // ??? Is this necessary ? - HRESULT hr = CoRegisterMallocSpy(m_pMallocSpy); - if FAILED(hr) - { - _tprintf(_T("\nCoRegisterMallocSpay failed with %.8x"), hr); - } - } - } - - virtual ~COMTable() - { - if (m_pMallocSpy != NULL) - m_pMallocSpy->m_pComTable = NULL; - CoRevokeMallocSpy(); - } - - virtual LONG Disable() - { - return InterlockedIncrement(&(m_pMallocSpy->m_disableCount)); - } - virtual LONG Enable() - { - return InterlockedDecrement(&(m_pMallocSpy->m_disableCount)); - } - - virtual SIZE_T HashFunction(LPVOID &key) - { - // I couldn´t find any better and faster -#ifdef _M_IX86 -#if _MSC_VER > 1100 -#pragma warning (push) -#endif -#pragma warning (disable: 4311) - DWORD llP = (DWORD) key; -#if _MSC_VER > 1100 -#pragma warning (pop) -#endif -#else - ULONGLONG llP = (ULONGLONG) key; -#endif - return (SIZE_T) llP % sAllocEntries; - } - virtual BOOL IsKeyEmpty(LPVOID &key) - { - if (key == 0) - return TRUE; - return FALSE; - } - virtual VOID SetEmptyKey(LPVOID &key) - { - key = 0; - } - virtual VOID GetKeyAsString(LPVOID &key, CHAR *szName, SIZE_T nBufferLen) - { -#if _MSC_VER < 1400 - _snprintf_s(szName, nBufferLen, "%p", key); -#else - _snprintf_s(szName, nBufferLen, nBufferLen, "%p", key); -#endif - } - - CMallocSpy *m_pMallocSpy; - friend CMallocSpy; -}; // class COMTable - - -STDMETHODIMP CMallocSpy::QueryInterface(REFIID riid, LPVOID *ppUnk) { - HRESULT hr = S_OK; - if (IsEqualIID(riid, IID_IUnknown)) { - *ppUnk = (IUnknown *) this; - } - else if (IsEqualIID(riid, IID_IMallocSpy)) { - *ppUnk = (IMalloc *) this; - } - else { - *ppUnk = NULL; - hr = E_NOINTERFACE; - } - AddRef(); - return hr; -} -STDMETHODIMP_(ULONG) CMallocSpy::AddRef(void) { - return (ULONG) InterlockedIncrement(&m_cRef); -} -STDMETHODIMP_(ULONG) CMallocSpy::Release(void) { - LONG cRef; - cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) - { - delete this; - } - return (ULONG) cRef; -} -// IMallocSpy methods -STDMETHODIMP_(SIZE_T) CMallocSpy::PreAlloc(SIZE_T cbRequest) { - m_cbRequest = cbRequest; - return cbRequest; -} -STDMETHODIMP_(void *) CMallocSpy::PostAlloc(void *pActual) { - if (m_pComTable != NULL) - { - CONTEXT c; - GET_CURRENT_CONTEXT(c, CONTEXT_FULL); - m_pComTable->Insert(pActual, c, m_cbRequest); - } - return pActual; -} -STDMETHODIMP_(void *) CMallocSpy::PreFree(void *pRequest, BOOL fSpyed) { - if (m_pComTable != NULL) - { - m_pComTable->Remove(pRequest); - } - return pRequest; -} -STDMETHODIMP_(SIZE_T) CMallocSpy::PreRealloc(void *pRequest, SIZE_T cbRequest, - void **ppNewRequest, BOOL fSpyed) { - if (m_pComTable != NULL) - { - m_pComTable->Remove(pRequest); - } - *ppNewRequest = pRequest; // Bug fixed. Thanx to Christoph Weber - return cbRequest; -} -STDMETHODIMP_(void *) CMallocSpy::PostRealloc(void *pActual, BOOL fSpyed) { - if (m_pComTable != NULL) - { - CONTEXT c; - GET_CURRENT_CONTEXT(c, CONTEXT_FULL); - m_pComTable->Insert(pActual, c, m_cbRequest); - } - return pActual; -} - - - - -// ########################################################################## -// ########################################################################## -// ########################################################################## -// Init/Deinit functions - - -static COMTable *g_pCOMTable; -HRESULT InitLeakFinder() -{ - // _X: Disabled COM monitoring: g_pCOMTable = new COMTable(); -#ifdef _DEBUG - g_pCRTTable = new CRTTable(); -#endif - return S_OK; -} - -void DeinitLeakFinder(LeakFinderOutput *output) -{ - LeakFinderOutput *pLeakFinderOutput = output; - -#ifdef _DEBUG - g_pCRTTable->Disable(); -#endif - // _X: Disabled COM monitoring: g_pCOMTable->Disable(); - - if (pLeakFinderOutput == NULL) - pLeakFinderOutput = new LeakFinderOutput(); - - // explicite load the modules: - pLeakFinderOutput->LoadModules(); - -#ifdef _DEBUG - g_pCRTTable->ShowLeaks(*pLeakFinderOutput); - if (g_pCRTTable != NULL) - delete g_pCRTTable; - g_pCRTTable = NULL; -#endif - - /* - // _X: Disabled COM monitoring: - g_pCOMTable->ShowLeaks(*pLeakFinderOutput); - if (g_pCOMTable != NULL) - delete g_pCOMTable; - g_pCOMTable = NULL; - */ - - if (output == NULL) - delete pLeakFinderOutput; -} -void DeinitLeakFinder() -{ - DeinitLeakFinder(NULL); -} + +// LeakFinder.cpp + +// Finds memory leaks rather effectively + +// _X: downloaded from http://www.codeproject.com/Articles/3134/Memory-Leak-and-Exception-Trace-CRT-and-COM-Leaks - the real link is in the comments, RC11 version + + + + + +/********************************************************************** + * + * LEAKFINDER.CPP + * + * + * + * History: + * 2010-04-15 RC10 - Updated to VC10 RTM + * Fixed Bug: Application Verifier, thanks to handsinmypocket! + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=3439751#xx3439751xx + * 2008-08-04 RC6 - Updated to VC9 RTM + * Fixed Bug: Missing "ole32.lib" LIB + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=2253980#xx2253980xx + * Fixed Bug: Compiled with "WIN32_LEAN_AND_MEAN" + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=1824718#xx1824718xx + * Fixed Bug: Compiling with "/Wall" + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=2638243#xx2638243xx + * Removed "#pragma init_seg (compiler)" from h-file + * + * 2005-12-30 RC5 - Now again VC8 RTM compatible + * - Added Xml-Output (like in the old Leakfinder) + * YOu need to define XML_LEAK_FINDER to activate it + * So you can use the LeakAnalyseTool from + * http://www.codeproject.com/tools/leakfinder.asp + * + * 2005-12-13 RC4 - Merged with the new "StackWalker"-project on + * http://www.codeproject.com/threads/StackWalker.asp + * + * 2005-08-01 RC3 - Merged with the new "StackWalker"-project on + * http://www.codeproject.com/threads/StackWalker.asp + * + * 2005-07-05 RC2 - First version with x86, IA64 and x64 support + * + * 2005-07-04 RC1 - Added "OutputOptions" + * - New define "INIT_LEAK_FINDER_VERBOSE" to + * display more info (for error reporting) + * + * 2005-07-01 Beta3 - Workaround for a bug in the new dbghelp.dll + * (version 6.5.3.7 from 2005-05-30; StakWalk64 no + * refused to produce an callstack on x86 systems + * if the context is NULL or has some registers set + * to 0 (for example Esp). This is against the + * documented behaviour of StackWalk64...) + * - First version with x64-support + * + * 2005-06-16 Beta1 First public release with the following features: + * - Completely rewritten in C++ (object oriented) + * - CRT-Leak-Report + * - COM-Leak-Report + * - Report is done via "OutputDebugString" so + * the line can directly selected in the debugger + * and is opening the corresponding file/line of + * the allocation + * - Tried to support x64 systems, bud had some + * trouble wih StackWalk64 + * See: http://blog.kalmbachnet.de/?postid=43 + * + * LICENSE (http://www.opensource.org/licenses/bsd-license.php) + * + * Copyright (c) 2005-2010, Jochen Kalmbach + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of Jochen Kalmbach nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ + +#include +#include // Needed if compiled with "WIN32_LEAN_AND_MEAN" +#include +#include +#include + +#include +#include + + +#include "LeakFinder.h" + +// Currently only tested with MS VC++ 5 to 10 +#if (_MSC_VER < 1100) || (_MSC_VER > 1600) +#error Only MS VC++ 5/6/7/7.1/8/9 supported. Check if the '_CrtMemBlockHeader' has not changed with this compiler! +#endif + + +// Controlling the callstack depth +#define MAX_CALLSTACK_LEN_BUF 0x2000 + +#define IGNORE_CRT_ALLOC + +// disable 64-bit compatibility-checks (because we explicite have here either x86 or x64!) +#pragma warning(disable:4312) // warning C4312: 'type cast' : conversion from 'DWORD' to 'LPCVOID' of greater size +#pragma warning(disable:4826) + + +// secure-CRT_functions are only available starting with VC8 +#if _MSC_VER < 1400 +#define _snprintf_s _snprintf +#define _tcscat_s _tcscat +#endif + +static std::string SimpleXMLEncode(LPCSTR szText) +{ + std::string szRet; + for (size_t i=0; i': + szRet.append(">"); + break; + case '"': + szRet.append("""); + break; + case '\'': + szRet.append("'"); + break; + default: + szRet += szText[i]; + } + } + return szRet; +} + + +LeakFinderOutput::LeakFinderOutput(int options, LPCSTR szSymPath) + : StackWalker(options, szSymPath) +{ +} +void LeakFinderOutput::OnLeakSearchStart(LPCSTR szLeakFinderName) +{ + CHAR buffer[1024]; + _snprintf_s(buffer, 1024, "######## %s ########\n", szLeakFinderName); + this->OnOutput(buffer); +} +void LeakFinderOutput::OnLeakStartEntry(LPCSTR szKeyName, SIZE_T nDataSize) +{ + CHAR buffer[1024]; + _snprintf_s(buffer, 1024, "--------------- Key: %s, %d bytes ---------\n", szKeyName, nDataSize); + this->OnOutput(buffer); +} +void LeakFinderOutput::OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry) +{ + if ( (eType != lastEntry) && (entry.offset != 0) ) + { + if ( ((this->m_options & LeakFinderShowCompleteCallstack) == 0) && ( + (strstr(entry.lineFileName, "afxmem.cpp") != NULL) || + (strstr(entry.lineFileName, "dbgheap.c") != NULL) || + (strstr(entry.lineFileName, "new.cpp") != NULL) || + (strstr(entry.lineFileName, "newop.cpp") != NULL) || + (strstr(entry.lineFileName, "leakfinder.cpp") != NULL) || + (strstr(entry.lineFileName, "stackwalker.cpp") != NULL) + ) ) + { + return; + } + } + StackWalker::OnCallstackEntry(eType, entry); +} + + +// #################################################################### +// XML-Output +LeakFinderXmlOutput::LeakFinderXmlOutput() +{ + TCHAR szXMLFileName[1024]; + + GetModuleFileName(NULL, szXMLFileName, sizeof(szXMLFileName) / sizeof(TCHAR)); + _tcscat_s(szXMLFileName, _T(".mem.xml-leaks")); +#if _MSC_VER < 1400 + m_fXmlFile = _tfopen(szXMLFileName, _T("w")); +#else + m_fXmlFile = NULL; + _tfopen_s(&m_fXmlFile, szXMLFileName, _T("w")); +#endif + if (m_fXmlFile != NULL) + { + SYSTEMTIME st; + GetLocalTime(&st); + fprintf(m_fXmlFile, "\n", + st.wMonth, st.wDay, st.wYear, + st.wHour, st.wMinute, st.wSecond); + } + else + { + MessageBox(NULL, _T("Could not open xml-logfile for leakfinder!"), _T("Warning"), MB_ICONHAND); + } +} +LeakFinderXmlOutput::LeakFinderXmlOutput(LPCTSTR szFileName) +{ +#if _MSC_VER < 1400 + m_fXmlFile = _tfopen(szFileName, _T("w")); +#else + m_fXmlFile = NULL; + _tfopen_s(&m_fXmlFile, szFileName, _T("w")); +#endif + if (m_fXmlFile == NULL) + { + MessageBox(NULL, _T("Could not open xml-logfile for leakfinder!"), _T("Warning"), MB_ICONHAND); + } +} +LeakFinderXmlOutput::~LeakFinderXmlOutput() +{ + if (m_fXmlFile != NULL) + { + // Write the ending-tags and close the file + fprintf(m_fXmlFile, "\n"); + fclose(m_fXmlFile); + } + m_fXmlFile = NULL; +} +void LeakFinderXmlOutput::OnLeakSearchStart(LPCSTR sszLeakFinderName) +{ +} +void LeakFinderXmlOutput::OnLeakStartEntry(LPCSTR szKeyName, SIZE_T nDataSize) +{ + if (m_fXmlFile != NULL) + { + fprintf(m_fXmlFile, " \n", SimpleXMLEncode(szKeyName).c_str(), nDataSize); + } +} +void LeakFinderXmlOutput::OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry) +{ + if (m_fXmlFile != NULL) + { + if (eType != lastEntry) + { + fprintf(m_fXmlFile, " \n"); + } + else + { + fprintf(m_fXmlFile, " \n"); + } + } +} + +// ########################################################################## +// ########################################################################## +// ########################################################################## +// Base class for storing contexts in a hashtable +template class ContextHashtableBase +{ +public: + ContextHashtableBase(SIZE_T sizeOfHastable, LPCSTR finderName) + { + SIZE_T s = sizeOfHastable*sizeof(AllocHashEntryType); + m_hHeap = HeapCreate(0, 10*1024 + s, 0); + if (m_hHeap == NULL) + throw; + pAllocHashTable = (AllocHashEntryType*) own_malloc(s); + sAllocEntries = sizeOfHastable; + m_finderName = own_strdup(finderName); + } + +protected: + virtual ~ContextHashtableBase() + { + if (pAllocHashTable != NULL) + own_free(pAllocHashTable); + pAllocHashTable = NULL; + + own_free(m_finderName); + m_finderName = NULL; + + if (m_hHeap != NULL) + HeapDestroy(m_hHeap); + } + + __inline LPVOID own_malloc(SIZE_T size) + { + return HeapAlloc(m_hHeap, HEAP_ZERO_MEMORY, size); + } + __inline VOID own_free(LPVOID memblock) + { + HeapFree(m_hHeap, 0, memblock); + } + __inline CHAR *own_strdup(const char *str) + { + size_t len = strlen(str)+1; + CHAR *c = (CHAR*)own_malloc(len); +#if _MSC_VER >= 1400 + strcpy_s(c, len, str); +#else + strcpy(c, str); +#endif + return c; + } + + // Disables this leak-finder + virtual LONG Disable() = 0; + // enables the leak-finder again... + virtual LONG Enable() = 0; + +private: + // Entry for each allocation + typedef struct AllocHashEntryType { + HASHTABLE_KEY key; + SIZE_T nDataSize; // Size of the allocated memory + struct AllocHashEntryType *Next; + CONTEXT c; + PVOID pStackBaseAddr; + SIZE_T nMaxStackSize; + + PVOID pCallstackOffset; + SIZE_T nCallstackLen; + char pcCallstackAddr[MAX_CALLSTACK_LEN_BUF]; // min of both values... + } AllocHashEntryType; + +protected: + virtual SIZE_T HashFunction(HASHTABLE_KEY &key) = 0; + virtual BOOL IsKeyEmpty(HASHTABLE_KEY &key) = 0; + virtual VOID SetEmptyKey(HASHTABLE_KEY &key) = 0; + virtual VOID GetKeyAsString(HASHTABLE_KEY &key, CHAR *szName, SIZE_T nBufferLen) = 0; + //virtual SIZE_T GetNativeBytes(HASHTABLE_KEY &key, CHAR *szName, SIZE_T nBufferLen) { return 0; } + +public: + VOID Insert(HASHTABLE_KEY &key, CONTEXT &context, SIZE_T nDataSize) + { + SIZE_T HashIdx; + AllocHashEntryType *pHashEntry; + + // generate hash-value + HashIdx = HashFunction(key); + + pHashEntry = &pAllocHashTable[HashIdx]; + if (IsKeyEmpty(pHashEntry->key) != FALSE) { + // Entry is empty... + } + else { + // Entry is not empy! make a list of entries for this hash value... + while(pHashEntry->Next != NULL) { + pHashEntry = pHashEntry->Next; + } + + pHashEntry->Next = (AllocHashEntryType*) own_malloc(sizeof(AllocHashEntryType)); + pHashEntry = pHashEntry->Next; + } + pHashEntry->key = key; + pHashEntry->nDataSize = nDataSize; + pHashEntry->Next = NULL; +#ifdef _M_IX86 + pHashEntry->pCallstackOffset = (LPVOID) min(context.Ebp, context.Esp); +#elif _M_X64 + pHashEntry->pCallstackOffset = (LPVOID) min(context.Rdi, context.Rsp); +#elif _M_IA64 + pHashEntry->pCallstackOffset = (LPVOID) min(context.IntSp, context.RsBSP); +#else +#error "Platform not supported!" +#endif + pHashEntry->c = context; + + // Query the max. stack-area: + MEMORY_BASIC_INFORMATION MemBuffer; + if(VirtualQuery((LPCVOID) pHashEntry->pCallstackOffset, &MemBuffer, sizeof(MemBuffer)) > 0) + { + pHashEntry->pStackBaseAddr = MemBuffer.BaseAddress; + pHashEntry->nMaxStackSize = MemBuffer.RegionSize; + } + else + { + pHashEntry->pStackBaseAddr = 0; + pHashEntry->nMaxStackSize = 0; + } + + SIZE_T bytesToRead = MAX_CALLSTACK_LEN_BUF; + if (pHashEntry->nMaxStackSize > 0) + { + SIZE_T len = ((SIZE_T) pHashEntry->pStackBaseAddr + pHashEntry->nMaxStackSize) - (SIZE_T)pHashEntry->pCallstackOffset; + bytesToRead = min(len, MAX_CALLSTACK_LEN_BUF); + } + // Now read the callstack: + if (ReadProcessMemory(GetCurrentProcess(), (LPCVOID) pHashEntry->pCallstackOffset, &(pHashEntry->pcCallstackAddr), bytesToRead, &(pHashEntry->nCallstackLen)) == 0) + { + // Could not read memory... + pHashEntry->nCallstackLen = 0; + pHashEntry->pCallstackOffset = 0; + } // read callstack + } // Insert + + BOOL Remove(HASHTABLE_KEY &key) + { + SIZE_T HashIdx; + AllocHashEntryType *pHashEntry, *pHashEntryLast; + + // get the Hash-Value + HashIdx = HashFunction(key); + + pHashEntryLast = NULL; + pHashEntry = &pAllocHashTable[HashIdx]; + while(pHashEntry != NULL) { + if (pHashEntry->key == key) { + // release my memory + if (pHashEntryLast == NULL) { + // It is an entry in the table, so do not release this memory + if (pHashEntry->Next == NULL) { + // It was the last entry, so empty the table entry + SetEmptyKey(pAllocHashTable[HashIdx].key); + //memset(&pAllocHashTable[HashIdx], 0, sizeof(pAllocHashTable[HashIdx])); + } + else { + // There are some more entries, so shorten the list + AllocHashEntryType *pTmp = pHashEntry->Next; + *pHashEntry = *(pHashEntry->Next); + own_free(pTmp); + } + return TRUE; + } + else { + // now, I am in an dynamic allocated entry (it was a collision) + pHashEntryLast->Next = pHashEntry->Next; + own_free(pHashEntry); + return TRUE; + } + } + pHashEntryLast = pHashEntry; + pHashEntry = pHashEntry->Next; + } + + // if we are here, we could not find the RequestID + return FALSE; + } + + AllocHashEntryType *Find(HASHTABLE_KEY &key) + { + SIZE_T HashIdx; + AllocHashEntryType *pHashEntry; + + // get the Hash-Value + HashIdx = HashFunction(key); + + pHashEntry = &pAllocHashTable[HashIdx]; + while(pHashEntry != NULL) { + if (pHashEntry->key == key) { + return pHashEntry; + } + pHashEntry = pHashEntry->Next; + } + + // entry was not found! + return NULL; + } + + // For the followong static-var See comment in "ShowCallstack"... + static BOOL CALLBACK ReadProcessMemoryFromHashEntry64( + HANDLE hProcess, // hProcess must be a pointer to an hash-entry! + DWORD64 lpBaseAddress, + PVOID lpBuffer, + DWORD nSize, + LPDWORD lpNumberOfBytesRead, + LPVOID pUserData // optional data, which was passed in "ShowCallstack" + ) + { + *lpNumberOfBytesRead = 0; + AllocHashEntryType *pHashEntry = (AllocHashEntryType*) pUserData; + if (pHashEntry == NULL) + { + return FALSE; + } + + if ( ( (DWORD64)lpBaseAddress >= (DWORD64)pHashEntry->pCallstackOffset) && ((DWORD64)lpBaseAddress <= ((DWORD64)pHashEntry->pCallstackOffset+pHashEntry->nCallstackLen)) ) { + // Memory is located in saved Callstack: + // Calculate the offset + DWORD dwOffset = (DWORD) ((DWORD64)lpBaseAddress - (DWORD64)pHashEntry->pCallstackOffset); + DWORD dwSize = __min(nSize, MAX_CALLSTACK_LEN_BUF-dwOffset); + memcpy(lpBuffer, &(pHashEntry->pcCallstackAddr[dwOffset]), dwSize); + *lpNumberOfBytesRead = dwSize; + if (dwSize != nSize) + { + return FALSE; + } + *lpNumberOfBytesRead = nSize; + return TRUE; + } + + if (*lpNumberOfBytesRead == 0) // Memory could not be found + { + if ( ( (DWORD64)lpBaseAddress < (DWORD64)pHashEntry->pStackBaseAddr) || ((DWORD64)lpBaseAddress > ((DWORD64)pHashEntry->pStackBaseAddr+pHashEntry->nMaxStackSize)) ) + { + // Stackwalking is done by reading the "real memory" (normally this happens when the StackWalk64 tries to read some code) + SIZE_T st = 0; + BOOL bRet = ReadProcessMemory(hProcess, (LPCVOID) lpBaseAddress, lpBuffer, nSize, &st); + *lpNumberOfBytesRead = (DWORD) st; + return bRet; + } + } + + return TRUE; + } + + VOID ShowLeaks(LeakFinderOutput &leakFinderOutput) + { + SIZE_T ulTemp; + AllocHashEntryType *pHashEntry; + ULONG ulCount = 0; + SIZE_T ulLeaksByte = 0; + + leakFinderOutput.OnLeakSearchStart(this->m_finderName); + + // Move throu every entry + CHAR keyName[1024]; + for(ulTemp = 0; ulTemp < this->sAllocEntries; ulTemp++) { + pHashEntry = &pAllocHashTable[ulTemp]; + if (IsKeyEmpty(pHashEntry->key) == FALSE) { + while(pHashEntry != NULL) { + ulCount++; + CONTEXT c; + memcpy(&c, &(pHashEntry->c), sizeof(CONTEXT)); + + this->GetKeyAsString(pHashEntry->key, keyName, 1024); + + leakFinderOutput.OnLeakStartEntry(keyName, pHashEntry->nDataSize); + leakFinderOutput.ShowCallstack(GetCurrentThread(), &c, ReadProcessMemoryFromHashEntry64, pHashEntry); + + // Count the number of leaky bytes + ulLeaksByte += pHashEntry->nDataSize; + + pHashEntry = pHashEntry->Next; + } // while + } + } + } + + AllocHashEntryType *pAllocHashTable; + SIZE_T sAllocEntries; + HANDLE m_hHeap; + LPSTR m_finderName; + bool m_bSupressUselessLines; +}; // template class ContextHashtableBase + + +// ########################################################################## +// ########################################################################## +// ########################################################################## +// Specialization for CRT-Leaks: +// VC5 has excluded all types in release-builds +#ifdef _DEBUG + +// The follwoing is copied from dbgint.h: +// +/* +* For diagnostic purpose, blocks are allocated with extra information and +* stored in a doubly-linked list. This makes all blocks registered with +* how big they are, when they were allocated, and what they are used for. +*/ + +// forward declaration: +#ifndef _M_CEE_PURE +#define MyAllocHookCallingConvention __cdecl +#endif +#if _MSC_VER >= 1400 +#ifdef _M_CEE +#define MyAllocHookCallingConvention __clrcall +#endif +#endif + +static int MyAllocHookCallingConvention MyAllocHook(int nAllocType, void *pvData, + size_t nSize, int nBlockUse, long lRequest, +#if _MSC_VER <= 1100 // Special case for VC 5 and before + const char * szFileName, +#else + const unsigned char * szFileName, +#endif + int nLine); + +static _CRT_ALLOC_HOOK s_pfnOldCrtAllocHook = NULL; +static LONG s_CrtDisableCount = 0; +static LONG s_lMallocCalled = 0; + + +class CRTTable : public ContextHashtableBase +{ +public: + CRTTable() : ContextHashtableBase(1021, "CRT-Leaks") + { + // save the previous alloc hook + s_pfnOldCrtAllocHook = _CrtSetAllocHook(MyAllocHook); + } + + virtual ~CRTTable() + { + _CrtSetAllocHook(s_pfnOldCrtAllocHook); + } + + virtual LONG Disable() + { + return InterlockedIncrement(&s_CrtDisableCount); + } + virtual LONG Enable() + { + return InterlockedDecrement(&s_CrtDisableCount); + } + + virtual SIZE_T HashFunction(LONG &key) + { + // I couldn´t find any better and faster + return key % sAllocEntries; + } + virtual BOOL IsKeyEmpty(LONG &key) + { + if (key == 0) + return TRUE; + return FALSE; + } + virtual VOID SetEmptyKey(LONG &key) + { + key = 0; + } + virtual VOID GetKeyAsString(LONG &key, CHAR *szName, SIZE_T nBufferLen) + { +#if _MSC_VER < 1400 + _snprintf_s(szName, nBufferLen, "%d", key); +#else + _snprintf_s(szName, nBufferLen, nBufferLen, "%d", key); +#endif + } + +protected: + CHAR *m_pBuffer; + SIZE_T m_maxBufferLen; + SIZE_T m_bufferLen; +}; // class CRTTable + + +#define nNoMansLandSize 4 + +typedef struct _CrtMemBlockHeader +{ + struct _CrtMemBlockHeader * pBlockHeaderNext; + struct _CrtMemBlockHeader * pBlockHeaderPrev; + char * szFileName; + int nLine; +#ifdef _WIN64 + /* These items are reversed on Win64 to eliminate gaps in the struct + * and ensure that sizeof(struct)%16 == 0, so 16-byte alignment is + * maintained in the debug heap. + */ + int nBlockUse; + size_t nDataSize; +#else /* _WIN64 */ + size_t nDataSize; + int nBlockUse; +#endif /* _WIN64 */ + long lRequest; + unsigned char gap[nNoMansLandSize]; + /* followed by: + * unsigned char data[nDataSize]; + * unsigned char anotherGap[nNoMansLandSize]; + */ +} _CrtMemBlockHeader; +#define pbData(pblock) ((unsigned char *)((_CrtMemBlockHeader *)pblock + 1)) +#define pHdr(pbData) (((_CrtMemBlockHeader *)pbData)-1) +// + +static CRTTable *g_pCRTTable = NULL; + + +// MyAllocHook is Single-Threaded, that means the the calls are serialized in the calling function! +static int MyAllocHook(int nAllocType, void *pvData, + size_t nSize, int nBlockUse, long lRequest, +#if _MSC_VER <= 1100 // Special case for VC 5 + const char * szFileName, +#else + const unsigned char * szFileName, +#endif + int nLine) +{ + //static TCHAR *operation[] = { _T(""), _T("ALLOCATIONG"), _T("RE-ALLOCATING"), _T("FREEING") }; + //static TCHAR *blockType[] = { _T("Free"), _T("Normal"), _T("CRT"), _T("Ignore"), _T("Client") }; + +#ifdef IGNORE_CRT_ALLOC + if (_BLOCK_TYPE(nBlockUse) == _CRT_BLOCK) // Ignore internal C runtime library allocations + return TRUE; +#endif + extern int _crtDbgFlag; + if ( ((_CRTDBG_ALLOC_MEM_DF & _crtDbgFlag) == 0) && ( (nAllocType == _HOOK_ALLOC) || (nAllocType == _HOOK_REALLOC) ) ) + { + // Someone has disabled that the runtime should log this allocation + // so we do not log this allocation + if (s_pfnOldCrtAllocHook != NULL) + s_pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); + return TRUE; + } + + // Handle the Disable/Enable setting + if (InterlockedExchangeAdd(&s_CrtDisableCount, 0) != 0) + return TRUE; + + // Prevent from reentrat calls + if (InterlockedIncrement(&s_lMallocCalled) > 1) { // I was already called + InterlockedDecrement(&s_lMallocCalled); + // call the previous alloc hook + if (s_pfnOldCrtAllocHook != NULL) + s_pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); + return TRUE; + } + + _ASSERT( (nAllocType == _HOOK_ALLOC) || (nAllocType == _HOOK_REALLOC) || (nAllocType == _HOOK_FREE) ); + _ASSERT( ( _BLOCK_TYPE(nBlockUse) >= 0 ) && ( _BLOCK_TYPE(nBlockUse) < 5 ) ); + + if (nAllocType == _HOOK_FREE) { // freeing + // Try to get the header information + if (_CrtIsValidHeapPointer(pvData)) { // it is a valid Heap-Pointer + // get the ID + _CrtMemBlockHeader *pHead; + // get a pointer to memory block header + pHead = pHdr(pvData); + nSize = pHead->nDataSize; + lRequest = pHead->lRequest; // This is the ID! + + if (pHead->nBlockUse == _IGNORE_BLOCK) + { + InterlockedDecrement(&s_lMallocCalled); + if (s_pfnOldCrtAllocHook != NULL) + s_pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); + return TRUE; + } + } + if (lRequest != 0) { // RequestID was found + g_pCRTTable->Remove(lRequest); + } + } // freeing + + if (nAllocType == _HOOK_REALLOC) { // re-allocating + // Try to get the header information + if (_CrtIsValidHeapPointer(pvData)) { // it is a valid Heap-Pointer + BOOL bRet; + LONG lReallocRequest; + // get the ID + _CrtMemBlockHeader *pHead; + // get a pointer to memory block header + pHead = pHdr(pvData); + // Try to find the RequestID in the Hash-Table, mark it that it was freed + lReallocRequest = pHead->lRequest; + bRet = g_pCRTTable->Remove(lReallocRequest); + } // ValidHeapPointer + } // re-allocating + + //if ( (g_ulShowStackAtAlloc < 3) && (nAllocType == _HOOK_FREE) ) { + if (nAllocType == _HOOK_FREE) { + InterlockedDecrement(&s_lMallocCalled); + // call the previous alloc hook + if (s_pfnOldCrtAllocHook != NULL) + s_pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); + return TRUE; + } + + CONTEXT c; + GET_CURRENT_CONTEXT(c, CONTEXT_FULL); + + // Only insert in the Hash-Table if it is not a "freeing" + if (nAllocType != _HOOK_FREE) { + if(lRequest != 0) // Always a valid RequestID should be provided (see comments in the header) + g_pCRTTable->Insert(lRequest, c, nSize); + } + + InterlockedDecrement(&s_lMallocCalled); + // call the previous alloc hook + if (s_pfnOldCrtAllocHook != NULL) + s_pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); + return TRUE; // allow the memory operation to proceed +} // MyAllocHook + +#endif // _DEBUG + + +// ########################################################################## +// ########################################################################## +// ########################################################################## +// Specialization for COM-Leaks: + +// forwards: +class COMTable; +class CMallocSpy : public IMallocSpy +{ +public: + CMallocSpy() { m_cbRequest = 0; m_cRef = 0; m_disableCount = 0; } + virtual ~CMallocSpy() {} + // IUnknown methods + STDMETHOD(QueryInterface) (REFIID riid, LPVOID *ppUnk); + STDMETHOD_(ULONG, AddRef) (); + STDMETHOD_(ULONG, Release) (); + // IMallocSpy methods + STDMETHOD_(SIZE_T, PreAlloc) (SIZE_T cbRequest); + STDMETHOD_(void *, PostAlloc) (void *pActual); + STDMETHOD_(void *, PreFree) (void *pRequest, BOOL fSpyed); + STDMETHOD_(void, PostFree) (BOOL fSpyed) { return; }; + STDMETHOD_(SIZE_T, PreRealloc) (void *pRequest, SIZE_T cbRequest, void **ppNewRequest, BOOL fSpyed); + STDMETHOD_(void *, PostRealloc) (void *pActual, BOOL fSpyed); + STDMETHOD_(void *, PreGetSize) (void *pRequest, BOOL fSpyed) { return pRequest; } + STDMETHOD_(SIZE_T, PostGetSize) (SIZE_T cbActual, BOOL fSpyed) { return cbActual; } + STDMETHOD_(void *, PreDidAlloc) (void *pRequest, BOOL fSpyed) { return pRequest; } + STDMETHOD_(BOOL, PostDidAlloc) (void *pRequest, BOOL fSpyed, BOOL fActual) { return fActual; } + STDMETHOD_(void, PreHeapMinimize) (void) { return; } + STDMETHOD_(void, PostHeapMinimize) (void) { return; } +private: + LONG m_cRef; + SIZE_T m_cbRequest; +protected: + COMTable *m_pComTable; + LONG m_disableCount; + friend COMTable; +}; + +class COMTable : public ContextHashtableBase +{ +public: + COMTable() : ContextHashtableBase(1021, "COM-Leaks") + { + m_pMallocSpy = new CMallocSpy(); // wird später durch Release freigegeben + if (m_pMallocSpy != NULL) + { + m_pMallocSpy->m_pComTable = this; + // CoInitilize(); // ??? Is this necessary ? + HRESULT hr = CoRegisterMallocSpy(m_pMallocSpy); + if FAILED(hr) + { + _tprintf(_T("\nCoRegisterMallocSpay failed with %.8x"), hr); + } + } + } + + virtual ~COMTable() + { + if (m_pMallocSpy != NULL) + m_pMallocSpy->m_pComTable = NULL; + CoRevokeMallocSpy(); + } + + virtual LONG Disable() + { + return InterlockedIncrement(&(m_pMallocSpy->m_disableCount)); + } + virtual LONG Enable() + { + return InterlockedDecrement(&(m_pMallocSpy->m_disableCount)); + } + + virtual SIZE_T HashFunction(LPVOID &key) + { + // I couldn´t find any better and faster +#ifdef _M_IX86 +#if _MSC_VER > 1100 +#pragma warning (push) +#endif +#pragma warning (disable: 4311) + DWORD llP = (DWORD) key; +#if _MSC_VER > 1100 +#pragma warning (pop) +#endif +#else + ULONGLONG llP = (ULONGLONG) key; +#endif + return (SIZE_T) llP % sAllocEntries; + } + virtual BOOL IsKeyEmpty(LPVOID &key) + { + if (key == 0) + return TRUE; + return FALSE; + } + virtual VOID SetEmptyKey(LPVOID &key) + { + key = 0; + } + virtual VOID GetKeyAsString(LPVOID &key, CHAR *szName, SIZE_T nBufferLen) + { +#if _MSC_VER < 1400 + _snprintf_s(szName, nBufferLen, "%p", key); +#else + _snprintf_s(szName, nBufferLen, nBufferLen, "%p", key); +#endif + } + + CMallocSpy *m_pMallocSpy; + friend CMallocSpy; +}; // class COMTable + + +STDMETHODIMP CMallocSpy::QueryInterface(REFIID riid, LPVOID *ppUnk) { + HRESULT hr = S_OK; + if (IsEqualIID(riid, IID_IUnknown)) { + *ppUnk = (IUnknown *) this; + } + else if (IsEqualIID(riid, IID_IMallocSpy)) { + *ppUnk = (IMalloc *) this; + } + else { + *ppUnk = NULL; + hr = E_NOINTERFACE; + } + AddRef(); + return hr; +} +STDMETHODIMP_(ULONG) CMallocSpy::AddRef(void) { + return (ULONG) InterlockedIncrement(&m_cRef); +} +STDMETHODIMP_(ULONG) CMallocSpy::Release(void) { + LONG cRef; + cRef = InterlockedDecrement(&m_cRef); + if (cRef == 0) + { + delete this; + } + return (ULONG) cRef; +} +// IMallocSpy methods +STDMETHODIMP_(SIZE_T) CMallocSpy::PreAlloc(SIZE_T cbRequest) { + m_cbRequest = cbRequest; + return cbRequest; +} +STDMETHODIMP_(void *) CMallocSpy::PostAlloc(void *pActual) { + if (m_pComTable != NULL) + { + CONTEXT c; + GET_CURRENT_CONTEXT(c, CONTEXT_FULL); + m_pComTable->Insert(pActual, c, m_cbRequest); + } + return pActual; +} +STDMETHODIMP_(void *) CMallocSpy::PreFree(void *pRequest, BOOL fSpyed) { + if (m_pComTable != NULL) + { + m_pComTable->Remove(pRequest); + } + return pRequest; +} +STDMETHODIMP_(SIZE_T) CMallocSpy::PreRealloc(void *pRequest, SIZE_T cbRequest, + void **ppNewRequest, BOOL fSpyed) { + if (m_pComTable != NULL) + { + m_pComTable->Remove(pRequest); + } + *ppNewRequest = pRequest; // Bug fixed. Thanx to Christoph Weber + return cbRequest; +} +STDMETHODIMP_(void *) CMallocSpy::PostRealloc(void *pActual, BOOL fSpyed) { + if (m_pComTable != NULL) + { + CONTEXT c; + GET_CURRENT_CONTEXT(c, CONTEXT_FULL); + m_pComTable->Insert(pActual, c, m_cbRequest); + } + return pActual; +} + + + + +// ########################################################################## +// ########################################################################## +// ########################################################################## +// Init/Deinit functions + + +static COMTable *g_pCOMTable; +HRESULT InitLeakFinder() +{ + // _X: Disabled COM monitoring: g_pCOMTable = new COMTable(); +#ifdef _DEBUG + g_pCRTTable = new CRTTable(); +#endif + return S_OK; +} + +void DeinitLeakFinder(LeakFinderOutput *output) +{ + LeakFinderOutput *pLeakFinderOutput = output; + +#ifdef _DEBUG + g_pCRTTable->Disable(); +#endif + // _X: Disabled COM monitoring: g_pCOMTable->Disable(); + + if (pLeakFinderOutput == NULL) + pLeakFinderOutput = new LeakFinderOutput(); + + // explicite load the modules: + pLeakFinderOutput->LoadModules(); + +#ifdef _DEBUG + g_pCRTTable->ShowLeaks(*pLeakFinderOutput); + if (g_pCRTTable != NULL) + delete g_pCRTTable; + g_pCRTTable = NULL; +#endif + + /* + // _X: Disabled COM monitoring: + g_pCOMTable->ShowLeaks(*pLeakFinderOutput); + if (g_pCOMTable != NULL) + delete g_pCOMTable; + g_pCOMTable = NULL; + */ + + if (output == NULL) + delete pLeakFinderOutput; +} +void DeinitLeakFinder() +{ + DeinitLeakFinder(NULL); +} diff --git a/source/LeakFinder.h b/source/LeakFinder.h index 77f221bca..6743adda0 100644 --- a/source/LeakFinder.h +++ b/source/LeakFinder.h @@ -1,145 +1,145 @@ -/********************************************************************** - * - * LEAKFINDER.H - * - * - * - * LICENSE (http://www.opensource.org/licenses/bsd-license.php) - * - * Copyright (c) 2005-2010, Jochen Kalmbach - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * Neither the name of Jochen Kalmbach nor the names of its contributors may be - * used to endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - **********************************************************************/ - -// #pragma once is supported starting with _MCS_VER 1000, -// so we need not to check the version (because we only support _MSC_VER >= 1100)! -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -HRESULT InitLeakFinder(); -void DeinitLeakFinder(); - -#ifdef __cplusplus -} -#endif - - -// The following is only available if the file is CPP -#ifdef __cplusplus - -#include "StackWalker.h" - -// Interface for output... -class LeakFinderOutput : public StackWalker -{ -public: - typedef enum LeakFinderOptions - { - // No addition info will be retrived - // (only the address is available) - LeakFinderNone = 0, - LeakFinderShowCompleteCallstack = 0x1000 - } LeakFinderOptions; - - LeakFinderOutput(int options = OptionsAll, LPCSTR szSymPath = NULL); - virtual void OnLeakSearchStart(LPCSTR sszLeakFinderName); - virtual void OnLeakStartEntry(LPCSTR szKeyName, SIZE_T nDataSize); -protected: - virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry); - virtual void OnOutput(LPCSTR szText) - { - printf(szText); - StackWalker::OnOutput(szText); - } - virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr) - { - if (strcmp(szFuncName, "SymGetLineFromAddr64") == 0) return; - StackWalker::OnDbgHelpErr(szFuncName, gle, addr); - } -}; - -class LeakFinderXmlOutput : public LeakFinderOutput -{ -public: - LeakFinderXmlOutput(); - virtual ~LeakFinderXmlOutput(); - LeakFinderXmlOutput(LPCTSTR szFileName); - virtual void OnLeakSearchStart(LPCSTR sszLeakFinderName); - virtual void OnLeakStartEntry(LPCSTR szKeyName, SIZE_T nDataSize); -protected: - virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry); - virtual void OnOutput(LPCSTR szText) { } - virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr) { } - - FILE *m_fXmlFile; -}; - -// C++ interface: -void DeinitLeakFinder(LeakFinderOutput *output); - -class ZZZ_LeakFinder -{ -public: - ZZZ_LeakFinder() - { - m_pXml = NULL; -#ifdef XML_LEAK_FINDER - m_pXml = new LeakFinderXmlOutput(); -#endif - InitLeakFinder(); - } - ~ZZZ_LeakFinder() - { - DeinitLeakFinder(m_pXml); - if (m_pXml != NULL) delete m_pXml; - } -protected: - LeakFinderXmlOutput *m_pXml; -}; - -#if defined(INIT_LEAK_FINDER) -#if _MSC_VER >= 1200 -#pragma warning(push) -#endif -#pragma warning (disable:4074) - -// WARNING: If you enable this option, the code might run without the CRT being initialized or after the CRT was deinitialized!!! -// Currently the code is not designed to bypass the CRT... -//#pragma init_seg (compiler) -ZZZ_LeakFinder zzz_LeakFinder; - -#if _MSC_VER >= 1200 -#pragma warning(pop) -#else -#pragma warning(default:4074) -#endif -#endif - -#endif // __cplusplus +/********************************************************************** + * + * LEAKFINDER.H + * + * + * + * LICENSE (http://www.opensource.org/licenses/bsd-license.php) + * + * Copyright (c) 2005-2010, Jochen Kalmbach + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of Jochen Kalmbach nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ + +// #pragma once is supported starting with _MCS_VER 1000, +// so we need not to check the version (because we only support _MSC_VER >= 1100)! +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +HRESULT InitLeakFinder(); +void DeinitLeakFinder(); + +#ifdef __cplusplus +} +#endif + + +// The following is only available if the file is CPP +#ifdef __cplusplus + +#include "StackWalker.h" + +// Interface for output... +class LeakFinderOutput : public StackWalker +{ +public: + typedef enum LeakFinderOptions + { + // No addition info will be retrived + // (only the address is available) + LeakFinderNone = 0, + LeakFinderShowCompleteCallstack = 0x1000 + } LeakFinderOptions; + + LeakFinderOutput(int options = OptionsAll, LPCSTR szSymPath = NULL); + virtual void OnLeakSearchStart(LPCSTR sszLeakFinderName); + virtual void OnLeakStartEntry(LPCSTR szKeyName, SIZE_T nDataSize); +protected: + virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry); + virtual void OnOutput(LPCSTR szText) + { + printf(szText); + StackWalker::OnOutput(szText); + } + virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr) + { + if (strcmp(szFuncName, "SymGetLineFromAddr64") == 0) return; + StackWalker::OnDbgHelpErr(szFuncName, gle, addr); + } +}; + +class LeakFinderXmlOutput : public LeakFinderOutput +{ +public: + LeakFinderXmlOutput(); + virtual ~LeakFinderXmlOutput(); + LeakFinderXmlOutput(LPCTSTR szFileName); + virtual void OnLeakSearchStart(LPCSTR sszLeakFinderName); + virtual void OnLeakStartEntry(LPCSTR szKeyName, SIZE_T nDataSize); +protected: + virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry); + virtual void OnOutput(LPCSTR szText) { } + virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr) { } + + FILE *m_fXmlFile; +}; + +// C++ interface: +void DeinitLeakFinder(LeakFinderOutput *output); + +class ZZZ_LeakFinder +{ +public: + ZZZ_LeakFinder() + { + m_pXml = NULL; +#ifdef XML_LEAK_FINDER + m_pXml = new LeakFinderXmlOutput(); +#endif + InitLeakFinder(); + } + ~ZZZ_LeakFinder() + { + DeinitLeakFinder(m_pXml); + if (m_pXml != NULL) delete m_pXml; + } +protected: + LeakFinderXmlOutput *m_pXml; +}; + +#if defined(INIT_LEAK_FINDER) +#if _MSC_VER >= 1200 +#pragma warning(push) +#endif +#pragma warning (disable:4074) + +// WARNING: If you enable this option, the code might run without the CRT being initialized or after the CRT was deinitialized!!! +// Currently the code is not designed to bypass the CRT... +//#pragma init_seg (compiler) +ZZZ_LeakFinder zzz_LeakFinder; + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#else +#pragma warning(default:4074) +#endif +#endif + +#endif // __cplusplus diff --git a/source/LightingThread.cpp b/source/LightingThread.cpp index c2f876e32..67f3b4116 100644 --- a/source/LightingThread.cpp +++ b/source/LightingThread.cpp @@ -1,531 +1,531 @@ - -// LightingThread.cpp - -// Implements the cLightingThread class representing the thread that processes requests for lighting - -#include "Globals.h" -#include "LightingThread.h" -#include "cChunkMap.h" -#include "cWorld.h" - - - - - -/// If more than this many chunks are in the queue, a warning is printed to the log -#define WARN_ON_QUEUE_SIZE 800 - - - - - -/// Chunk data callback that takes the chunk data and puts them into cLightingThread's m_BlockTypes[] / m_HeightMap[]: -class cReader : - public cChunkDataCallback -{ - virtual void BlockTypes(const BLOCKTYPE * a_Type) override - { - // ROW is a block of 16 Blocks, one whole row is copied at a time (hopefully the compiler will optimize that) - // C++ doesn't permit copying arrays, but arrays as a part of a struct is ok :) - typedef struct {BLOCKTYPE m_Row[16]; } ROW; - ROW * InputRows = (ROW *)a_Type; - ROW * OutputRows = (ROW *)m_BlockTypes; - int InputIdx = 0; - int OutputIdx = m_ReadingChunkX + m_ReadingChunkZ * cChunkDef::Width * 3; - for (int y = 0; y < cChunkDef::Height; y++) - { - for (int z = 0; z < cChunkDef::Width; z++) - { - OutputRows[OutputIdx] = InputRows[InputIdx++]; - OutputIdx += 3; - } // for z - // Skip into the next y-level in the 3x3 chunk blob; each level has cChunkDef::Width * 9 rows - // We've already walked cChunkDef::Width * 3 in the "for z" cycle, that makes cChunkDef::Width * 6 rows left to skip - OutputIdx += cChunkDef::Width * 6; - } // for y - } // BlockTypes() - - - virtual void HeightMap(const cChunkDef::HeightMap * a_Heightmap) override - { - typedef struct {HEIGHTTYPE m_Row[16]; } ROW; - ROW * InputRows = (ROW *)a_Heightmap; - ROW * OutputRows = (ROW *)m_HeightMap; - int InputIdx = 0; - int OutputIdx = m_ReadingChunkX + m_ReadingChunkZ * cChunkDef::Width * 3; - for (int z = 0; z < cChunkDef::Width; z++) - { - OutputRows[OutputIdx] = InputRows[InputIdx++]; - OutputIdx += 3; - } // for z - } - -public: - int m_ReadingChunkX; // 0, 1 or 2; x-offset of the chunk we're reading from the BlockTypes start - int m_ReadingChunkZ; // 0, 1 or 2; z-offset of the chunk we're reading from the BlockTypes start - BLOCKTYPE * m_BlockTypes; // 3x3 chunks of block types, organized as a single XZY blob of data (instead of 3x3 XZY blobs) - HEIGHTTYPE * m_HeightMap; // 3x3 chunks of height map, organized as a single XZY blob of data (instead of 3x3 XZY blobs) -} ; - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cLightingThread: - -cLightingThread::cLightingThread(void) : - super("cLightingThread"), - m_World(NULL) -{ -} - - - - - -cLightingThread::~cLightingThread() -{ - Stop(); -} - - - - - -bool cLightingThread::Start(cWorld * a_World) -{ - ASSERT(m_World == NULL); // Not started yet - m_World = a_World; - - return super::Start(); -} - - - - - -void cLightingThread::Stop(void) -{ - { - cCSLock Lock(m_CS); - m_Queue.clear(); - } - m_ShouldTerminate = true; - m_evtItemAdded.Set(); - - Wait(); -} - - - - - -void cLightingThread::QueueChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallbackAfter) -{ - ASSERT(m_World != NULL); // Did you call Start() properly? - - cChunkStay * ChunkStay = new cChunkStay(m_World); - ChunkStay->Add(a_ChunkX + 1, ZERO_CHUNK_Y, a_ChunkZ + 1); - ChunkStay->Add(a_ChunkX + 1, ZERO_CHUNK_Y, a_ChunkZ); - ChunkStay->Add(a_ChunkX + 1, ZERO_CHUNK_Y, a_ChunkZ - 1); - ChunkStay->Add(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ + 1); - ChunkStay->Add(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); - ChunkStay->Add(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ - 1); - ChunkStay->Add(a_ChunkX - 1, ZERO_CHUNK_Y, a_ChunkZ + 1); - ChunkStay->Add(a_ChunkX - 1, ZERO_CHUNK_Y, a_ChunkZ); - ChunkStay->Add(a_ChunkX - 1, ZERO_CHUNK_Y, a_ChunkZ - 1); - ChunkStay->Enable(); - ChunkStay->Load(); - cCSLock Lock(m_CS); - m_Queue.push_back(sItem(a_ChunkX, a_ChunkZ, ChunkStay, a_CallbackAfter)); - if (m_Queue.size() > WARN_ON_QUEUE_SIZE) - { - LOGINFO("Lighting thread overloaded, %d items in queue", m_Queue.size()); - } - m_evtItemAdded.Set(); -} - - - - - -void cLightingThread::WaitForQueueEmpty(void) -{ - cCSLock Lock(m_CS); - while (!m_ShouldTerminate && (!m_Queue.empty() || !m_PostponedQueue.empty())) - { - cCSUnlock Unlock(Lock); - m_evtQueueEmpty.Wait(); - } -} - - - - - -size_t cLightingThread::GetQueueLength(void) -{ - cCSLock Lock(m_CS); - return m_Queue.size() + m_PostponedQueue.size(); -} - - - - - -void cLightingThread::ChunkReady(int a_ChunkX, int a_ChunkZ) -{ - // Check all the items in the m_PostponedQueue, if the chunk is their neighbor, move the item to m_Queue - - bool NewlyAdded = false; - { - cCSLock Lock(m_CS); - for (sItems::iterator itr = m_PostponedQueue.begin(); itr != m_PostponedQueue.end(); ) - { - if ( - (itr->x - a_ChunkX >= -1) && (itr->x - a_ChunkX <= 1) && - (itr->x - a_ChunkX >= -1) && (itr->x - a_ChunkX <= 1) - ) - { - // It is a neighbor - m_Queue.push_back(*itr); - itr = m_PostponedQueue.erase(itr); - NewlyAdded = true; - } - else - { - ++itr; - } - } // for itr - m_PostponedQueue[] - } // Lock(m_CS) - - if (NewlyAdded) - { - m_evtItemAdded.Set(); // Notify the thread it has some work to do - } -} - - - - - -void cLightingThread::Execute(void) -{ - while (true) - { - { - cCSLock Lock(m_CS); - if (m_Queue.size() == 0) - { - cCSUnlock Unlock(Lock); - m_evtItemAdded.Wait(); - } - } - - if (m_ShouldTerminate) - { - return; - } - - // Process one items from the queue: - sItem Item; - { - cCSLock Lock(m_CS); - if (m_Queue.empty()) - { - continue; - } - Item = m_Queue.front(); - m_Queue.pop_front(); - if (m_Queue.empty()) - { - m_evtQueueEmpty.Set(); - } - } // CSLock(m_CS) - - LightChunk(Item); - } -} - - - - - - -void cLightingThread::LightChunk(cLightingThread::sItem & a_Item) -{ - cChunkDef::BlockNibbles BlockLight, SkyLight; - - if (!ReadChunks(a_Item.x, a_Item.z)) - { - // Neighbors not available. Re-queue in the postponed queue - cCSLock Lock(m_CS); - m_PostponedQueue.push_back(a_Item); - return; - } - - /* - // DEBUG: torch somewhere: - m_BlockTypes[19 + 24 * cChunkDef::Width * 3 + (m_HeightMap[24 + 24 * cChunkDef::Width * 3] / 2) * BlocksPerYLayer] = E_BLOCK_TORCH; - // m_HeightMap[24 + 24 * cChunkDef::Width * 3]++; - */ - - PrepareBlockLight(); - CalcLight(m_BlockLight); - - PrepareSkyLight(); - CalcLight(m_SkyLight); - - CompressLight(m_BlockLight, BlockLight); - CompressLight(m_SkyLight, SkyLight); - - /* - // DEBUG: - { - cFile f("chunk_BlockTypes.dat", cFile::fmWrite); - if (f.IsOpen()) - { - f.Write(m_BlockTypes, sizeof(m_BlockTypes)); - } - } - - // DEBUG: - { - cFile f("Chunk_SkyLight.dat", cFile::fmWrite); - if (f.IsOpen()) - { - f.Write(m_SkyLight, sizeof(m_SkyLight)); - } - } - - // DEBUG: - { - cFile f("Chunk_BlockLight.dat", cFile::fmWrite); - if (f.IsOpen()) - { - f.Write(m_BlockLight, sizeof(m_BlockLight)); - } - } - */ - - m_World->ChunkLighted(a_Item.x, a_Item.z, BlockLight, SkyLight); - - if (a_Item.m_Callback != NULL) - { - a_Item.m_Callback->Call(a_Item.x, a_Item.z); - } - delete a_Item.m_ChunkStay; -} - - - - - -bool cLightingThread::ReadChunks(int a_ChunkX, int a_ChunkZ) -{ - cReader Reader; - Reader.m_BlockTypes = m_BlockTypes; - Reader.m_HeightMap = m_HeightMap; - - for (int z = 0; z < 3; z++) - { - Reader.m_ReadingChunkZ = z; - for (int x = 0; x < 3; x++) - { - Reader.m_ReadingChunkX = x; - if (!m_World->GetChunkData(a_ChunkX + x - 1, ZERO_CHUNK_Y, a_ChunkZ + z - 1, Reader)) - { - return false; - } - } // for z - } // for x - - memset(m_BlockLight, 0, sizeof(m_BlockLight)); - memset(m_SkyLight, 0, sizeof(m_SkyLight)); - return true; -} - - - - - -void cLightingThread::PrepareSkyLight(void) -{ - // Clear seeds: - memset(m_IsSeed1, 0, sizeof(m_IsSeed1)); - m_NumSeeds = 0; - - // Walk every column that has all XZ neighbors - for (int z = 1; z < cChunkDef::Width * 3 - 1; z++) - { - int BaseZ = z * cChunkDef::Width * 3; - for (int x = 1; x < cChunkDef::Width * 3 - 1; x++) - { - int idx = BaseZ + x; - int Current = m_HeightMap[idx] + 1; - int Neighbor1 = m_HeightMap[idx + 1] + 1; // X + 1 - int Neighbor2 = m_HeightMap[idx - 1] + 1; // X - 1 - int Neighbor3 = m_HeightMap[idx + cChunkDef::Width * 3] + 1; // Z + 1 - int Neighbor4 = m_HeightMap[idx - cChunkDef::Width * 3] + 1; // Z - 1 - int MaxNeighbor = MAX(MAX(Neighbor1, Neighbor2), MAX(Neighbor3, Neighbor4)); // Maximum of the four neighbors - - // TODO: The following cycle can be transofrmed into two separate cycles with no condition inside them, one lighting and the other seeding - for (int y = Current, Index = idx + y * BlocksPerYLayer; y < cChunkDef::Height; y++, Index += BlocksPerYLayer) - { - // If all the XZ neighbors are lower than y, abort for the current column (but light up the rest of it): - if (y >= MaxNeighbor) - { - for (int y2 = y; y2 < cChunkDef::Height; y2++, Index += BlocksPerYLayer) - { - m_SkyLight[Index] = 15; - } // for y2 - break; // for y - } - - // Add current block as a seed: - m_IsSeed1[Index] = true; - m_SeedIdx1[m_NumSeeds++] = Index; - - // Light it up to full skylight: - m_SkyLight[Index] = 15; - } - } - } -} - - - - - -void cLightingThread::PrepareBlockLight(void) -{ - // Clear seeds: - memset(m_IsSeed1, 0, sizeof(m_IsSeed1)); - m_NumSeeds = 0; - - // Walk every column that has all XZ neighbors, make a seed for each light-emitting block: - for (int z = 1; z < cChunkDef::Width * 3 - 1; z++) - { - int BaseZ = z * cChunkDef::Width * 3; - for (int x = 1; x < cChunkDef::Width * 3 - 1; x++) - { - int idx = BaseZ + x; - for (int y = m_HeightMap[idx], Index = idx + y * BlocksPerYLayer; y >= 0; y--, Index -= BlocksPerYLayer) - { - if (g_BlockLightValue[m_BlockTypes[Index]] == 0) - { - continue; - } - - // Add current block as a seed: - m_IsSeed1[Index] = true; - m_SeedIdx1[m_NumSeeds++] = Index; - - // Light it up: - m_BlockLight[Index] = g_BlockLightValue[m_BlockTypes[Index]]; - } - } - } -} - - - - - -void cLightingThread::CalcLight(NIBBLETYPE * a_Light) -{ - int NumSeeds2 = 0; - while (m_NumSeeds > 0) - { - // Buffer 1 -> buffer 2 - memset(m_IsSeed2, 0, sizeof(m_IsSeed2)); - NumSeeds2 = 0; - CalcLightStep(a_Light, m_NumSeeds, m_IsSeed1, m_SeedIdx1, NumSeeds2, m_IsSeed2, m_SeedIdx2); - if (NumSeeds2 == 0) - { - return; - } - - // Buffer 2 -> buffer 1 - memset(m_IsSeed1, 0, sizeof(m_IsSeed1)); - m_NumSeeds = 0; - CalcLightStep(a_Light, NumSeeds2, m_IsSeed2, m_SeedIdx2, m_NumSeeds, m_IsSeed1, m_SeedIdx1); - } -} - - - - - -void cLightingThread::CalcLightStep( - NIBBLETYPE * a_Light, - int a_NumSeedsIn, unsigned char * a_IsSeedIn, unsigned int * a_SeedIdxIn, - int & a_NumSeedsOut, unsigned char * a_IsSeedOut, unsigned int * a_SeedIdxOut -) -{ - int NumSeedsOut = 0; - for (int i = 0; i < a_NumSeedsIn; i++) - { - int SeedIdx = a_SeedIdxIn[i]; - int SeedX = SeedIdx % (cChunkDef::Width * 3); - int SeedZ = (SeedIdx / (cChunkDef::Width * 3)) % (cChunkDef::Width * 3); - int SeedY = SeedIdx / BlocksPerYLayer; - - // Propagate seed: - if (SeedX < cChunkDef::Width * 3) - { - PropagateLight(a_Light, SeedIdx, SeedIdx + 1, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut); - } - if (SeedX > 0) - { - PropagateLight(a_Light, SeedIdx, SeedIdx - 1, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut); - } - if (SeedZ < cChunkDef::Width * 3) - { - PropagateLight(a_Light, SeedIdx, SeedIdx + cChunkDef::Width * 3, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut); - } - if (SeedZ > 0) - { - PropagateLight(a_Light, SeedIdx, SeedIdx - cChunkDef::Width * 3, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut); - } - if (SeedY < cChunkDef::Height) - { - PropagateLight(a_Light, SeedIdx, SeedIdx + cChunkDef::Width * cChunkDef::Width * 3 * 3, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut); - } - if (SeedY > 0) - { - PropagateLight(a_Light, SeedIdx, SeedIdx - cChunkDef::Width * cChunkDef::Width * 3 * 3, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut); - } - } // for i - a_SeedIdxIn[] - a_NumSeedsOut = NumSeedsOut; -} - - - - - -void cLightingThread::CompressLight(NIBBLETYPE * a_LightArray, NIBBLETYPE * a_ChunkLight) -{ - int InIdx = cChunkDef::Width * 49; // Index to the first nibble of the middle chunk in the a_LightArray - int OutIdx = 0; - for (int y = 0; y < cChunkDef::Height; y++) - { - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int x = 0; x < cChunkDef::Width; x += 2) - { - a_ChunkLight[OutIdx++] = (a_LightArray[InIdx + 1] << 4) | a_LightArray[InIdx]; - InIdx += 2; - } - InIdx += cChunkDef::Width * 2; - } - // Skip into the next y-level in the 3x3 chunk blob; each level has cChunkDef::Width * 9 rows - // We've already walked cChunkDef::Width * 3 in the "for z" cycle, that makes cChunkDef::Width * 6 rows left to skip - InIdx += cChunkDef::Width * cChunkDef::Width * 6; - } -} - - - - + +// LightingThread.cpp + +// Implements the cLightingThread class representing the thread that processes requests for lighting + +#include "Globals.h" +#include "LightingThread.h" +#include "cChunkMap.h" +#include "cWorld.h" + + + + + +/// If more than this many chunks are in the queue, a warning is printed to the log +#define WARN_ON_QUEUE_SIZE 800 + + + + + +/// Chunk data callback that takes the chunk data and puts them into cLightingThread's m_BlockTypes[] / m_HeightMap[]: +class cReader : + public cChunkDataCallback +{ + virtual void BlockTypes(const BLOCKTYPE * a_Type) override + { + // ROW is a block of 16 Blocks, one whole row is copied at a time (hopefully the compiler will optimize that) + // C++ doesn't permit copying arrays, but arrays as a part of a struct is ok :) + typedef struct {BLOCKTYPE m_Row[16]; } ROW; + ROW * InputRows = (ROW *)a_Type; + ROW * OutputRows = (ROW *)m_BlockTypes; + int InputIdx = 0; + int OutputIdx = m_ReadingChunkX + m_ReadingChunkZ * cChunkDef::Width * 3; + for (int y = 0; y < cChunkDef::Height; y++) + { + for (int z = 0; z < cChunkDef::Width; z++) + { + OutputRows[OutputIdx] = InputRows[InputIdx++]; + OutputIdx += 3; + } // for z + // Skip into the next y-level in the 3x3 chunk blob; each level has cChunkDef::Width * 9 rows + // We've already walked cChunkDef::Width * 3 in the "for z" cycle, that makes cChunkDef::Width * 6 rows left to skip + OutputIdx += cChunkDef::Width * 6; + } // for y + } // BlockTypes() + + + virtual void HeightMap(const cChunkDef::HeightMap * a_Heightmap) override + { + typedef struct {HEIGHTTYPE m_Row[16]; } ROW; + ROW * InputRows = (ROW *)a_Heightmap; + ROW * OutputRows = (ROW *)m_HeightMap; + int InputIdx = 0; + int OutputIdx = m_ReadingChunkX + m_ReadingChunkZ * cChunkDef::Width * 3; + for (int z = 0; z < cChunkDef::Width; z++) + { + OutputRows[OutputIdx] = InputRows[InputIdx++]; + OutputIdx += 3; + } // for z + } + +public: + int m_ReadingChunkX; // 0, 1 or 2; x-offset of the chunk we're reading from the BlockTypes start + int m_ReadingChunkZ; // 0, 1 or 2; z-offset of the chunk we're reading from the BlockTypes start + BLOCKTYPE * m_BlockTypes; // 3x3 chunks of block types, organized as a single XZY blob of data (instead of 3x3 XZY blobs) + HEIGHTTYPE * m_HeightMap; // 3x3 chunks of height map, organized as a single XZY blob of data (instead of 3x3 XZY blobs) +} ; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cLightingThread: + +cLightingThread::cLightingThread(void) : + super("cLightingThread"), + m_World(NULL) +{ +} + + + + + +cLightingThread::~cLightingThread() +{ + Stop(); +} + + + + + +bool cLightingThread::Start(cWorld * a_World) +{ + ASSERT(m_World == NULL); // Not started yet + m_World = a_World; + + return super::Start(); +} + + + + + +void cLightingThread::Stop(void) +{ + { + cCSLock Lock(m_CS); + m_Queue.clear(); + } + m_ShouldTerminate = true; + m_evtItemAdded.Set(); + + Wait(); +} + + + + + +void cLightingThread::QueueChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallbackAfter) +{ + ASSERT(m_World != NULL); // Did you call Start() properly? + + cChunkStay * ChunkStay = new cChunkStay(m_World); + ChunkStay->Add(a_ChunkX + 1, ZERO_CHUNK_Y, a_ChunkZ + 1); + ChunkStay->Add(a_ChunkX + 1, ZERO_CHUNK_Y, a_ChunkZ); + ChunkStay->Add(a_ChunkX + 1, ZERO_CHUNK_Y, a_ChunkZ - 1); + ChunkStay->Add(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ + 1); + ChunkStay->Add(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + ChunkStay->Add(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ - 1); + ChunkStay->Add(a_ChunkX - 1, ZERO_CHUNK_Y, a_ChunkZ + 1); + ChunkStay->Add(a_ChunkX - 1, ZERO_CHUNK_Y, a_ChunkZ); + ChunkStay->Add(a_ChunkX - 1, ZERO_CHUNK_Y, a_ChunkZ - 1); + ChunkStay->Enable(); + ChunkStay->Load(); + cCSLock Lock(m_CS); + m_Queue.push_back(sItem(a_ChunkX, a_ChunkZ, ChunkStay, a_CallbackAfter)); + if (m_Queue.size() > WARN_ON_QUEUE_SIZE) + { + LOGINFO("Lighting thread overloaded, %d items in queue", m_Queue.size()); + } + m_evtItemAdded.Set(); +} + + + + + +void cLightingThread::WaitForQueueEmpty(void) +{ + cCSLock Lock(m_CS); + while (!m_ShouldTerminate && (!m_Queue.empty() || !m_PostponedQueue.empty())) + { + cCSUnlock Unlock(Lock); + m_evtQueueEmpty.Wait(); + } +} + + + + + +size_t cLightingThread::GetQueueLength(void) +{ + cCSLock Lock(m_CS); + return m_Queue.size() + m_PostponedQueue.size(); +} + + + + + +void cLightingThread::ChunkReady(int a_ChunkX, int a_ChunkZ) +{ + // Check all the items in the m_PostponedQueue, if the chunk is their neighbor, move the item to m_Queue + + bool NewlyAdded = false; + { + cCSLock Lock(m_CS); + for (sItems::iterator itr = m_PostponedQueue.begin(); itr != m_PostponedQueue.end(); ) + { + if ( + (itr->x - a_ChunkX >= -1) && (itr->x - a_ChunkX <= 1) && + (itr->x - a_ChunkX >= -1) && (itr->x - a_ChunkX <= 1) + ) + { + // It is a neighbor + m_Queue.push_back(*itr); + itr = m_PostponedQueue.erase(itr); + NewlyAdded = true; + } + else + { + ++itr; + } + } // for itr - m_PostponedQueue[] + } // Lock(m_CS) + + if (NewlyAdded) + { + m_evtItemAdded.Set(); // Notify the thread it has some work to do + } +} + + + + + +void cLightingThread::Execute(void) +{ + while (true) + { + { + cCSLock Lock(m_CS); + if (m_Queue.size() == 0) + { + cCSUnlock Unlock(Lock); + m_evtItemAdded.Wait(); + } + } + + if (m_ShouldTerminate) + { + return; + } + + // Process one items from the queue: + sItem Item; + { + cCSLock Lock(m_CS); + if (m_Queue.empty()) + { + continue; + } + Item = m_Queue.front(); + m_Queue.pop_front(); + if (m_Queue.empty()) + { + m_evtQueueEmpty.Set(); + } + } // CSLock(m_CS) + + LightChunk(Item); + } +} + + + + + + +void cLightingThread::LightChunk(cLightingThread::sItem & a_Item) +{ + cChunkDef::BlockNibbles BlockLight, SkyLight; + + if (!ReadChunks(a_Item.x, a_Item.z)) + { + // Neighbors not available. Re-queue in the postponed queue + cCSLock Lock(m_CS); + m_PostponedQueue.push_back(a_Item); + return; + } + + /* + // DEBUG: torch somewhere: + m_BlockTypes[19 + 24 * cChunkDef::Width * 3 + (m_HeightMap[24 + 24 * cChunkDef::Width * 3] / 2) * BlocksPerYLayer] = E_BLOCK_TORCH; + // m_HeightMap[24 + 24 * cChunkDef::Width * 3]++; + */ + + PrepareBlockLight(); + CalcLight(m_BlockLight); + + PrepareSkyLight(); + CalcLight(m_SkyLight); + + CompressLight(m_BlockLight, BlockLight); + CompressLight(m_SkyLight, SkyLight); + + /* + // DEBUG: + { + cFile f("chunk_BlockTypes.dat", cFile::fmWrite); + if (f.IsOpen()) + { + f.Write(m_BlockTypes, sizeof(m_BlockTypes)); + } + } + + // DEBUG: + { + cFile f("Chunk_SkyLight.dat", cFile::fmWrite); + if (f.IsOpen()) + { + f.Write(m_SkyLight, sizeof(m_SkyLight)); + } + } + + // DEBUG: + { + cFile f("Chunk_BlockLight.dat", cFile::fmWrite); + if (f.IsOpen()) + { + f.Write(m_BlockLight, sizeof(m_BlockLight)); + } + } + */ + + m_World->ChunkLighted(a_Item.x, a_Item.z, BlockLight, SkyLight); + + if (a_Item.m_Callback != NULL) + { + a_Item.m_Callback->Call(a_Item.x, a_Item.z); + } + delete a_Item.m_ChunkStay; +} + + + + + +bool cLightingThread::ReadChunks(int a_ChunkX, int a_ChunkZ) +{ + cReader Reader; + Reader.m_BlockTypes = m_BlockTypes; + Reader.m_HeightMap = m_HeightMap; + + for (int z = 0; z < 3; z++) + { + Reader.m_ReadingChunkZ = z; + for (int x = 0; x < 3; x++) + { + Reader.m_ReadingChunkX = x; + if (!m_World->GetChunkData(a_ChunkX + x - 1, ZERO_CHUNK_Y, a_ChunkZ + z - 1, Reader)) + { + return false; + } + } // for z + } // for x + + memset(m_BlockLight, 0, sizeof(m_BlockLight)); + memset(m_SkyLight, 0, sizeof(m_SkyLight)); + return true; +} + + + + + +void cLightingThread::PrepareSkyLight(void) +{ + // Clear seeds: + memset(m_IsSeed1, 0, sizeof(m_IsSeed1)); + m_NumSeeds = 0; + + // Walk every column that has all XZ neighbors + for (int z = 1; z < cChunkDef::Width * 3 - 1; z++) + { + int BaseZ = z * cChunkDef::Width * 3; + for (int x = 1; x < cChunkDef::Width * 3 - 1; x++) + { + int idx = BaseZ + x; + int Current = m_HeightMap[idx] + 1; + int Neighbor1 = m_HeightMap[idx + 1] + 1; // X + 1 + int Neighbor2 = m_HeightMap[idx - 1] + 1; // X - 1 + int Neighbor3 = m_HeightMap[idx + cChunkDef::Width * 3] + 1; // Z + 1 + int Neighbor4 = m_HeightMap[idx - cChunkDef::Width * 3] + 1; // Z - 1 + int MaxNeighbor = MAX(MAX(Neighbor1, Neighbor2), MAX(Neighbor3, Neighbor4)); // Maximum of the four neighbors + + // TODO: The following cycle can be transofrmed into two separate cycles with no condition inside them, one lighting and the other seeding + for (int y = Current, Index = idx + y * BlocksPerYLayer; y < cChunkDef::Height; y++, Index += BlocksPerYLayer) + { + // If all the XZ neighbors are lower than y, abort for the current column (but light up the rest of it): + if (y >= MaxNeighbor) + { + for (int y2 = y; y2 < cChunkDef::Height; y2++, Index += BlocksPerYLayer) + { + m_SkyLight[Index] = 15; + } // for y2 + break; // for y + } + + // Add current block as a seed: + m_IsSeed1[Index] = true; + m_SeedIdx1[m_NumSeeds++] = Index; + + // Light it up to full skylight: + m_SkyLight[Index] = 15; + } + } + } +} + + + + + +void cLightingThread::PrepareBlockLight(void) +{ + // Clear seeds: + memset(m_IsSeed1, 0, sizeof(m_IsSeed1)); + m_NumSeeds = 0; + + // Walk every column that has all XZ neighbors, make a seed for each light-emitting block: + for (int z = 1; z < cChunkDef::Width * 3 - 1; z++) + { + int BaseZ = z * cChunkDef::Width * 3; + for (int x = 1; x < cChunkDef::Width * 3 - 1; x++) + { + int idx = BaseZ + x; + for (int y = m_HeightMap[idx], Index = idx + y * BlocksPerYLayer; y >= 0; y--, Index -= BlocksPerYLayer) + { + if (g_BlockLightValue[m_BlockTypes[Index]] == 0) + { + continue; + } + + // Add current block as a seed: + m_IsSeed1[Index] = true; + m_SeedIdx1[m_NumSeeds++] = Index; + + // Light it up: + m_BlockLight[Index] = g_BlockLightValue[m_BlockTypes[Index]]; + } + } + } +} + + + + + +void cLightingThread::CalcLight(NIBBLETYPE * a_Light) +{ + int NumSeeds2 = 0; + while (m_NumSeeds > 0) + { + // Buffer 1 -> buffer 2 + memset(m_IsSeed2, 0, sizeof(m_IsSeed2)); + NumSeeds2 = 0; + CalcLightStep(a_Light, m_NumSeeds, m_IsSeed1, m_SeedIdx1, NumSeeds2, m_IsSeed2, m_SeedIdx2); + if (NumSeeds2 == 0) + { + return; + } + + // Buffer 2 -> buffer 1 + memset(m_IsSeed1, 0, sizeof(m_IsSeed1)); + m_NumSeeds = 0; + CalcLightStep(a_Light, NumSeeds2, m_IsSeed2, m_SeedIdx2, m_NumSeeds, m_IsSeed1, m_SeedIdx1); + } +} + + + + + +void cLightingThread::CalcLightStep( + NIBBLETYPE * a_Light, + int a_NumSeedsIn, unsigned char * a_IsSeedIn, unsigned int * a_SeedIdxIn, + int & a_NumSeedsOut, unsigned char * a_IsSeedOut, unsigned int * a_SeedIdxOut +) +{ + int NumSeedsOut = 0; + for (int i = 0; i < a_NumSeedsIn; i++) + { + int SeedIdx = a_SeedIdxIn[i]; + int SeedX = SeedIdx % (cChunkDef::Width * 3); + int SeedZ = (SeedIdx / (cChunkDef::Width * 3)) % (cChunkDef::Width * 3); + int SeedY = SeedIdx / BlocksPerYLayer; + + // Propagate seed: + if (SeedX < cChunkDef::Width * 3) + { + PropagateLight(a_Light, SeedIdx, SeedIdx + 1, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut); + } + if (SeedX > 0) + { + PropagateLight(a_Light, SeedIdx, SeedIdx - 1, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut); + } + if (SeedZ < cChunkDef::Width * 3) + { + PropagateLight(a_Light, SeedIdx, SeedIdx + cChunkDef::Width * 3, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut); + } + if (SeedZ > 0) + { + PropagateLight(a_Light, SeedIdx, SeedIdx - cChunkDef::Width * 3, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut); + } + if (SeedY < cChunkDef::Height) + { + PropagateLight(a_Light, SeedIdx, SeedIdx + cChunkDef::Width * cChunkDef::Width * 3 * 3, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut); + } + if (SeedY > 0) + { + PropagateLight(a_Light, SeedIdx, SeedIdx - cChunkDef::Width * cChunkDef::Width * 3 * 3, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut); + } + } // for i - a_SeedIdxIn[] + a_NumSeedsOut = NumSeedsOut; +} + + + + + +void cLightingThread::CompressLight(NIBBLETYPE * a_LightArray, NIBBLETYPE * a_ChunkLight) +{ + int InIdx = cChunkDef::Width * 49; // Index to the first nibble of the middle chunk in the a_LightArray + int OutIdx = 0; + for (int y = 0; y < cChunkDef::Height; y++) + { + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x += 2) + { + a_ChunkLight[OutIdx++] = (a_LightArray[InIdx + 1] << 4) | a_LightArray[InIdx]; + InIdx += 2; + } + InIdx += cChunkDef::Width * 2; + } + // Skip into the next y-level in the 3x3 chunk blob; each level has cChunkDef::Width * 9 rows + // We've already walked cChunkDef::Width * 3 in the "for z" cycle, that makes cChunkDef::Width * 6 rows left to skip + InIdx += cChunkDef::Width * cChunkDef::Width * 6; + } +} + + + + diff --git a/source/LightingThread.h b/source/LightingThread.h index b1ff0d33f..96f7c009e 100644 --- a/source/LightingThread.h +++ b/source/LightingThread.h @@ -1,176 +1,176 @@ - -// LightingThread.h - -// Interfaces to the cLightingThread class representing the thread that processes requests for lighting - -/* -Lighting is done on whole chunks. For each chunk to be lighted, the whole 3x3 chunk area around it is read, -then it is processed, so that the middle chunk area has valid lighting, and the lighting is copied into the ChunkMap. -Lighting is calculated in full char arrays instead of nibbles, so that accessing the arrays is fast. -Lighting is calculated in a flood-fill fashion: -1. Generate seeds from where the light spreads (full skylight / light-emitting blocks) -2. For each seed: - - Spread the light 1 block in each of the 6 cardinal directions, if the blocktype allows - - If the recipient block has had lower lighting value than that being spread, make it a new seed -3. Repeat step 2, until there are no more seeds -The seeds need two fast operations: - - Check if a block at [x, y, z] is already a seed - - Get the next seed in the row -For that reason it is stored in two arrays, one stores a bool saying a seed is in that position, -the other is an array of seed coords, encoded as a single int. -Step 2 needs two separate storages for old seeds and new seeds, so there are two actual storages for that purpose, -their content is swapped after each full step-2-cycle. - -The thread has two queues of chunks that are to be lighted. -The first queue, m_Queue, is the only one that is publicly visible, chunks get queued there by external requests. -The second one, m_PostponedQueue, is for chunks that have been taken out of m_Queue and didn't have neighbors ready. -Chunks from m_PostponedQueue are moved back into m_Queue when their neighbors get valid, using the ChunkReady callback. -*/ - - - -#pragma once - -#include "cIsThread.h" -#include "ChunkDef.h" - - - - - -// fwd: "cWorld.h" -class cWorld; - -// fwd: "cChunkMap.h" -class cChunkStay; - - - - - -class cLightingThread : - public cIsThread -{ - typedef cIsThread super; - -public: - - cLightingThread(void); - ~cLightingThread(); - - bool Start(cWorld * a_World); - - void Stop(void); - - /// Queues the entire chunk for lighting - void QueueChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallbackAfter = NULL); - - /// Blocks until the queue is empty or the thread is terminated - void WaitForQueueEmpty(void); - - size_t GetQueueLength(void); - - /// Called from cWorld when a chunk gets valid. Chunks in m_PostponedQueue may need moving into m_Queue - void ChunkReady(int a_ChunkX, int a_ChunkZ); - -protected: - - struct sItem - { - int x, z; - cChunkStay * m_ChunkStay; - cChunkCoordCallback * m_Callback; - - sItem(void) {} // empty default constructor needed - sItem(int a_X, int a_Z, cChunkStay * a_ChunkStay, cChunkCoordCallback * a_Callback) : - x(a_X), - z(a_Z), - m_ChunkStay(a_ChunkStay), - m_Callback(a_Callback) - { - } - } ; - - typedef std::list sItems; - - cWorld * m_World; - cCriticalSection m_CS; - sItems m_Queue; - sItems m_PostponedQueue; // Chunks that have been postponed due to missing neighbors - cEvent m_evtItemAdded; // Set when queue is appended, or to stop the thread - cEvent m_evtQueueEmpty; // Set when the queue gets empty - - // Buffers for the 3x3 chunk data - // These buffers alone are 1.7 MiB in size, therefore they cannot be located on the stack safely - some architectures may have only 1 MiB for stack, or even less - // Placing the buffers into the object means that this object can light chunks only in one thread! - // The blobs are XZY organized as a whole, instead of 3x3 XZY-organized subarrays -> - // -> This means data has to be scatterred when reading and gathered when writing! - static const int BlocksPerYLayer = cChunkDef::Width * cChunkDef::Width * 3 * 3; - BLOCKTYPE m_BlockTypes[BlocksPerYLayer * cChunkDef::Height]; - NIBBLETYPE m_BlockLight[BlocksPerYLayer * cChunkDef::Height]; - NIBBLETYPE m_SkyLight [BlocksPerYLayer * cChunkDef::Height]; - HEIGHTTYPE m_HeightMap [BlocksPerYLayer]; - - // Seed management (5.7 MiB) - // Two buffers, in each calc step one is set as input and the other as output, then in the next step they're swapped - // Each seed is represented twice in this structure - both as a "list" and as a "position". - // "list" allows fast traversal from seed to seed - // "position" allows fast checking if a coord is already a seed - unsigned char m_IsSeed1 [BlocksPerYLayer * cChunkDef::Height]; - unsigned int m_SeedIdx1[BlocksPerYLayer * cChunkDef::Height]; - unsigned char m_IsSeed2 [BlocksPerYLayer * cChunkDef::Height]; - unsigned int m_SeedIdx2[BlocksPerYLayer * cChunkDef::Height]; - int m_NumSeeds; - - virtual void Execute(void) override; - - /// Lights the entire chunk. If neighbor chunks don't exist, touches them and re-queues the chunk - void LightChunk(sItem & a_Item); - - /// Prepares m_BlockTypes and m_HeightMap data; returns false if any of the chunks fail. Zeroes out the light arrays - bool ReadChunks(int a_ChunkX, int a_ChunkZ); - - /// Uses m_HeightMap to initialize the m_SkyLight[] data; fills in seeds for the skylight - void PrepareSkyLight(void); - - /// Uses m_BlockTypes to initialize the m_BlockLight[] data; fills in seeds for the blocklight - void PrepareBlockLight(void); - - /// Calculates light in the light array specified, using stored seeds - void CalcLight(NIBBLETYPE * a_Light); - - /// Does one step in the light calculation - one seed propagation and seed recalculation - void CalcLightStep( - NIBBLETYPE * a_Light, - int a_NumSeedsIn, unsigned char * a_IsSeedIn, unsigned int * a_SeedIdxIn, - int & a_NumSeedsOut, unsigned char * a_IsSeedOut, unsigned int * a_SeedIdxOut - ); - - /// Compresses from 1-byte-per-block into 2-bytes-per-block: - void CompressLight(NIBBLETYPE * a_LightArray, NIBBLETYPE * a_ChunkLight); - - inline void PropagateLight( - NIBBLETYPE * a_Light, - int a_SrcIdx, int a_DstIdx, - int & a_NumSeedsOut, unsigned char * a_IsSeedOut, unsigned int * a_SeedIdxOut - ) - { - if (a_Light[a_SrcIdx] <= a_Light[a_DstIdx] + g_BlockSpreadLightFalloff[m_BlockTypes[a_DstIdx]]) - { - // We're not offering more light than the dest block already has - return; - } - - a_Light[a_DstIdx] = a_Light[a_SrcIdx] - g_BlockSpreadLightFalloff[m_BlockTypes[a_DstIdx]]; - if (!a_IsSeedOut[a_DstIdx]) - { - a_IsSeedOut[a_DstIdx] = true; - a_SeedIdxOut[a_NumSeedsOut++] = a_DstIdx; - } - } - -} ; - - - - + +// LightingThread.h + +// Interfaces to the cLightingThread class representing the thread that processes requests for lighting + +/* +Lighting is done on whole chunks. For each chunk to be lighted, the whole 3x3 chunk area around it is read, +then it is processed, so that the middle chunk area has valid lighting, and the lighting is copied into the ChunkMap. +Lighting is calculated in full char arrays instead of nibbles, so that accessing the arrays is fast. +Lighting is calculated in a flood-fill fashion: +1. Generate seeds from where the light spreads (full skylight / light-emitting blocks) +2. For each seed: + - Spread the light 1 block in each of the 6 cardinal directions, if the blocktype allows + - If the recipient block has had lower lighting value than that being spread, make it a new seed +3. Repeat step 2, until there are no more seeds +The seeds need two fast operations: + - Check if a block at [x, y, z] is already a seed + - Get the next seed in the row +For that reason it is stored in two arrays, one stores a bool saying a seed is in that position, +the other is an array of seed coords, encoded as a single int. +Step 2 needs two separate storages for old seeds and new seeds, so there are two actual storages for that purpose, +their content is swapped after each full step-2-cycle. + +The thread has two queues of chunks that are to be lighted. +The first queue, m_Queue, is the only one that is publicly visible, chunks get queued there by external requests. +The second one, m_PostponedQueue, is for chunks that have been taken out of m_Queue and didn't have neighbors ready. +Chunks from m_PostponedQueue are moved back into m_Queue when their neighbors get valid, using the ChunkReady callback. +*/ + + + +#pragma once + +#include "cIsThread.h" +#include "ChunkDef.h" + + + + + +// fwd: "cWorld.h" +class cWorld; + +// fwd: "cChunkMap.h" +class cChunkStay; + + + + + +class cLightingThread : + public cIsThread +{ + typedef cIsThread super; + +public: + + cLightingThread(void); + ~cLightingThread(); + + bool Start(cWorld * a_World); + + void Stop(void); + + /// Queues the entire chunk for lighting + void QueueChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallbackAfter = NULL); + + /// Blocks until the queue is empty or the thread is terminated + void WaitForQueueEmpty(void); + + size_t GetQueueLength(void); + + /// Called from cWorld when a chunk gets valid. Chunks in m_PostponedQueue may need moving into m_Queue + void ChunkReady(int a_ChunkX, int a_ChunkZ); + +protected: + + struct sItem + { + int x, z; + cChunkStay * m_ChunkStay; + cChunkCoordCallback * m_Callback; + + sItem(void) {} // empty default constructor needed + sItem(int a_X, int a_Z, cChunkStay * a_ChunkStay, cChunkCoordCallback * a_Callback) : + x(a_X), + z(a_Z), + m_ChunkStay(a_ChunkStay), + m_Callback(a_Callback) + { + } + } ; + + typedef std::list sItems; + + cWorld * m_World; + cCriticalSection m_CS; + sItems m_Queue; + sItems m_PostponedQueue; // Chunks that have been postponed due to missing neighbors + cEvent m_evtItemAdded; // Set when queue is appended, or to stop the thread + cEvent m_evtQueueEmpty; // Set when the queue gets empty + + // Buffers for the 3x3 chunk data + // These buffers alone are 1.7 MiB in size, therefore they cannot be located on the stack safely - some architectures may have only 1 MiB for stack, or even less + // Placing the buffers into the object means that this object can light chunks only in one thread! + // The blobs are XZY organized as a whole, instead of 3x3 XZY-organized subarrays -> + // -> This means data has to be scatterred when reading and gathered when writing! + static const int BlocksPerYLayer = cChunkDef::Width * cChunkDef::Width * 3 * 3; + BLOCKTYPE m_BlockTypes[BlocksPerYLayer * cChunkDef::Height]; + NIBBLETYPE m_BlockLight[BlocksPerYLayer * cChunkDef::Height]; + NIBBLETYPE m_SkyLight [BlocksPerYLayer * cChunkDef::Height]; + HEIGHTTYPE m_HeightMap [BlocksPerYLayer]; + + // Seed management (5.7 MiB) + // Two buffers, in each calc step one is set as input and the other as output, then in the next step they're swapped + // Each seed is represented twice in this structure - both as a "list" and as a "position". + // "list" allows fast traversal from seed to seed + // "position" allows fast checking if a coord is already a seed + unsigned char m_IsSeed1 [BlocksPerYLayer * cChunkDef::Height]; + unsigned int m_SeedIdx1[BlocksPerYLayer * cChunkDef::Height]; + unsigned char m_IsSeed2 [BlocksPerYLayer * cChunkDef::Height]; + unsigned int m_SeedIdx2[BlocksPerYLayer * cChunkDef::Height]; + int m_NumSeeds; + + virtual void Execute(void) override; + + /// Lights the entire chunk. If neighbor chunks don't exist, touches them and re-queues the chunk + void LightChunk(sItem & a_Item); + + /// Prepares m_BlockTypes and m_HeightMap data; returns false if any of the chunks fail. Zeroes out the light arrays + bool ReadChunks(int a_ChunkX, int a_ChunkZ); + + /// Uses m_HeightMap to initialize the m_SkyLight[] data; fills in seeds for the skylight + void PrepareSkyLight(void); + + /// Uses m_BlockTypes to initialize the m_BlockLight[] data; fills in seeds for the blocklight + void PrepareBlockLight(void); + + /// Calculates light in the light array specified, using stored seeds + void CalcLight(NIBBLETYPE * a_Light); + + /// Does one step in the light calculation - one seed propagation and seed recalculation + void CalcLightStep( + NIBBLETYPE * a_Light, + int a_NumSeedsIn, unsigned char * a_IsSeedIn, unsigned int * a_SeedIdxIn, + int & a_NumSeedsOut, unsigned char * a_IsSeedOut, unsigned int * a_SeedIdxOut + ); + + /// Compresses from 1-byte-per-block into 2-bytes-per-block: + void CompressLight(NIBBLETYPE * a_LightArray, NIBBLETYPE * a_ChunkLight); + + inline void PropagateLight( + NIBBLETYPE * a_Light, + int a_SrcIdx, int a_DstIdx, + int & a_NumSeedsOut, unsigned char * a_IsSeedOut, unsigned int * a_SeedIdxOut + ) + { + if (a_Light[a_SrcIdx] <= a_Light[a_DstIdx] + g_BlockSpreadLightFalloff[m_BlockTypes[a_DstIdx]]) + { + // We're not offering more light than the dest block already has + return; + } + + a_Light[a_DstIdx] = a_Light[a_SrcIdx] - g_BlockSpreadLightFalloff[m_BlockTypes[a_DstIdx]]; + if (!a_IsSeedOut[a_DstIdx]) + { + a_IsSeedOut[a_DstIdx] = true; + a_SeedIdxOut[a_NumSeedsOut++] = a_DstIdx; + } + } + +} ; + + + + diff --git a/source/LuaFunctions.h b/source/LuaFunctions.h index 04de7784f..66a505980 100644 --- a/source/LuaFunctions.h +++ b/source/LuaFunctions.h @@ -1,17 +1,17 @@ -#pragma once - -#include "cMCLogger.h" -#include -// tolua_begin - -unsigned int GetTime() -{ - return (unsigned int)time(0); -} - -std::string GetChar( std::string & a_Str, unsigned int a_Idx ) -{ - return std::string(1, a_Str[ a_Idx ]); -} - -// tolua_end +#pragma once + +#include "cMCLogger.h" +#include +// tolua_begin + +unsigned int GetTime() +{ + return (unsigned int)time(0); +} + +std::string GetChar( std::string & a_Str, unsigned int a_Idx ) +{ + return std::string(1, a_Str[ a_Idx ]); +} + +// tolua_end diff --git a/source/LuaItems.h b/source/LuaItems.h index 28ceb0d24..deec7f205 100644 --- a/source/LuaItems.h +++ b/source/LuaItems.h @@ -1,52 +1,52 @@ - -// LuaItems.h - -// Interfaces to the cLuaItems class representing a wrapper class that allows Lua to access and manipulate cItems - - - - - -#pragma once - -#include "cItem.h" - - - - - -// tolua_begin -class cLuaItems -{ -public: - // tolua_end - // The constructor is not to be Lua-exported, Lua cannot make use of this object - cLuaItems(cItems & a_Items) : - m_Items(a_Items) - { - } - - // tolua_begin - cItem & Get (int a_Idx) {return m_Items[a_Idx]; } - void Set (int a_Idx, const cItem & a_Item) {m_Items[a_Idx] = a_Item; } - void Add (const cItem & a_Item) {m_Items.push_back(a_Item); } - void Delete(int a_Idx) {m_Items.erase(m_Items.begin() + a_Idx); } - void Clear (void) {m_Items.clear(); } - int Size (void) {return m_Items.size(); } - - void Add (ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth) - { - m_Items.push_back(cItem(a_ItemType, a_ItemCount, a_ItemHealth)); - } - - void Set (int a_Idx, ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth) - { - m_Items[a_Idx] = cItem(a_ItemType, a_ItemCount, a_ItemHealth); - } -protected: - cItems & m_Items; -} ; -// tolua_end - - - + +// LuaItems.h + +// Interfaces to the cLuaItems class representing a wrapper class that allows Lua to access and manipulate cItems + + + + + +#pragma once + +#include "cItem.h" + + + + + +// tolua_begin +class cLuaItems +{ +public: + // tolua_end + // The constructor is not to be Lua-exported, Lua cannot make use of this object + cLuaItems(cItems & a_Items) : + m_Items(a_Items) + { + } + + // tolua_begin + cItem & Get (int a_Idx) {return m_Items[a_Idx]; } + void Set (int a_Idx, const cItem & a_Item) {m_Items[a_Idx] = a_Item; } + void Add (const cItem & a_Item) {m_Items.push_back(a_Item); } + void Delete(int a_Idx) {m_Items.erase(m_Items.begin() + a_Idx); } + void Clear (void) {m_Items.clear(); } + int Size (void) {return m_Items.size(); } + + void Add (ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth) + { + m_Items.push_back(cItem(a_ItemType, a_ItemCount, a_ItemHealth)); + } + + void Set (int a_Idx, ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth) + { + m_Items[a_Idx] = cItem(a_ItemType, a_ItemCount, a_ItemHealth); + } +protected: + cItems & m_Items; +} ; +// tolua_end + + + diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index b6e1e9f72..8349f52f0 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -1,614 +1,614 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "ManualBindings.h" -#include "tolua++.h" - -#include "cRoot.h" -#include "cWorld.h" -#include "cPlugin.h" -#include "cPluginManager.h" -#include "cWebPlugin_Lua.h" -#include "cLuaCommandBinder.h" -#include "cPlayer.h" -#include "cWebAdmin.h" -#include "cStringMap.h" -#include "cClientHandle.h" -#include "md5/md5.h" - - -static bool report_errors(lua_State* lua, int status) -{ - if ( status!=0 ) - { - std::string s = lua_tostring(lua, -1); - LOGERROR("-- %s", s.c_str() ); - lua_pop(lua, 1); - return true; - } - return false; -} - - -/**************************** - * Lua bound functions with special return types - **/ - -static int tolua_StringSplit(lua_State* tolua_S) -{ - std::string str = ((std::string) tolua_tocppstring(tolua_S,1,0)); - std::string delim = ((std::string) tolua_tocppstring(tolua_S,2,0)); - - AStringVector Split = StringSplit( str, delim ); - - lua_createtable(tolua_S, Split.size(), 0); - int newTable = lua_gettop(tolua_S); - int index = 1; - std::vector::const_iterator iter = Split.begin(); - while(iter != Split.end()) { - tolua_pushstring( tolua_S, (*iter).c_str() ); - lua_rawseti(tolua_S, newTable, index); - ++iter; - ++index; - } - return 1; -} - - - - - -static int tolua_LOG(lua_State* tolua_S) -{ - const char* str = tolua_tocppstring(tolua_S,1,0); - cMCLogger::GetInstance()->LogSimple( str, 0 ); - return 0; -} - - - - - -static int tolua_LOGINFO(lua_State* tolua_S) -{ - const char* str = tolua_tocppstring(tolua_S,1,0); - cMCLogger::GetInstance()->LogSimple( str, 1 ); - return 0; -} - - - - - -static int tolua_LOGWARN(lua_State* tolua_S) -{ - const char* str = tolua_tocppstring(tolua_S,1,0); - cMCLogger::GetInstance()->LogSimple( str, 2 ); - return 0; -} - - - - - -static int tolua_LOGERROR(lua_State* tolua_S) -{ - const char* str = tolua_tocppstring(tolua_S,1,0); - cMCLogger::GetInstance()->LogSimple( str, 3 ); - return 0; -} - - - - - -static int tolua_cRoot_ForEachWorld(lua_State * tolua_S) -{ - int NumArgs = lua_gettop( tolua_S ) - 1; // This includes 'self' - if ((NumArgs != 1) && (NumArgs != 2)) - { - LOGWARN("Error in function call 'ForEachWorld': Requires 1 or 2 arguments, got %i", NumArgs); - return 0; - } - - cRoot * self = (cRoot *)tolua_tousertype(tolua_S, 1, 0); - - if (!lua_isfunction(tolua_S, 2)) - { - LOGWARN("Error in function call 'ForEachWorld': Expected a function for parameter #1"); - return 0; - } - - // luaL_ref gets reference to value on top of the stack, the table is the last argument and therefore on the top - int TableRef = LUA_REFNIL; - if( NumArgs == 2 ) - { - TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); - if( TableRef == LUA_REFNIL ) - { - LOGWARN("Error in function call 'ForEachWorld': Could not get value reference of parameter #2"); - return 0; - } - } - - // table value is popped, and now function is on top of the stack - int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); - if( FuncRef == LUA_REFNIL ) - { - LOGWARN("Error in function call 'ForEachWorld': Could not get function reference of parameter #1"); - return 0; - } - - class cLuaWorldCallback : public cWorldListCallback - { - public: - cLuaWorldCallback( lua_State* a_LuaState, int a_FuncRef, int a_TableRef ) - : LuaState( a_LuaState ) - , FuncRef( a_FuncRef ) - , TableRef( a_TableRef ) - {} - - private: - virtual bool Item(cWorld * a_World) override - { - lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); // Push function reference - tolua_pushusertype( LuaState, a_World, "cWorld" ); - if (TableRef != LUA_REFNIL) - { - lua_rawgeti(LuaState, LUA_REGISTRYINDEX, TableRef); // Push table reference - } - - int s = lua_pcall( LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); - if (report_errors(LuaState, s)) - { - return true; // break enumeration - } - - if (lua_isboolean( LuaState, -1)) - { - return (tolua_toboolean( LuaState, -1, 0) > 0); - } - return false; // continue enumeration - } - lua_State* LuaState; - int FuncRef; - int TableRef; - } Callback( tolua_S, FuncRef, TableRef ); - - bool bRetVal = self->ForEachWorld(Callback); - - // Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references - luaL_unref( tolua_S, LUA_REGISTRYINDEX, TableRef ); - luaL_unref( tolua_S, LUA_REGISTRYINDEX, FuncRef ); - - // Push return value on stack - tolua_pushboolean( tolua_S, bRetVal ); - return 1; -} - - - - - -static int tolua_cWorld_ForEachPlayer(lua_State* tolua_S) -{ - int NumArgs = lua_gettop( tolua_S )-1; // This includes 'self' - if( NumArgs != 1 && NumArgs != 2) - { - LOGWARN("Error in function call 'ForEachPlayer': Requires 1 or 2 arguments, got %i", NumArgs ); - return 0; - } - - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - - if( !lua_isfunction( tolua_S, 2 ) ) - { - LOGWARN("Error in function call 'ForEachPlayer': Expected a function for parameter #1"); - return 0; - } - - // luaL_ref gets reference to value on top of the stack, the table is the last argument and therefore on the top - int TableRef = LUA_REFNIL; - if( NumArgs == 2 ) - { - TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); - if( TableRef == LUA_REFNIL ) - { - LOGWARN("Error in function call 'ForEachPlayer': Could not get value reference of parameter #2"); - return 0; - } - } - - // table value is popped, and now function is on top of the stack - int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); - if( FuncRef == LUA_REFNIL ) - { - LOGWARN("Error in function call 'ForEachPlayer': Could not get function reference of parameter #1"); - return 0; - } - - class cLuaPlayerCallback : public cPlayerListCallback - { - public: - cLuaPlayerCallback( lua_State* a_LuaState, int a_FuncRef, int a_TableRef ) - : LuaState( a_LuaState ) - , FuncRef( a_FuncRef ) - , TableRef( a_TableRef ) - {} - - private: - virtual bool Item(cPlayer * a_Player) override - { - lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); // Push function reference - tolua_pushusertype( LuaState, a_Player, "cPlayer" ); - if( TableRef != LUA_REFNIL ) - { - lua_rawgeti( LuaState, LUA_REGISTRYINDEX, TableRef); // Push table reference - } - - int s = lua_pcall( LuaState, (TableRef==LUA_REFNIL?1:2), 1, 0); - if( report_errors( LuaState, s ) ) - { - return true; // Abort enumeration - } - - if( lua_isboolean( LuaState, -1 ) ) - { - return (tolua_toboolean( LuaState, -1, 0) > 0); - } - return false; // Continue enumeration - } - lua_State * LuaState; - int FuncRef; - int TableRef; - } Callback( tolua_S, FuncRef, TableRef ); - - bool bRetVal = self->ForEachPlayer( Callback ); - - // Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references - luaL_unref( tolua_S, LUA_REGISTRYINDEX, TableRef ); - luaL_unref( tolua_S, LUA_REGISTRYINDEX, FuncRef ); - - // Push return value on stack - tolua_pushboolean( tolua_S, bRetVal ); - return 1; -} - - - - - -static int tolua_cPlugin_GetCommands(lua_State* tolua_S) -{ - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - - const std::vector< cPlugin::CommandStruct > & AllCommands = self->GetCommands(); - - lua_createtable(tolua_S, AllCommands.size(), 0); - int newTable = lua_gettop(tolua_S); - int index = 1; - std::vector< cPlugin::CommandStruct >::const_iterator iter = AllCommands.begin(); - while(iter != AllCommands.end()) - { - const cPlugin::CommandStruct & CS = *iter; - tolua_pushusertype( tolua_S, (void*)&CS, "const cPlugin::CommandStruct" ); - lua_rawseti(tolua_S, newTable, index); - ++iter; - ++index; - } - return 1; -} - - - - - -static int tolua_cPluginManager_GetAllPlugins(lua_State* tolua_S) -{ - cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); - - const cPluginManager::PluginList & AllPlugins = self->GetAllPlugins(); - - lua_createtable(tolua_S, AllPlugins.size(), 0); - int newTable = lua_gettop(tolua_S); - int index = 1; - cPluginManager::PluginList::const_iterator iter = AllPlugins.begin(); - while(iter != AllPlugins.end()) - { - const cPlugin* Plugin = *iter; - tolua_pushusertype( tolua_S, (void*)Plugin, "const cPlugin" ); - lua_rawseti(tolua_S, newTable, index); - ++iter; - ++index; - } - return 1; -} - - - - - -static int tolua_cPlayer_GetGroups(lua_State* tolua_S) -{ - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - - const cPlayer::GroupList & AllGroups = self->GetGroups(); - - lua_createtable(tolua_S, AllGroups.size(), 0); - int newTable = lua_gettop(tolua_S); - int index = 1; - cPlayer::GroupList::const_iterator iter = AllGroups.begin(); - while(iter != AllGroups.end()) - { - const cGroup* Group = *iter; - tolua_pushusertype( tolua_S, (void*)Group, "const cGroup" ); - lua_rawseti(tolua_S, newTable, index); - ++iter; - ++index; - } - return 1; -} - - - - - -static int tolua_cPlayer_GetResolvedPermissions(lua_State* tolua_S) -{ - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - - cPlayer::StringList AllPermissions = self->GetResolvedPermissions(); - - lua_createtable(tolua_S, AllPermissions.size(), 0); - int newTable = lua_gettop(tolua_S); - int index = 1; - cPlayer::StringList::iterator iter = AllPermissions.begin(); - while(iter != AllPermissions.end()) - { - std::string& Permission = *iter; - tolua_pushstring( tolua_S, Permission.c_str() ); - lua_rawseti(tolua_S, newTable, index); - ++iter; - ++index; - } - return 1; -} - - - - - -static int tolua_cPlugin_BindCommand(lua_State* tolua_S) -{ - cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - cPluginManager* PluginManager = cRoot::Get()->GetPluginManager(); - cLuaCommandBinder* CommandBinder = PluginManager->GetLuaCommandBinder(); - - tolua_Error tolua_err; - tolua_err.array = 0; - tolua_err.index = 0; - tolua_err.type = 0; - - std::string Permission = ""; - std::string Command = ""; - int Reference = LUA_REFNIL; - - if( tolua_isstring( tolua_S, 2, 0, &tolua_err ) && - lua_isfunction( tolua_S, 3 ) ) - { - Reference = luaL_ref(tolua_S, LUA_REGISTRYINDEX); - Command = ((std::string) tolua_tocppstring(tolua_S,2,0)); - } - else if( tolua_isstring( tolua_S, 2, 0, &tolua_err ) && - tolua_isstring( tolua_S, 3, 0, &tolua_err ) && - lua_isfunction( tolua_S, 4 ) ) - { - Reference = luaL_ref(tolua_S, LUA_REGISTRYINDEX); - Command = ((std::string) tolua_tocppstring(tolua_S,2,0)); - Permission = ((std::string) tolua_tocppstring(tolua_S,3,0)); - } - else - { - if( tolua_err.type == 0 ) - { - tolua_err.type = "function"; - } - tolua_error(tolua_S,"#ferror in function 'BindCommand'.",&tolua_err); - return 0; - } - - if( Reference != LUA_REFNIL ) - { - if( !CommandBinder->BindCommand( Command, Permission, self, tolua_S, Reference ) ) - { - luaL_unref( tolua_S, LUA_REGISTRYINDEX, Reference ); - } - } - else - { - LOGERROR("ERROR: cPlugin:BindCommand invalid function reference in 2nd argument (Command: \"%s\")", Command.c_str() ); - } - - return 0; -} - - - - - -static int tolua_cWebPlugin_Lua_AddTab(lua_State* tolua_S) -{ - cWebPlugin_Lua* self = (cWebPlugin_Lua*) tolua_tousertype(tolua_S,1,0); - - tolua_Error tolua_err; - tolua_err.array = 0; - tolua_err.index = 0; - tolua_err.type = 0; - - std::string Title = ""; - int Reference = LUA_REFNIL; - - if( tolua_isstring( tolua_S, 2, 0, &tolua_err ) && - lua_isfunction( tolua_S, 3 ) ) - { - Reference = luaL_ref(tolua_S, LUA_REGISTRYINDEX); - Title = ((std::string) tolua_tocppstring(tolua_S,2,0)); - } - else - { - if( tolua_err.type == 0 ) - { - tolua_err.type = "function"; - } - tolua_error(tolua_S,"#ferror in function 'AddTab'.",&tolua_err); - return 0; - } - - if( Reference != LUA_REFNIL ) - { - if( !self->AddTab( Title.c_str(), tolua_S, Reference ) ) - { - luaL_unref( tolua_S, LUA_REGISTRYINDEX, Reference ); - } - } - else - { - LOGERROR("ERROR: cWebPlugin_Lua:AddTab invalid function reference in 2nd argument (Title: \"%s\")", Title.c_str() ); - } - - return 0; -} - - - - - -static int tolua_md5(lua_State* tolua_S) -{ - std::string SourceString = tolua_tostring(tolua_S, 1, 0); - std::string CryptedString = md5( SourceString ); - tolua_pushstring( tolua_S, CryptedString.c_str() ); - return 1; -} - - - - - -static int tolua_push_StringStringMap(lua_State* tolua_S, std::map< std::string, std::string >& a_StringStringMap ) -{ - lua_newtable(tolua_S); - int top = lua_gettop(tolua_S); - - for( std::map< std::string, std::string >::iterator it = a_StringStringMap.begin(); it != a_StringStringMap.end(); ++it ) - { - const char* key = it->first.c_str(); - const char* value = it->second.c_str(); - lua_pushstring(tolua_S, key); - lua_pushstring(tolua_S, value); - lua_settable(tolua_S, top); - } - - return 1; -} - - - - - -static int tolua_get_HTTPRequest_Params(lua_State* tolua_S) -{ - HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); - return tolua_push_StringStringMap(tolua_S, self->Params); -} - - - - - -static int tolua_get_HTTPRequest_PostParams(lua_State* tolua_S) -{ - HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); - return tolua_push_StringStringMap(tolua_S, self->PostParams); -} - - - - - -static int tolua_get_HTTPRequest_FormData(lua_State* tolua_S) -{ - HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); - std::map< std::string, HTTPFormData >& FormData = self->FormData; - - lua_newtable(tolua_S); - int top = lua_gettop(tolua_S); - - for( std::map< std::string, HTTPFormData >::iterator it = FormData.begin(); it != FormData.end(); ++it ) - { - lua_pushstring(tolua_S, it->first.c_str() ); - tolua_pushusertype(tolua_S, &(it->second), "HTTPFormData" ); - //lua_pushlstring(tolua_S, it->second.Value.c_str(), it->second.Value.size() ); // Might contain binary data - lua_settable(tolua_S, top); - } - - return 1; -} - - - - - -void ManualBindings::Bind( lua_State* tolua_S ) -{ - tolua_beginmodule(tolua_S,NULL); - tolua_function(tolua_S,"StringSplit",tolua_StringSplit); - tolua_function(tolua_S,"LOG",tolua_LOG); - tolua_function(tolua_S,"LOGINFO",tolua_LOGINFO); - tolua_function(tolua_S,"LOGWARN",tolua_LOGWARN); - tolua_function(tolua_S,"LOGERROR",tolua_LOGERROR); - tolua_function(tolua_S,"Log",tolua_LOG); // Deprecated - - tolua_beginmodule(tolua_S,"cRoot"); - tolua_function(tolua_S,"ForEachWorld",tolua_cRoot_ForEachWorld); - tolua_endmodule(tolua_S); - tolua_beginmodule(tolua_S,"cWorld"); - tolua_function(tolua_S,"ForEachPlayer",tolua_cWorld_ForEachPlayer); - tolua_endmodule(tolua_S); - tolua_beginmodule(tolua_S,"cPlugin"); - tolua_function(tolua_S,"GetCommands",tolua_cPlugin_GetCommands); - tolua_function(tolua_S,"BindCommand",tolua_cPlugin_BindCommand); - tolua_endmodule(tolua_S); - tolua_beginmodule(tolua_S,"cPluginManager"); - tolua_function(tolua_S,"GetAllPlugins",tolua_cPluginManager_GetAllPlugins); - tolua_endmodule(tolua_S); - tolua_beginmodule(tolua_S,"cPlayer"); - tolua_function(tolua_S,"GetGroups",tolua_cPlayer_GetGroups); - tolua_function(tolua_S,"GetResolvedPermissions",tolua_cPlayer_GetResolvedPermissions); - tolua_endmodule(tolua_S); - tolua_beginmodule(tolua_S,"cWebPlugin_Lua"); - tolua_function(tolua_S,"AddTab",tolua_cWebPlugin_Lua_AddTab); - tolua_endmodule(tolua_S); - - tolua_cclass(tolua_S,"HTTPRequest","HTTPRequest","",NULL); - tolua_beginmodule(tolua_S,"HTTPRequest"); - //tolua_variable(tolua_S,"Method",tolua_get_HTTPRequest_Method,tolua_set_HTTPRequest_Method); - //tolua_variable(tolua_S,"Path",tolua_get_HTTPRequest_Path,tolua_set_HTTPRequest_Path); - tolua_variable(tolua_S,"Params",tolua_get_HTTPRequest_Params,0); - tolua_variable(tolua_S,"PostParams",tolua_get_HTTPRequest_PostParams,0); - tolua_variable(tolua_S,"FormData",tolua_get_HTTPRequest_FormData,0); - tolua_endmodule(tolua_S); - - tolua_beginmodule(tolua_S,"cClientHandle"); - tolua_constant(tolua_S,"MIN_VIEW_DISTANCE",cClientHandle::MIN_VIEW_DISTANCE); - tolua_constant(tolua_S,"MAX_VIEW_DISTANCE",cClientHandle::MAX_VIEW_DISTANCE); - tolua_endmodule(tolua_S); - - tolua_function(tolua_S,"md5",tolua_md5); - - tolua_endmodule(tolua_S); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "ManualBindings.h" +#include "tolua++.h" + +#include "cRoot.h" +#include "cWorld.h" +#include "cPlugin.h" +#include "cPluginManager.h" +#include "cWebPlugin_Lua.h" +#include "cLuaCommandBinder.h" +#include "cPlayer.h" +#include "cWebAdmin.h" +#include "cStringMap.h" +#include "cClientHandle.h" +#include "md5/md5.h" + + +static bool report_errors(lua_State* lua, int status) +{ + if ( status!=0 ) + { + std::string s = lua_tostring(lua, -1); + LOGERROR("-- %s", s.c_str() ); + lua_pop(lua, 1); + return true; + } + return false; +} + + +/**************************** + * Lua bound functions with special return types + **/ + +static int tolua_StringSplit(lua_State* tolua_S) +{ + std::string str = ((std::string) tolua_tocppstring(tolua_S,1,0)); + std::string delim = ((std::string) tolua_tocppstring(tolua_S,2,0)); + + AStringVector Split = StringSplit( str, delim ); + + lua_createtable(tolua_S, Split.size(), 0); + int newTable = lua_gettop(tolua_S); + int index = 1; + std::vector::const_iterator iter = Split.begin(); + while(iter != Split.end()) { + tolua_pushstring( tolua_S, (*iter).c_str() ); + lua_rawseti(tolua_S, newTable, index); + ++iter; + ++index; + } + return 1; +} + + + + + +static int tolua_LOG(lua_State* tolua_S) +{ + const char* str = tolua_tocppstring(tolua_S,1,0); + cMCLogger::GetInstance()->LogSimple( str, 0 ); + return 0; +} + + + + + +static int tolua_LOGINFO(lua_State* tolua_S) +{ + const char* str = tolua_tocppstring(tolua_S,1,0); + cMCLogger::GetInstance()->LogSimple( str, 1 ); + return 0; +} + + + + + +static int tolua_LOGWARN(lua_State* tolua_S) +{ + const char* str = tolua_tocppstring(tolua_S,1,0); + cMCLogger::GetInstance()->LogSimple( str, 2 ); + return 0; +} + + + + + +static int tolua_LOGERROR(lua_State* tolua_S) +{ + const char* str = tolua_tocppstring(tolua_S,1,0); + cMCLogger::GetInstance()->LogSimple( str, 3 ); + return 0; +} + + + + + +static int tolua_cRoot_ForEachWorld(lua_State * tolua_S) +{ + int NumArgs = lua_gettop( tolua_S ) - 1; // This includes 'self' + if ((NumArgs != 1) && (NumArgs != 2)) + { + LOGWARN("Error in function call 'ForEachWorld': Requires 1 or 2 arguments, got %i", NumArgs); + return 0; + } + + cRoot * self = (cRoot *)tolua_tousertype(tolua_S, 1, 0); + + if (!lua_isfunction(tolua_S, 2)) + { + LOGWARN("Error in function call 'ForEachWorld': Expected a function for parameter #1"); + return 0; + } + + // luaL_ref gets reference to value on top of the stack, the table is the last argument and therefore on the top + int TableRef = LUA_REFNIL; + if( NumArgs == 2 ) + { + TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if( TableRef == LUA_REFNIL ) + { + LOGWARN("Error in function call 'ForEachWorld': Could not get value reference of parameter #2"); + return 0; + } + } + + // table value is popped, and now function is on top of the stack + int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if( FuncRef == LUA_REFNIL ) + { + LOGWARN("Error in function call 'ForEachWorld': Could not get function reference of parameter #1"); + return 0; + } + + class cLuaWorldCallback : public cWorldListCallback + { + public: + cLuaWorldCallback( lua_State* a_LuaState, int a_FuncRef, int a_TableRef ) + : LuaState( a_LuaState ) + , FuncRef( a_FuncRef ) + , TableRef( a_TableRef ) + {} + + private: + virtual bool Item(cWorld * a_World) override + { + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); // Push function reference + tolua_pushusertype( LuaState, a_World, "cWorld" ); + if (TableRef != LUA_REFNIL) + { + lua_rawgeti(LuaState, LUA_REGISTRYINDEX, TableRef); // Push table reference + } + + int s = lua_pcall( LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); + if (report_errors(LuaState, s)) + { + return true; // break enumeration + } + + if (lua_isboolean( LuaState, -1)) + { + return (tolua_toboolean( LuaState, -1, 0) > 0); + } + return false; // continue enumeration + } + lua_State* LuaState; + int FuncRef; + int TableRef; + } Callback( tolua_S, FuncRef, TableRef ); + + bool bRetVal = self->ForEachWorld(Callback); + + // Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references + luaL_unref( tolua_S, LUA_REGISTRYINDEX, TableRef ); + luaL_unref( tolua_S, LUA_REGISTRYINDEX, FuncRef ); + + // Push return value on stack + tolua_pushboolean( tolua_S, bRetVal ); + return 1; +} + + + + + +static int tolua_cWorld_ForEachPlayer(lua_State* tolua_S) +{ + int NumArgs = lua_gettop( tolua_S )-1; // This includes 'self' + if( NumArgs != 1 && NumArgs != 2) + { + LOGWARN("Error in function call 'ForEachPlayer': Requires 1 or 2 arguments, got %i", NumArgs ); + return 0; + } + + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + + if( !lua_isfunction( tolua_S, 2 ) ) + { + LOGWARN("Error in function call 'ForEachPlayer': Expected a function for parameter #1"); + return 0; + } + + // luaL_ref gets reference to value on top of the stack, the table is the last argument and therefore on the top + int TableRef = LUA_REFNIL; + if( NumArgs == 2 ) + { + TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if( TableRef == LUA_REFNIL ) + { + LOGWARN("Error in function call 'ForEachPlayer': Could not get value reference of parameter #2"); + return 0; + } + } + + // table value is popped, and now function is on top of the stack + int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if( FuncRef == LUA_REFNIL ) + { + LOGWARN("Error in function call 'ForEachPlayer': Could not get function reference of parameter #1"); + return 0; + } + + class cLuaPlayerCallback : public cPlayerListCallback + { + public: + cLuaPlayerCallback( lua_State* a_LuaState, int a_FuncRef, int a_TableRef ) + : LuaState( a_LuaState ) + , FuncRef( a_FuncRef ) + , TableRef( a_TableRef ) + {} + + private: + virtual bool Item(cPlayer * a_Player) override + { + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); // Push function reference + tolua_pushusertype( LuaState, a_Player, "cPlayer" ); + if( TableRef != LUA_REFNIL ) + { + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, TableRef); // Push table reference + } + + int s = lua_pcall( LuaState, (TableRef==LUA_REFNIL?1:2), 1, 0); + if( report_errors( LuaState, s ) ) + { + return true; // Abort enumeration + } + + if( lua_isboolean( LuaState, -1 ) ) + { + return (tolua_toboolean( LuaState, -1, 0) > 0); + } + return false; // Continue enumeration + } + lua_State * LuaState; + int FuncRef; + int TableRef; + } Callback( tolua_S, FuncRef, TableRef ); + + bool bRetVal = self->ForEachPlayer( Callback ); + + // Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references + luaL_unref( tolua_S, LUA_REGISTRYINDEX, TableRef ); + luaL_unref( tolua_S, LUA_REGISTRYINDEX, FuncRef ); + + // Push return value on stack + tolua_pushboolean( tolua_S, bRetVal ); + return 1; +} + + + + + +static int tolua_cPlugin_GetCommands(lua_State* tolua_S) +{ + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + + const std::vector< cPlugin::CommandStruct > & AllCommands = self->GetCommands(); + + lua_createtable(tolua_S, AllCommands.size(), 0); + int newTable = lua_gettop(tolua_S); + int index = 1; + std::vector< cPlugin::CommandStruct >::const_iterator iter = AllCommands.begin(); + while(iter != AllCommands.end()) + { + const cPlugin::CommandStruct & CS = *iter; + tolua_pushusertype( tolua_S, (void*)&CS, "const cPlugin::CommandStruct" ); + lua_rawseti(tolua_S, newTable, index); + ++iter; + ++index; + } + return 1; +} + + + + + +static int tolua_cPluginManager_GetAllPlugins(lua_State* tolua_S) +{ + cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); + + const cPluginManager::PluginList & AllPlugins = self->GetAllPlugins(); + + lua_createtable(tolua_S, AllPlugins.size(), 0); + int newTable = lua_gettop(tolua_S); + int index = 1; + cPluginManager::PluginList::const_iterator iter = AllPlugins.begin(); + while(iter != AllPlugins.end()) + { + const cPlugin* Plugin = *iter; + tolua_pushusertype( tolua_S, (void*)Plugin, "const cPlugin" ); + lua_rawseti(tolua_S, newTable, index); + ++iter; + ++index; + } + return 1; +} + + + + + +static int tolua_cPlayer_GetGroups(lua_State* tolua_S) +{ + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + + const cPlayer::GroupList & AllGroups = self->GetGroups(); + + lua_createtable(tolua_S, AllGroups.size(), 0); + int newTable = lua_gettop(tolua_S); + int index = 1; + cPlayer::GroupList::const_iterator iter = AllGroups.begin(); + while(iter != AllGroups.end()) + { + const cGroup* Group = *iter; + tolua_pushusertype( tolua_S, (void*)Group, "const cGroup" ); + lua_rawseti(tolua_S, newTable, index); + ++iter; + ++index; + } + return 1; +} + + + + + +static int tolua_cPlayer_GetResolvedPermissions(lua_State* tolua_S) +{ + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + + cPlayer::StringList AllPermissions = self->GetResolvedPermissions(); + + lua_createtable(tolua_S, AllPermissions.size(), 0); + int newTable = lua_gettop(tolua_S); + int index = 1; + cPlayer::StringList::iterator iter = AllPermissions.begin(); + while(iter != AllPermissions.end()) + { + std::string& Permission = *iter; + tolua_pushstring( tolua_S, Permission.c_str() ); + lua_rawseti(tolua_S, newTable, index); + ++iter; + ++index; + } + return 1; +} + + + + + +static int tolua_cPlugin_BindCommand(lua_State* tolua_S) +{ + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cPluginManager* PluginManager = cRoot::Get()->GetPluginManager(); + cLuaCommandBinder* CommandBinder = PluginManager->GetLuaCommandBinder(); + + tolua_Error tolua_err; + tolua_err.array = 0; + tolua_err.index = 0; + tolua_err.type = 0; + + std::string Permission = ""; + std::string Command = ""; + int Reference = LUA_REFNIL; + + if( tolua_isstring( tolua_S, 2, 0, &tolua_err ) && + lua_isfunction( tolua_S, 3 ) ) + { + Reference = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + Command = ((std::string) tolua_tocppstring(tolua_S,2,0)); + } + else if( tolua_isstring( tolua_S, 2, 0, &tolua_err ) && + tolua_isstring( tolua_S, 3, 0, &tolua_err ) && + lua_isfunction( tolua_S, 4 ) ) + { + Reference = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + Command = ((std::string) tolua_tocppstring(tolua_S,2,0)); + Permission = ((std::string) tolua_tocppstring(tolua_S,3,0)); + } + else + { + if( tolua_err.type == 0 ) + { + tolua_err.type = "function"; + } + tolua_error(tolua_S,"#ferror in function 'BindCommand'.",&tolua_err); + return 0; + } + + if( Reference != LUA_REFNIL ) + { + if( !CommandBinder->BindCommand( Command, Permission, self, tolua_S, Reference ) ) + { + luaL_unref( tolua_S, LUA_REGISTRYINDEX, Reference ); + } + } + else + { + LOGERROR("ERROR: cPlugin:BindCommand invalid function reference in 2nd argument (Command: \"%s\")", Command.c_str() ); + } + + return 0; +} + + + + + +static int tolua_cWebPlugin_Lua_AddTab(lua_State* tolua_S) +{ + cWebPlugin_Lua* self = (cWebPlugin_Lua*) tolua_tousertype(tolua_S,1,0); + + tolua_Error tolua_err; + tolua_err.array = 0; + tolua_err.index = 0; + tolua_err.type = 0; + + std::string Title = ""; + int Reference = LUA_REFNIL; + + if( tolua_isstring( tolua_S, 2, 0, &tolua_err ) && + lua_isfunction( tolua_S, 3 ) ) + { + Reference = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + Title = ((std::string) tolua_tocppstring(tolua_S,2,0)); + } + else + { + if( tolua_err.type == 0 ) + { + tolua_err.type = "function"; + } + tolua_error(tolua_S,"#ferror in function 'AddTab'.",&tolua_err); + return 0; + } + + if( Reference != LUA_REFNIL ) + { + if( !self->AddTab( Title.c_str(), tolua_S, Reference ) ) + { + luaL_unref( tolua_S, LUA_REGISTRYINDEX, Reference ); + } + } + else + { + LOGERROR("ERROR: cWebPlugin_Lua:AddTab invalid function reference in 2nd argument (Title: \"%s\")", Title.c_str() ); + } + + return 0; +} + + + + + +static int tolua_md5(lua_State* tolua_S) +{ + std::string SourceString = tolua_tostring(tolua_S, 1, 0); + std::string CryptedString = md5( SourceString ); + tolua_pushstring( tolua_S, CryptedString.c_str() ); + return 1; +} + + + + + +static int tolua_push_StringStringMap(lua_State* tolua_S, std::map< std::string, std::string >& a_StringStringMap ) +{ + lua_newtable(tolua_S); + int top = lua_gettop(tolua_S); + + for( std::map< std::string, std::string >::iterator it = a_StringStringMap.begin(); it != a_StringStringMap.end(); ++it ) + { + const char* key = it->first.c_str(); + const char* value = it->second.c_str(); + lua_pushstring(tolua_S, key); + lua_pushstring(tolua_S, value); + lua_settable(tolua_S, top); + } + + return 1; +} + + + + + +static int tolua_get_HTTPRequest_Params(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); + return tolua_push_StringStringMap(tolua_S, self->Params); +} + + + + + +static int tolua_get_HTTPRequest_PostParams(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); + return tolua_push_StringStringMap(tolua_S, self->PostParams); +} + + + + + +static int tolua_get_HTTPRequest_FormData(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); + std::map< std::string, HTTPFormData >& FormData = self->FormData; + + lua_newtable(tolua_S); + int top = lua_gettop(tolua_S); + + for( std::map< std::string, HTTPFormData >::iterator it = FormData.begin(); it != FormData.end(); ++it ) + { + lua_pushstring(tolua_S, it->first.c_str() ); + tolua_pushusertype(tolua_S, &(it->second), "HTTPFormData" ); + //lua_pushlstring(tolua_S, it->second.Value.c_str(), it->second.Value.size() ); // Might contain binary data + lua_settable(tolua_S, top); + } + + return 1; +} + + + + + +void ManualBindings::Bind( lua_State* tolua_S ) +{ + tolua_beginmodule(tolua_S,NULL); + tolua_function(tolua_S,"StringSplit",tolua_StringSplit); + tolua_function(tolua_S,"LOG",tolua_LOG); + tolua_function(tolua_S,"LOGINFO",tolua_LOGINFO); + tolua_function(tolua_S,"LOGWARN",tolua_LOGWARN); + tolua_function(tolua_S,"LOGERROR",tolua_LOGERROR); + tolua_function(tolua_S,"Log",tolua_LOG); // Deprecated + + tolua_beginmodule(tolua_S,"cRoot"); + tolua_function(tolua_S,"ForEachWorld",tolua_cRoot_ForEachWorld); + tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S,"cWorld"); + tolua_function(tolua_S,"ForEachPlayer",tolua_cWorld_ForEachPlayer); + tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S,"cPlugin"); + tolua_function(tolua_S,"GetCommands",tolua_cPlugin_GetCommands); + tolua_function(tolua_S,"BindCommand",tolua_cPlugin_BindCommand); + tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S,"cPluginManager"); + tolua_function(tolua_S,"GetAllPlugins",tolua_cPluginManager_GetAllPlugins); + tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S,"cPlayer"); + tolua_function(tolua_S,"GetGroups",tolua_cPlayer_GetGroups); + tolua_function(tolua_S,"GetResolvedPermissions",tolua_cPlayer_GetResolvedPermissions); + tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S,"cWebPlugin_Lua"); + tolua_function(tolua_S,"AddTab",tolua_cWebPlugin_Lua_AddTab); + tolua_endmodule(tolua_S); + + tolua_cclass(tolua_S,"HTTPRequest","HTTPRequest","",NULL); + tolua_beginmodule(tolua_S,"HTTPRequest"); + //tolua_variable(tolua_S,"Method",tolua_get_HTTPRequest_Method,tolua_set_HTTPRequest_Method); + //tolua_variable(tolua_S,"Path",tolua_get_HTTPRequest_Path,tolua_set_HTTPRequest_Path); + tolua_variable(tolua_S,"Params",tolua_get_HTTPRequest_Params,0); + tolua_variable(tolua_S,"PostParams",tolua_get_HTTPRequest_PostParams,0); + tolua_variable(tolua_S,"FormData",tolua_get_HTTPRequest_FormData,0); + tolua_endmodule(tolua_S); + + tolua_beginmodule(tolua_S,"cClientHandle"); + tolua_constant(tolua_S,"MIN_VIEW_DISTANCE",cClientHandle::MIN_VIEW_DISTANCE); + tolua_constant(tolua_S,"MAX_VIEW_DISTANCE",cClientHandle::MAX_VIEW_DISTANCE); + tolua_endmodule(tolua_S); + + tolua_function(tolua_S,"md5",tolua_md5); + + tolua_endmodule(tolua_S); +} + + + + diff --git a/source/ManualBindings.h b/source/ManualBindings.h index 147a1362d..e6594947e 100644 --- a/source/ManualBindings.h +++ b/source/ManualBindings.h @@ -1,8 +1,8 @@ -#pragma once - -struct lua_State; -class ManualBindings -{ -public: - static void Bind( lua_State* tolua_S ); +#pragma once + +struct lua_State; +class ManualBindings +{ +public: + static void Bind( lua_State* tolua_S ); }; \ No newline at end of file diff --git a/source/Matrix4f.cpp b/source/Matrix4f.cpp index 322bad192..d0a407a99 100644 --- a/source/Matrix4f.cpp +++ b/source/Matrix4f.cpp @@ -1,4 +1,4 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -// _X: empty file?? + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +// _X: empty file?? diff --git a/source/Matrix4f.h b/source/Matrix4f.h index 131208099..ab925da03 100644 --- a/source/Matrix4f.h +++ b/source/Matrix4f.h @@ -1,111 +1,111 @@ -#pragma once - -#define _USE_MATH_DEFINES -#include -#include "Vector3f.h" - -class Matrix4f -{ -public: - enum - { - TX=3, - TY=7, - TZ=11, - D0=0, D1=5, D2=10, D3=15, - SX=D0, SY=D1, SZ=D2, - W=D3 - }; - Matrix4f() { Identity(); } - float& operator [] ( int a_N ) { return cell[a_N]; } - void Identity() - { - cell[1] = cell[2] = cell[TX] = cell[4] = cell[6] = cell[TY] = - cell[8] = cell[9] = cell[TZ] = cell[12] = cell[13] = cell[14] = 0; - cell[D0] = cell[D1] = cell[D2] = cell[W] = 1; - } - void Init( Vector3f a_Pos, float a_RX, float a_RY, float a_RZ ) - { - Matrix4f t; - t.RotateX( a_RZ ); - RotateY( a_RY ); - Concatenate( t ); - t.RotateZ( a_RX ); - Concatenate( t ); - Translate( a_Pos ); - } - void RotateX( float a_RX ) - { - float sx = (float)sin( a_RX * M_PI / 180 ); - float cx = (float)cos( a_RX * M_PI / 180 ); - Identity(); - cell[5] = cx, cell[6] = sx, cell[9] = -sx, cell[10] = cx; - } - void RotateY( float a_RY ) - { - float sy = (float)sin( a_RY * M_PI / 180 ); - float cy = (float)cos( a_RY * M_PI / 180 ); - Identity (); - cell[0] = cy, cell[2] = -sy, cell[8] = sy, cell[10] = cy; - } - void RotateZ( float a_RZ ) - { - float sz = (float)sin( a_RZ * M_PI / 180 ); - float cz = (float)cos( a_RZ * M_PI / 180 ); - Identity (); - cell[0] = cz, cell[1] = sz, cell[4] = -sz, cell[5] = cz; - } - void Translate( Vector3f a_Pos ) { cell[TX] += a_Pos.x; cell[TY] += a_Pos.y; cell[TZ] += a_Pos.z; } - void SetTranslation( Vector3f a_Pos ) { cell[TX] = a_Pos.x; cell[TY] = a_Pos.y; cell[TZ] = a_Pos.z; } - void Concatenate( const Matrix4f& m2 ) - { - Matrix4f res; - int c; - for ( c = 0; c < 4; c++ ) for ( int r = 0; r < 4; r++ ) - res.cell[r * 4 + c] = cell[r * 4] * m2.cell[c] + - cell[r * 4 + 1] * m2.cell[c + 4] + - cell[r * 4 + 2] * m2.cell[c + 8] + - cell[r * 4 + 3] * m2.cell[c + 12]; - for ( c = 0; c < 16; c++ ) cell[c] = res.cell[c]; - } - Vector3f Transform( const Vector3f& v ) const - { - float x = cell[0] * v.x + cell[1] * v.y + cell[2] * v.z + cell[3]; - float y = cell[4] * v.x + cell[5] * v.y + cell[6] * v.z + cell[7]; - float z = cell[8] * v.x + cell[9] * v.y + cell[10] * v.z + cell[11]; - return Vector3f( x, y, z ); - } - void Invert() - { - Matrix4f t; - int h, i; - float tx = -cell[3], ty = -cell[7], tz = -cell[11]; - for ( h = 0; h < 3; h++ ) for ( int v = 0; v < 3; v++ ) t.cell[h + v * 4] = cell[v + h * 4]; - for ( i = 0; i < 11; i++ ) cell[i] = t.cell[i]; - cell[3] = tx * cell[0] + ty * cell[1] + tz * cell[2]; - cell[7] = tx * cell[4] + ty * cell[5] + tz * cell[6]; - cell[11] = tx * cell[8] + ty * cell[9] + tz * cell[10]; - } - Vector3f GetXColumn() { return Vector3f( cell[0], cell[1], cell[2] ); } - Vector3f GetYColumn() { return Vector3f( cell[4], cell[5], cell[6] ); } - Vector3f GetZColumn() { return Vector3f( cell[8], cell[9], cell[10] ); } - void SetXColumn( const Vector3f & a_X ) - { - cell[0] = a_X.x; - cell[1] = a_X.y; - cell[2] = a_X.z; - } - void SetYColumn( const Vector3f & a_Y ) - { - cell[4] = a_Y.x; - cell[5] = a_Y.y; - cell[6] = a_Y.z; - } - void SetZColumn( const Vector3f & a_Z ) - { - cell[8] = a_Z.x; - cell[9] = a_Z.y; - cell[10] = a_Z.z; - } - float cell[16]; -}; +#pragma once + +#define _USE_MATH_DEFINES +#include +#include "Vector3f.h" + +class Matrix4f +{ +public: + enum + { + TX=3, + TY=7, + TZ=11, + D0=0, D1=5, D2=10, D3=15, + SX=D0, SY=D1, SZ=D2, + W=D3 + }; + Matrix4f() { Identity(); } + float& operator [] ( int a_N ) { return cell[a_N]; } + void Identity() + { + cell[1] = cell[2] = cell[TX] = cell[4] = cell[6] = cell[TY] = + cell[8] = cell[9] = cell[TZ] = cell[12] = cell[13] = cell[14] = 0; + cell[D0] = cell[D1] = cell[D2] = cell[W] = 1; + } + void Init( Vector3f a_Pos, float a_RX, float a_RY, float a_RZ ) + { + Matrix4f t; + t.RotateX( a_RZ ); + RotateY( a_RY ); + Concatenate( t ); + t.RotateZ( a_RX ); + Concatenate( t ); + Translate( a_Pos ); + } + void RotateX( float a_RX ) + { + float sx = (float)sin( a_RX * M_PI / 180 ); + float cx = (float)cos( a_RX * M_PI / 180 ); + Identity(); + cell[5] = cx, cell[6] = sx, cell[9] = -sx, cell[10] = cx; + } + void RotateY( float a_RY ) + { + float sy = (float)sin( a_RY * M_PI / 180 ); + float cy = (float)cos( a_RY * M_PI / 180 ); + Identity (); + cell[0] = cy, cell[2] = -sy, cell[8] = sy, cell[10] = cy; + } + void RotateZ( float a_RZ ) + { + float sz = (float)sin( a_RZ * M_PI / 180 ); + float cz = (float)cos( a_RZ * M_PI / 180 ); + Identity (); + cell[0] = cz, cell[1] = sz, cell[4] = -sz, cell[5] = cz; + } + void Translate( Vector3f a_Pos ) { cell[TX] += a_Pos.x; cell[TY] += a_Pos.y; cell[TZ] += a_Pos.z; } + void SetTranslation( Vector3f a_Pos ) { cell[TX] = a_Pos.x; cell[TY] = a_Pos.y; cell[TZ] = a_Pos.z; } + void Concatenate( const Matrix4f& m2 ) + { + Matrix4f res; + int c; + for ( c = 0; c < 4; c++ ) for ( int r = 0; r < 4; r++ ) + res.cell[r * 4 + c] = cell[r * 4] * m2.cell[c] + + cell[r * 4 + 1] * m2.cell[c + 4] + + cell[r * 4 + 2] * m2.cell[c + 8] + + cell[r * 4 + 3] * m2.cell[c + 12]; + for ( c = 0; c < 16; c++ ) cell[c] = res.cell[c]; + } + Vector3f Transform( const Vector3f& v ) const + { + float x = cell[0] * v.x + cell[1] * v.y + cell[2] * v.z + cell[3]; + float y = cell[4] * v.x + cell[5] * v.y + cell[6] * v.z + cell[7]; + float z = cell[8] * v.x + cell[9] * v.y + cell[10] * v.z + cell[11]; + return Vector3f( x, y, z ); + } + void Invert() + { + Matrix4f t; + int h, i; + float tx = -cell[3], ty = -cell[7], tz = -cell[11]; + for ( h = 0; h < 3; h++ ) for ( int v = 0; v < 3; v++ ) t.cell[h + v * 4] = cell[v + h * 4]; + for ( i = 0; i < 11; i++ ) cell[i] = t.cell[i]; + cell[3] = tx * cell[0] + ty * cell[1] + tz * cell[2]; + cell[7] = tx * cell[4] + ty * cell[5] + tz * cell[6]; + cell[11] = tx * cell[8] + ty * cell[9] + tz * cell[10]; + } + Vector3f GetXColumn() { return Vector3f( cell[0], cell[1], cell[2] ); } + Vector3f GetYColumn() { return Vector3f( cell[4], cell[5], cell[6] ); } + Vector3f GetZColumn() { return Vector3f( cell[8], cell[9], cell[10] ); } + void SetXColumn( const Vector3f & a_X ) + { + cell[0] = a_X.x; + cell[1] = a_X.y; + cell[2] = a_X.z; + } + void SetYColumn( const Vector3f & a_Y ) + { + cell[4] = a_Y.x; + cell[5] = a_Y.y; + cell[6] = a_Y.z; + } + void SetZColumn( const Vector3f & a_Z ) + { + cell[8] = a_Z.x; + cell[9] = a_Z.y; + cell[10] = a_Z.z; + } + float cell[16]; +}; diff --git a/source/MemoryLeak.h b/source/MemoryLeak.h index a7f0c316b..e9c0c34e3 100644 --- a/source/MemoryLeak.h +++ b/source/MemoryLeak.h @@ -1,19 +1,19 @@ -#pragma once - -#ifdef _WIN32 - #ifdef _DEBUG - // Enable the CRT debugging features: - #define _CRTDBG_MAP_ALLOC - #include - #include - - // This works only in MSVC 2010+: - #if _MSC_VER >= 1600 - // Map the new operator - #ifndef DEBUG_NEW - #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) - #define new DEBUG_NEW - #endif // _CRTDBG_MAP_ALLOC - #endif // _MSC_VER - #endif // _DEBUG -#endif // _WIN32 +#pragma once + +#ifdef _WIN32 + #ifdef _DEBUG + // Enable the CRT debugging features: + #define _CRTDBG_MAP_ALLOC + #include + #include + + // This works only in MSVC 2010+: + #if _MSC_VER >= 1600 + // Map the new operator + #ifndef DEBUG_NEW + #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) + #define new DEBUG_NEW + #endif // _CRTDBG_MAP_ALLOC + #endif // _MSC_VER + #endif // _DEBUG +#endif // _WIN32 diff --git a/source/MersenneTwister.h b/source/MersenneTwister.h index c6184ec0b..dc7134a93 100644 --- a/source/MersenneTwister.h +++ b/source/MersenneTwister.h @@ -1,456 +1,456 @@ -// MersenneTwister.h -// Mersenne Twister random number generator -- a C++ class MTRand -// Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus -// Richard J. Wagner v1.1 28 September 2009 wagnerr@umich.edu - -// The Mersenne Twister is an algorithm for generating random numbers. It -// was designed with consideration of the flaws in various other generators. -// The period, 2^19937-1, and the order of equidistribution, 623 dimensions, -// are far greater. The generator is also fast; it avoids multiplication and -// division, and it benefits from caches and pipelines. For more information -// see the inventors' web page at -// http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html - -// Reference -// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally -// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on -// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30. - -// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, -// Copyright (C) 2000 - 2009, Richard J. Wagner -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. The names of its contributors may not be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef MERSENNETWISTER_H -#define MERSENNETWISTER_H - -// Not thread safe (unless auto-initialization is avoided and each thread has -// its own MTRand object) - -#include -#include -#include -#include -#include - -class MTRand { -// Data -public: - typedef long uint32; // unsigned integer type, at least 32 bits - - enum { N = 624 }; // length of state vector - enum { SAVE = N + 1 }; // length of array for save() - -protected: - enum { M = 397 }; // period parameter - - uint32 state[N]; // internal state - uint32 *pNext; // next value to get from state - int left; // number of values left before reload needed - -// Methods -public: - MTRand( const uint32 oneSeed ); // initialize with a simple uint32 - MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or array - MTRand(); // auto-initialize with /dev/urandom or time() and clock() - MTRand( const MTRand& o ); // copy - - // Do NOT use for CRYPTOGRAPHY without securely hashing several returned - // values together, otherwise the generator state can be learned after - // reading 624 consecutive values. - - // Access to 32-bit random numbers - uint32 randInt(); // integer in [0,2^32-1] - uint32 randInt( const uint32 n ); // integer in [0,n] for n < 2^32 - double rand(); // real number in [0,1] - double rand( const double n ); // real number in [0,n] - double randExc(); // real number in [0,1) - double randExc( const double n ); // real number in [0,n) - double randDblExc(); // real number in (0,1) - double randDblExc( const double n ); // real number in (0,n) - double operator()(); // same as rand() - - // Access to 53-bit random numbers (capacity of IEEE double precision) - double rand53(); // real number in [0,1) - - // Access to nonuniform random number distributions - double randNorm( const double mean = 0.0, const double stddev = 1.0 ); - - // Re-seeding functions with same behavior as initializers - void seed( const uint32 oneSeed ); - void seed( uint32 *const bigSeed, const uint32 seedLength = N ); - void seed(); - - // Saving and loading generator state - void save( uint32* saveArray ) const; // to array of size SAVE - void load( uint32 *const loadArray ); // from such array - friend std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ); - friend std::istream& operator>>( std::istream& is, MTRand& mtrand ); - MTRand& operator=( const MTRand& o ); - -protected: - void initialize( const uint32 oneSeed ); - void reload(); - uint32 hiBit( const uint32 u ) const { return u & 0x80000000UL; } - uint32 loBit( const uint32 u ) const { return u & 0x00000001UL; } - uint32 loBits( const uint32 u ) const { return u & 0x7fffffffUL; } - uint32 mixBits( const uint32 u, const uint32 v ) const - { return hiBit(u) | loBits(v); } - uint32 magic( const uint32 u ) const - { return loBit(u) ? 0x9908b0dfUL : 0x0UL; } - uint32 twist( const uint32 m, const uint32 s0, const uint32 s1 ) const - { return m ^ (mixBits(s0,s1)>>1) ^ magic(s1); } - static uint32 hash( time_t t, clock_t c ); -}; - -// Functions are defined in order of usage to assist inlining - -inline MTRand::uint32 MTRand::hash( time_t t, clock_t c ) -{ - // Get a uint32 from t and c - // Better than uint32(x) in case x is floating point in [0,1] - // Based on code by Lawrence Kirby (fred@genesis.demon.co.uk) - - static uint32 differ = 0; // guarantee time-based seeds will change - - uint32 h1 = 0; - unsigned char *p = (unsigned char *) &t; - for( size_t i = 0; i < sizeof(t); ++i ) - { - h1 *= UCHAR_MAX + 2U; - h1 += p[i]; - } - uint32 h2 = 0; - p = (unsigned char *) &c; - for( size_t j = 0; j < sizeof(c); ++j ) - { - h2 *= UCHAR_MAX + 2U; - h2 += p[j]; - } - return ( h1 + differ++ ) ^ h2; -} - -inline void MTRand::initialize( const uint32 seed ) -{ - // Initialize generator state with seed - // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier. - // In previous versions, most significant bits (MSBs) of the seed affect - // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto. - register uint32 *s = state; - register uint32 *r = state; - register int i = 1; - *s++ = seed & 0xffffffffUL; - for( ; i < N; ++i ) - { - *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL; - r++; - } -} - -inline void MTRand::reload() -{ - // Generate N new values in state - // Made clearer and faster by Matthew Bellew (matthew.bellew@home.com) - static const int MmN = int(M) - int(N); // in case enums are unsigned - register uint32 *p = state; - register int i; - for( i = N - M; i--; ++p ) - *p = twist( p[M], p[0], p[1] ); - for( i = M; --i; ++p ) - *p = twist( p[MmN], p[0], p[1] ); - *p = twist( p[MmN], p[0], state[0] ); - - left = N, pNext = state; -} - -inline void MTRand::seed( const uint32 oneSeed ) -{ - // Seed the generator with a simple uint32 - initialize(oneSeed); - reload(); -} - -inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength ) -{ - // Seed the generator with an array of uint32's - // There are 2^19937-1 possible initial states. This function allows - // all of those to be accessed by providing at least 19937 bits (with a - // default seed length of N = 624 uint32's). Any bits above the lower 32 - // in each element are discarded. - // Just call seed() if you want to get array from /dev/urandom - initialize(19650218UL); - register int i = 1; - register uint32 j = 0; - register int k = ( N > seedLength ? N : seedLength ); - for( ; k; --k ) - { - state[i] = - state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL ); - state[i] += ( bigSeed[j] & 0xffffffffUL ) + j; - state[i] &= 0xffffffffUL; - ++i; ++j; - if( i >= N ) { state[0] = state[N-1]; i = 1; } - if( j >= seedLength ) j = 0; - } - for( k = N - 1; k; --k ) - { - state[i] = - state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL ); - state[i] -= i; - state[i] &= 0xffffffffUL; - ++i; - if( i >= N ) { state[0] = state[N-1]; i = 1; } - } - state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array - reload(); -} - -inline void MTRand::seed() -{ - // Seed the generator with an array from /dev/urandom if available - // Otherwise use a hash of time() and clock() values - - // First try getting an array from /dev/urandom - - /* // Commented out by FakeTruth because doing this 200 times a tick is SUUUUPEERRR SLOW!!~~!ŐNe - FILE* urandom = fopen( "/dev/urandom", "rb" ); - if( urandom ) - { - uint32 bigSeed[N]; - register uint32 *s = bigSeed; - register int i = N; - register bool success = true; - while( success && i-- ) - success = fread( s++, sizeof(uint32), 1, urandom ); - fclose(urandom); - if( success ) { seed( bigSeed, N ); return; } - } - */ - - // Was not successful, so use time() and clock() instead - seed( hash( time(NULL), clock() ) ); -} - -inline MTRand::MTRand( const uint32 oneSeed ) - { seed(oneSeed); } - -inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength ) - { seed(bigSeed,seedLength); } - -inline MTRand::MTRand() - { seed(); } - -inline MTRand::MTRand( const MTRand& o ) -{ - register const uint32 *t = o.state; - register uint32 *s = state; - register int i = N; - for( ; i--; *s++ = *t++ ) {} - left = o.left; - pNext = &state[N-left]; -} - -inline MTRand::uint32 MTRand::randInt() -{ - // Pull a 32-bit integer from the generator state - // Every other access function simply transforms the numbers extracted here - - if( left == 0 ) reload(); - --left; - - register uint32 s1; - s1 = *pNext++; - s1 ^= (s1 >> 11); - s1 ^= (s1 << 7) & 0x9d2c5680UL; - s1 ^= (s1 << 15) & 0xefc60000UL; - return ( s1 ^ (s1 >> 18) ); -} - -inline MTRand::uint32 MTRand::randInt( const uint32 n ) -{ - // Find which bits are used in n - // Optimized by Magnus Jonsson (magnus@smartelectronix.com) - uint32 used = n; - used |= used >> 1; - used |= used >> 2; - used |= used >> 4; - used |= used >> 8; - used |= used >> 16; - - // Draw numbers until one is found in [0,n] - uint32 i; - do - i = randInt() & used; // toss unused bits to shorten search - while( i > n ); - return i; -} - -inline double MTRand::rand() - { return double(randInt()) * (1.0/4294967295.0); } - -inline double MTRand::rand( const double n ) - { return rand() * n; } - -inline double MTRand::randExc() - { return double(randInt()) * (1.0/4294967296.0); } - -inline double MTRand::randExc( const double n ) - { return randExc() * n; } - -inline double MTRand::randDblExc() - { return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); } - -inline double MTRand::randDblExc( const double n ) - { return randDblExc() * n; } - -inline double MTRand::rand53() -{ - uint32 a = randInt() >> 5, b = randInt() >> 6; - return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada -} - -inline double MTRand::randNorm( const double mean, const double stddev ) -{ - // Return a real number from a normal (Gaussian) distribution with given - // mean and standard deviation by polar form of Box-Muller transformation - double x, y, r; - do - { - x = 2.0 * rand() - 1.0; - y = 2.0 * rand() - 1.0; - r = x * x + y * y; - } - while ( r >= 1.0 || r == 0.0 ); - double s = sqrt( -2.0 * log(r) / r ); - return mean + x * s * stddev; -} - -inline double MTRand::operator()() -{ - return rand(); -} - -inline void MTRand::save( uint32* saveArray ) const -{ - register const uint32 *s = state; - register uint32 *sa = saveArray; - register int i = N; - for( ; i--; *sa++ = *s++ ) {} - *sa = left; -} - -inline void MTRand::load( uint32 *const loadArray ) -{ - register uint32 *s = state; - register uint32 *la = loadArray; - register int i = N; - for( ; i--; *s++ = *la++ ) {} - left = *la; - pNext = &state[N-left]; -} - -inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ) -{ - register const MTRand::uint32 *s = mtrand.state; - register int i = mtrand.N; - for( ; i--; os << *s++ << "\t" ) {} - return os << mtrand.left; -} - -inline std::istream& operator>>( std::istream& is, MTRand& mtrand ) -{ - register MTRand::uint32 *s = mtrand.state; - register int i = mtrand.N; - for( ; i--; is >> *s++ ) {} - is >> mtrand.left; - mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left]; - return is; -} - -inline MTRand& MTRand::operator=( const MTRand& o ) -{ - if( this == &o ) return (*this); - register const uint32 *t = o.state; - register uint32 *s = state; - register int i = N; - for( ; i--; *s++ = *t++ ) {} - left = o.left; - pNext = &state[N-left]; - return (*this); -} - -#endif // MERSENNETWISTER_H - -// Change log: -// -// v0.1 - First release on 15 May 2000 -// - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus -// - Translated from C to C++ -// - Made completely ANSI compliant -// - Designed convenient interface for initialization, seeding, and -// obtaining numbers in default or user-defined ranges -// - Added automatic seeding from /dev/urandom or time() and clock() -// - Provided functions for saving and loading generator state -// -// v0.2 - Fixed bug which reloaded generator one step too late -// -// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew -// -// v0.4 - Removed trailing newline in saved generator format to be consistent -// with output format of built-in types -// -// v0.5 - Improved portability by replacing static const int's with enum's and -// clarifying return values in seed(); suggested by Eric Heimburg -// - Removed MAXINT constant; use 0xffffffffUL instead -// -// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits -// - Changed integer [0,n] generator to give better uniformity -// -// v0.7 - Fixed operator precedence ambiguity in reload() -// - Added access for real numbers in (0,1) and (0,n) -// -// v0.8 - Included time.h header to properly support time_t and clock_t -// -// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto -// - Allowed for seeding with arrays of any length -// - Added access for real numbers in [0,1) with 53-bit resolution -// - Added access for real numbers from normal (Gaussian) distributions -// - Increased overall speed by optimizing twist() -// - Doubled speed of integer [0,n] generation -// - Fixed out-of-range number generation on 64-bit machines -// - Improved portability by substituting literal constants for long enum's -// - Changed license from GNU LGPL to BSD -// -// v1.1 - Corrected parameter label in randNorm from "variance" to "stddev" -// - Changed randNorm algorithm from basic to polar form for efficiency -// - Updated includes from deprecated to standard forms -// - Cleaned declarations and definitions to please Intel compiler -// - Revised twist() operator to work on ones'-complement machines -// - Fixed reload() function to work when N and M are unsigned -// - Added copy constructor and copy operator from Salvador Espana +// MersenneTwister.h +// Mersenne Twister random number generator -- a C++ class MTRand +// Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus +// Richard J. Wagner v1.1 28 September 2009 wagnerr@umich.edu + +// The Mersenne Twister is an algorithm for generating random numbers. It +// was designed with consideration of the flaws in various other generators. +// The period, 2^19937-1, and the order of equidistribution, 623 dimensions, +// are far greater. The generator is also fast; it avoids multiplication and +// division, and it benefits from caches and pipelines. For more information +// see the inventors' web page at +// http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + +// Reference +// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally +// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on +// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30. + +// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, +// Copyright (C) 2000 - 2009, Richard J. Wagner +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The names of its contributors may not be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#ifndef MERSENNETWISTER_H +#define MERSENNETWISTER_H + +// Not thread safe (unless auto-initialization is avoided and each thread has +// its own MTRand object) + +#include +#include +#include +#include +#include + +class MTRand { +// Data +public: + typedef long uint32; // unsigned integer type, at least 32 bits + + enum { N = 624 }; // length of state vector + enum { SAVE = N + 1 }; // length of array for save() + +protected: + enum { M = 397 }; // period parameter + + uint32 state[N]; // internal state + uint32 *pNext; // next value to get from state + int left; // number of values left before reload needed + +// Methods +public: + MTRand( const uint32 oneSeed ); // initialize with a simple uint32 + MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or array + MTRand(); // auto-initialize with /dev/urandom or time() and clock() + MTRand( const MTRand& o ); // copy + + // Do NOT use for CRYPTOGRAPHY without securely hashing several returned + // values together, otherwise the generator state can be learned after + // reading 624 consecutive values. + + // Access to 32-bit random numbers + uint32 randInt(); // integer in [0,2^32-1] + uint32 randInt( const uint32 n ); // integer in [0,n] for n < 2^32 + double rand(); // real number in [0,1] + double rand( const double n ); // real number in [0,n] + double randExc(); // real number in [0,1) + double randExc( const double n ); // real number in [0,n) + double randDblExc(); // real number in (0,1) + double randDblExc( const double n ); // real number in (0,n) + double operator()(); // same as rand() + + // Access to 53-bit random numbers (capacity of IEEE double precision) + double rand53(); // real number in [0,1) + + // Access to nonuniform random number distributions + double randNorm( const double mean = 0.0, const double stddev = 1.0 ); + + // Re-seeding functions with same behavior as initializers + void seed( const uint32 oneSeed ); + void seed( uint32 *const bigSeed, const uint32 seedLength = N ); + void seed(); + + // Saving and loading generator state + void save( uint32* saveArray ) const; // to array of size SAVE + void load( uint32 *const loadArray ); // from such array + friend std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ); + friend std::istream& operator>>( std::istream& is, MTRand& mtrand ); + MTRand& operator=( const MTRand& o ); + +protected: + void initialize( const uint32 oneSeed ); + void reload(); + uint32 hiBit( const uint32 u ) const { return u & 0x80000000UL; } + uint32 loBit( const uint32 u ) const { return u & 0x00000001UL; } + uint32 loBits( const uint32 u ) const { return u & 0x7fffffffUL; } + uint32 mixBits( const uint32 u, const uint32 v ) const + { return hiBit(u) | loBits(v); } + uint32 magic( const uint32 u ) const + { return loBit(u) ? 0x9908b0dfUL : 0x0UL; } + uint32 twist( const uint32 m, const uint32 s0, const uint32 s1 ) const + { return m ^ (mixBits(s0,s1)>>1) ^ magic(s1); } + static uint32 hash( time_t t, clock_t c ); +}; + +// Functions are defined in order of usage to assist inlining + +inline MTRand::uint32 MTRand::hash( time_t t, clock_t c ) +{ + // Get a uint32 from t and c + // Better than uint32(x) in case x is floating point in [0,1] + // Based on code by Lawrence Kirby (fred@genesis.demon.co.uk) + + static uint32 differ = 0; // guarantee time-based seeds will change + + uint32 h1 = 0; + unsigned char *p = (unsigned char *) &t; + for( size_t i = 0; i < sizeof(t); ++i ) + { + h1 *= UCHAR_MAX + 2U; + h1 += p[i]; + } + uint32 h2 = 0; + p = (unsigned char *) &c; + for( size_t j = 0; j < sizeof(c); ++j ) + { + h2 *= UCHAR_MAX + 2U; + h2 += p[j]; + } + return ( h1 + differ++ ) ^ h2; +} + +inline void MTRand::initialize( const uint32 seed ) +{ + // Initialize generator state with seed + // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier. + // In previous versions, most significant bits (MSBs) of the seed affect + // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto. + register uint32 *s = state; + register uint32 *r = state; + register int i = 1; + *s++ = seed & 0xffffffffUL; + for( ; i < N; ++i ) + { + *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL; + r++; + } +} + +inline void MTRand::reload() +{ + // Generate N new values in state + // Made clearer and faster by Matthew Bellew (matthew.bellew@home.com) + static const int MmN = int(M) - int(N); // in case enums are unsigned + register uint32 *p = state; + register int i; + for( i = N - M; i--; ++p ) + *p = twist( p[M], p[0], p[1] ); + for( i = M; --i; ++p ) + *p = twist( p[MmN], p[0], p[1] ); + *p = twist( p[MmN], p[0], state[0] ); + + left = N, pNext = state; +} + +inline void MTRand::seed( const uint32 oneSeed ) +{ + // Seed the generator with a simple uint32 + initialize(oneSeed); + reload(); +} + +inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength ) +{ + // Seed the generator with an array of uint32's + // There are 2^19937-1 possible initial states. This function allows + // all of those to be accessed by providing at least 19937 bits (with a + // default seed length of N = 624 uint32's). Any bits above the lower 32 + // in each element are discarded. + // Just call seed() if you want to get array from /dev/urandom + initialize(19650218UL); + register int i = 1; + register uint32 j = 0; + register int k = ( N > seedLength ? N : seedLength ); + for( ; k; --k ) + { + state[i] = + state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL ); + state[i] += ( bigSeed[j] & 0xffffffffUL ) + j; + state[i] &= 0xffffffffUL; + ++i; ++j; + if( i >= N ) { state[0] = state[N-1]; i = 1; } + if( j >= seedLength ) j = 0; + } + for( k = N - 1; k; --k ) + { + state[i] = + state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL ); + state[i] -= i; + state[i] &= 0xffffffffUL; + ++i; + if( i >= N ) { state[0] = state[N-1]; i = 1; } + } + state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array + reload(); +} + +inline void MTRand::seed() +{ + // Seed the generator with an array from /dev/urandom if available + // Otherwise use a hash of time() and clock() values + + // First try getting an array from /dev/urandom + + /* // Commented out by FakeTruth because doing this 200 times a tick is SUUUUPEERRR SLOW!!~~!ŐNe + FILE* urandom = fopen( "/dev/urandom", "rb" ); + if( urandom ) + { + uint32 bigSeed[N]; + register uint32 *s = bigSeed; + register int i = N; + register bool success = true; + while( success && i-- ) + success = fread( s++, sizeof(uint32), 1, urandom ); + fclose(urandom); + if( success ) { seed( bigSeed, N ); return; } + } + */ + + // Was not successful, so use time() and clock() instead + seed( hash( time(NULL), clock() ) ); +} + +inline MTRand::MTRand( const uint32 oneSeed ) + { seed(oneSeed); } + +inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength ) + { seed(bigSeed,seedLength); } + +inline MTRand::MTRand() + { seed(); } + +inline MTRand::MTRand( const MTRand& o ) +{ + register const uint32 *t = o.state; + register uint32 *s = state; + register int i = N; + for( ; i--; *s++ = *t++ ) {} + left = o.left; + pNext = &state[N-left]; +} + +inline MTRand::uint32 MTRand::randInt() +{ + // Pull a 32-bit integer from the generator state + // Every other access function simply transforms the numbers extracted here + + if( left == 0 ) reload(); + --left; + + register uint32 s1; + s1 = *pNext++; + s1 ^= (s1 >> 11); + s1 ^= (s1 << 7) & 0x9d2c5680UL; + s1 ^= (s1 << 15) & 0xefc60000UL; + return ( s1 ^ (s1 >> 18) ); +} + +inline MTRand::uint32 MTRand::randInt( const uint32 n ) +{ + // Find which bits are used in n + // Optimized by Magnus Jonsson (magnus@smartelectronix.com) + uint32 used = n; + used |= used >> 1; + used |= used >> 2; + used |= used >> 4; + used |= used >> 8; + used |= used >> 16; + + // Draw numbers until one is found in [0,n] + uint32 i; + do + i = randInt() & used; // toss unused bits to shorten search + while( i > n ); + return i; +} + +inline double MTRand::rand() + { return double(randInt()) * (1.0/4294967295.0); } + +inline double MTRand::rand( const double n ) + { return rand() * n; } + +inline double MTRand::randExc() + { return double(randInt()) * (1.0/4294967296.0); } + +inline double MTRand::randExc( const double n ) + { return randExc() * n; } + +inline double MTRand::randDblExc() + { return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); } + +inline double MTRand::randDblExc( const double n ) + { return randDblExc() * n; } + +inline double MTRand::rand53() +{ + uint32 a = randInt() >> 5, b = randInt() >> 6; + return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada +} + +inline double MTRand::randNorm( const double mean, const double stddev ) +{ + // Return a real number from a normal (Gaussian) distribution with given + // mean and standard deviation by polar form of Box-Muller transformation + double x, y, r; + do + { + x = 2.0 * rand() - 1.0; + y = 2.0 * rand() - 1.0; + r = x * x + y * y; + } + while ( r >= 1.0 || r == 0.0 ); + double s = sqrt( -2.0 * log(r) / r ); + return mean + x * s * stddev; +} + +inline double MTRand::operator()() +{ + return rand(); +} + +inline void MTRand::save( uint32* saveArray ) const +{ + register const uint32 *s = state; + register uint32 *sa = saveArray; + register int i = N; + for( ; i--; *sa++ = *s++ ) {} + *sa = left; +} + +inline void MTRand::load( uint32 *const loadArray ) +{ + register uint32 *s = state; + register uint32 *la = loadArray; + register int i = N; + for( ; i--; *s++ = *la++ ) {} + left = *la; + pNext = &state[N-left]; +} + +inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ) +{ + register const MTRand::uint32 *s = mtrand.state; + register int i = mtrand.N; + for( ; i--; os << *s++ << "\t" ) {} + return os << mtrand.left; +} + +inline std::istream& operator>>( std::istream& is, MTRand& mtrand ) +{ + register MTRand::uint32 *s = mtrand.state; + register int i = mtrand.N; + for( ; i--; is >> *s++ ) {} + is >> mtrand.left; + mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left]; + return is; +} + +inline MTRand& MTRand::operator=( const MTRand& o ) +{ + if( this == &o ) return (*this); + register const uint32 *t = o.state; + register uint32 *s = state; + register int i = N; + for( ; i--; *s++ = *t++ ) {} + left = o.left; + pNext = &state[N-left]; + return (*this); +} + +#endif // MERSENNETWISTER_H + +// Change log: +// +// v0.1 - First release on 15 May 2000 +// - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus +// - Translated from C to C++ +// - Made completely ANSI compliant +// - Designed convenient interface for initialization, seeding, and +// obtaining numbers in default or user-defined ranges +// - Added automatic seeding from /dev/urandom or time() and clock() +// - Provided functions for saving and loading generator state +// +// v0.2 - Fixed bug which reloaded generator one step too late +// +// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew +// +// v0.4 - Removed trailing newline in saved generator format to be consistent +// with output format of built-in types +// +// v0.5 - Improved portability by replacing static const int's with enum's and +// clarifying return values in seed(); suggested by Eric Heimburg +// - Removed MAXINT constant; use 0xffffffffUL instead +// +// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits +// - Changed integer [0,n] generator to give better uniformity +// +// v0.7 - Fixed operator precedence ambiguity in reload() +// - Added access for real numbers in (0,1) and (0,n) +// +// v0.8 - Included time.h header to properly support time_t and clock_t +// +// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto +// - Allowed for seeding with arrays of any length +// - Added access for real numbers in [0,1) with 53-bit resolution +// - Added access for real numbers from normal (Gaussian) distributions +// - Increased overall speed by optimizing twist() +// - Doubled speed of integer [0,n] generation +// - Fixed out-of-range number generation on 64-bit machines +// - Improved portability by substituting literal constants for long enum's +// - Changed license from GNU LGPL to BSD +// +// v1.1 - Corrected parameter label in randNorm from "variance" to "stddev" +// - Changed randNorm algorithm from basic to polar form for efficiency +// - Updated includes from deprecated to standard forms +// - Cleaned declarations and definitions to please Intel compiler +// - Revised twist() operator to work on ones'-complement machines +// - Fixed reload() function to work when N and M are unsigned +// - Added copy constructor and copy operator from Salvador Espana diff --git a/source/PacketID.h b/source/PacketID.h index d557a284f..f11688284 100644 --- a/source/PacketID.h +++ b/source/PacketID.h @@ -1,61 +1,61 @@ -#pragma once - -//tolua_begin -enum ENUM_PACKET_ID -{ - E_KEEP_ALIVE = 0x00, - E_LOGIN = 0x01, - E_HANDSHAKE = 0x02, - E_CHAT = 0x03, - E_UPDATE_TIME = 0x04, - E_ENTITY_EQUIPMENT = 0x05, - E_USE_ENTITY = 0x07, - E_UPDATE_HEALTH = 0x08, - E_RESPAWN = 0x09, - E_FLYING = 0x0a, - E_PLAYERPOS = 0x0b, - E_PLAYERLOOK = 0x0c, - E_PLAYERMOVELOOK = 0x0d, - E_BLOCK_DIG = 0x0e, - E_BLOCK_PLACE = 0x0f, - E_ITEM_SWITCH = 0x10, - E_ADD_TO_INV = 0x11, // TODO: Sure this is not Use Bed?? - E_ANIMATION = 0x12, - E_PACKET_13 = 0x13, - E_NAMED_ENTITY_SPAWN = 0x14, - E_PICKUP_SPAWN = 0x15, - E_COLLECT_ITEM = 0x16, - E_ADD_VEHICLE = 0x17, - E_SPAWN_MOB = 0x18, - E_DESTROY_ENT = 0x1d, - E_ENTITY = 0x1e, - E_REL_ENT_MOVE = 0x1f, - E_ENT_LOOK = 0x20, - E_REL_ENT_MOVE_LOOK = 0x21, - E_ENT_TELEPORT = 0x22, - E_ENT_HEAD_LOOK = 0x23, - E_ENT_STATUS = 0x26, - E_METADATA = 0x28, - E_PRE_CHUNK = 0x32, - E_MAP_CHUNK = 0x33, - E_MULTI_BLOCK = 0x34, - E_BLOCK_CHANGE = 0x35, - E_BLOCK_ACTION = 0x36, - E_EXPLOSION = 0x3C, - E_SOUND_EFFECT = 0x3D, - E_NEW_INVALID_STATE = 0x46, - E_THUNDERBOLT = 0x47, - E_WINDOW_OPEN = 0x64, - E_WINDOW_CLOSE = 0x65, - E_WINDOW_CLICK = 0x66, - E_INVENTORY_SLOT = 0x67, - E_INVENTORY_WHOLE = 0x68, - E_INVENTORY_PROGRESS = 0x69, - E_CREATIVE_INVENTORY_ACTION = 0x6B, - E_UPDATE_SIGN = 0x82, - E_PLAYER_LIST_ITEM = 0xC9, - E_PLAYER_ABILITIES = 0xca, // since 1.2.4, protocol version 29 - E_PING = 0xfe, - E_DISCONNECT = 0xff, -}; -//tolua_end +#pragma once + +//tolua_begin +enum ENUM_PACKET_ID +{ + E_KEEP_ALIVE = 0x00, + E_LOGIN = 0x01, + E_HANDSHAKE = 0x02, + E_CHAT = 0x03, + E_UPDATE_TIME = 0x04, + E_ENTITY_EQUIPMENT = 0x05, + E_USE_ENTITY = 0x07, + E_UPDATE_HEALTH = 0x08, + E_RESPAWN = 0x09, + E_FLYING = 0x0a, + E_PLAYERPOS = 0x0b, + E_PLAYERLOOK = 0x0c, + E_PLAYERMOVELOOK = 0x0d, + E_BLOCK_DIG = 0x0e, + E_BLOCK_PLACE = 0x0f, + E_ITEM_SWITCH = 0x10, + E_ADD_TO_INV = 0x11, // TODO: Sure this is not Use Bed?? + E_ANIMATION = 0x12, + E_PACKET_13 = 0x13, + E_NAMED_ENTITY_SPAWN = 0x14, + E_PICKUP_SPAWN = 0x15, + E_COLLECT_ITEM = 0x16, + E_ADD_VEHICLE = 0x17, + E_SPAWN_MOB = 0x18, + E_DESTROY_ENT = 0x1d, + E_ENTITY = 0x1e, + E_REL_ENT_MOVE = 0x1f, + E_ENT_LOOK = 0x20, + E_REL_ENT_MOVE_LOOK = 0x21, + E_ENT_TELEPORT = 0x22, + E_ENT_HEAD_LOOK = 0x23, + E_ENT_STATUS = 0x26, + E_METADATA = 0x28, + E_PRE_CHUNK = 0x32, + E_MAP_CHUNK = 0x33, + E_MULTI_BLOCK = 0x34, + E_BLOCK_CHANGE = 0x35, + E_BLOCK_ACTION = 0x36, + E_EXPLOSION = 0x3C, + E_SOUND_EFFECT = 0x3D, + E_NEW_INVALID_STATE = 0x46, + E_THUNDERBOLT = 0x47, + E_WINDOW_OPEN = 0x64, + E_WINDOW_CLOSE = 0x65, + E_WINDOW_CLICK = 0x66, + E_INVENTORY_SLOT = 0x67, + E_INVENTORY_WHOLE = 0x68, + E_INVENTORY_PROGRESS = 0x69, + E_CREATIVE_INVENTORY_ACTION = 0x6B, + E_UPDATE_SIGN = 0x82, + E_PLAYER_LIST_ITEM = 0xC9, + E_PLAYER_ABILITIES = 0xca, // since 1.2.4, protocol version 29 + E_PING = 0xfe, + E_DISCONNECT = 0xff, +}; +//tolua_end diff --git a/source/SquirrelBindings.cpp b/source/SquirrelBindings.cpp index 9c960d923..d8f513370 100644 --- a/source/SquirrelBindings.cpp +++ b/source/SquirrelBindings.cpp @@ -1,140 +1,140 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "SquirrelBindings.h" -#if USE_SQUIRREL -#pragma warning(disable:4100) // Getting A LOT of these warnings from SqPlus -#pragma warning(disable:4127) - -#include -#include -#include <../squirrel/sqstate.h> -#include <../squirrel/sqvm.h> - -#include "cPlugin.h" -#include "cPluginManager.h" -#include "cRoot.h" -#include "cPlayer.h" - - - - - -bool SquirrelBindings::IsBound = false; - -bool IsTopClosure( HSQUIRRELVM v ) -{ - return ( v->_stack[0]._type == OT_CLOSURE ); -} - -class __Squirrel_Base_Class // All inheritable classes should extend this class, as it allows virtual functions to call Squirrel -{ -public: - template - static int ConstructAndDestruct(HSQUIRRELVM v, T* a_Instance, SQRELEASEHOOK a_ReleaseHook ) - { - LOG("ConstructAndDestruct()"); - - StackHandler sa(v); - HSQOBJECT ho = sa.GetObjectHandle(1); // OT_INSTANCE - SquirrelObject instance(ho); - SqPlus::PopulateAncestry(v, instance, a_Instance); - a_Instance->vm = v; - a_Instance->obj = instance; - - sq_setinstanceup(v, 1, a_Instance); - sq_setreleasehook(v, 1, a_ReleaseHook); - return TRUE; - } - - HSQUIRRELVM vm; - SquirrelObject obj; -}; - -class cPlugin__Squirrel : public cPlugin, public __Squirrel_Base_Class -{ -public: - cPlugin__Squirrel() { SetLanguage( cPlugin::E_SQUIRREL ); } - - bool Initialize() // This is a pure virtual function, so it NEEDS an implementation on the script side or it would be an illegal instance - { - SqPlus::SquirrelFunction InitFunc(obj, "Initialize"); - if( !InitFunc.func.IsNull() ) - return InitFunc(); - LOGWARN("cPlugin__Squirrel::Initialize() Pure virtual function called!"); // Spam some errorz to make it clear this function needs to be implemented - return false; - } - - static int constructor(HSQUIRRELVM v) { return ConstructAndDestruct( v, new cPlugin__Squirrel, SqPlus::ReleaseClassPtr::release ); } - - virtual bool OnChat( const char* a_Chat, cPlayer* a_Player ) - { - if( !IsTopClosure(vm) ) // Avoid recursion (TODO: FIXME: THIS NEEDS MORE RESEARCH!) - { //Called from C++ - return SqPlus::SquirrelFunction(obj, "OnChat")(a_Chat, a_Player); - } - else // Called from Squirrel - { - return cPlugin::OnChat(a_Chat, a_Player); - } - } -}; - -static void printFunc(HSQUIRRELVM v,const SQChar * s,...) -{ - (void)v; - va_list vl; - va_start(vl,s); - cMCLogger::GetInstance()->Log( s, vl ); - va_end(vl); -} - -DECLARE_INSTANCE_TYPE( cRoot ); -DECLARE_INSTANCE_TYPE( cPluginManager ); -DECLARE_ENUM_TYPE( cPluginManager::PluginHook ); -DECLARE_INSTANCE_TYPE( cPlugin ); -DECLARE_INSTANCE_TYPE( cPlugin__Squirrel ); - -DECLARE_INSTANCE_TYPE( cEntity ); -DECLARE_INSTANCE_TYPE( cPawn ); -DECLARE_INSTANCE_TYPE( cPlayer ); - -void SquirrelBindings::Bind( HSQUIRRELVM a_SquirrelVM ) -{ - IsBound = true; - - sq_setprintfunc(a_SquirrelVM, printFunc, printFunc); - - - SqPlus::SQClassDefNoConstructor("cEntity"); - SqPlus::SQClassDefNoConstructor("cPawn", "cEntity"); - SqPlus::SQClassDefNoConstructor("cPlayer", "cPawn"). // All NoConstructor because they need a custom one - func(&cPlayer::GetName, "GetName"); - - SqPlus::SQClassDefNoConstructor("cPlugin"). - func(&cPlugin::SetName, "SetName"). - func(&cPlugin::GetName, "GetName"). - func(&cPlugin::GetVersion, "GetVersion"). - func(&cPlugin::OnChat, "OnChat"); - - - SqPlus::SQClassDef("cPlugin__Squirrel", "cPlugin"). - staticFunc(&cPlugin__Squirrel::constructor, "constructor"); - - - SqPlus::SQClassDefNoConstructor("cRoot"). - staticFunc(&cRoot::Get, "Get"). - func(static_cast(&cRoot::GetPluginManager), "GetPluginManager"); - - - SqPlus::SQClassDefNoConstructor("cPluginManager"). - overloadFunc(&cPluginManager::AddPlugin, "AddPlugin"). - func(&cPluginManager::GetPlugin, "GetPlugin"). - func(&cPluginManager::AddHook, "AddHook"). - enumInt( cPluginManager::E_PLUGIN_CHAT, "E_PLUGIN_CHAT"); - - - -} - -#endif + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "SquirrelBindings.h" +#if USE_SQUIRREL +#pragma warning(disable:4100) // Getting A LOT of these warnings from SqPlus +#pragma warning(disable:4127) + +#include +#include +#include <../squirrel/sqstate.h> +#include <../squirrel/sqvm.h> + +#include "cPlugin.h" +#include "cPluginManager.h" +#include "cRoot.h" +#include "cPlayer.h" + + + + + +bool SquirrelBindings::IsBound = false; + +bool IsTopClosure( HSQUIRRELVM v ) +{ + return ( v->_stack[0]._type == OT_CLOSURE ); +} + +class __Squirrel_Base_Class // All inheritable classes should extend this class, as it allows virtual functions to call Squirrel +{ +public: + template + static int ConstructAndDestruct(HSQUIRRELVM v, T* a_Instance, SQRELEASEHOOK a_ReleaseHook ) + { + LOG("ConstructAndDestruct()"); + + StackHandler sa(v); + HSQOBJECT ho = sa.GetObjectHandle(1); // OT_INSTANCE + SquirrelObject instance(ho); + SqPlus::PopulateAncestry(v, instance, a_Instance); + a_Instance->vm = v; + a_Instance->obj = instance; + + sq_setinstanceup(v, 1, a_Instance); + sq_setreleasehook(v, 1, a_ReleaseHook); + return TRUE; + } + + HSQUIRRELVM vm; + SquirrelObject obj; +}; + +class cPlugin__Squirrel : public cPlugin, public __Squirrel_Base_Class +{ +public: + cPlugin__Squirrel() { SetLanguage( cPlugin::E_SQUIRREL ); } + + bool Initialize() // This is a pure virtual function, so it NEEDS an implementation on the script side or it would be an illegal instance + { + SqPlus::SquirrelFunction InitFunc(obj, "Initialize"); + if( !InitFunc.func.IsNull() ) + return InitFunc(); + LOGWARN("cPlugin__Squirrel::Initialize() Pure virtual function called!"); // Spam some errorz to make it clear this function needs to be implemented + return false; + } + + static int constructor(HSQUIRRELVM v) { return ConstructAndDestruct( v, new cPlugin__Squirrel, SqPlus::ReleaseClassPtr::release ); } + + virtual bool OnChat( const char* a_Chat, cPlayer* a_Player ) + { + if( !IsTopClosure(vm) ) // Avoid recursion (TODO: FIXME: THIS NEEDS MORE RESEARCH!) + { //Called from C++ + return SqPlus::SquirrelFunction(obj, "OnChat")(a_Chat, a_Player); + } + else // Called from Squirrel + { + return cPlugin::OnChat(a_Chat, a_Player); + } + } +}; + +static void printFunc(HSQUIRRELVM v,const SQChar * s,...) +{ + (void)v; + va_list vl; + va_start(vl,s); + cMCLogger::GetInstance()->Log( s, vl ); + va_end(vl); +} + +DECLARE_INSTANCE_TYPE( cRoot ); +DECLARE_INSTANCE_TYPE( cPluginManager ); +DECLARE_ENUM_TYPE( cPluginManager::PluginHook ); +DECLARE_INSTANCE_TYPE( cPlugin ); +DECLARE_INSTANCE_TYPE( cPlugin__Squirrel ); + +DECLARE_INSTANCE_TYPE( cEntity ); +DECLARE_INSTANCE_TYPE( cPawn ); +DECLARE_INSTANCE_TYPE( cPlayer ); + +void SquirrelBindings::Bind( HSQUIRRELVM a_SquirrelVM ) +{ + IsBound = true; + + sq_setprintfunc(a_SquirrelVM, printFunc, printFunc); + + + SqPlus::SQClassDefNoConstructor("cEntity"); + SqPlus::SQClassDefNoConstructor("cPawn", "cEntity"); + SqPlus::SQClassDefNoConstructor("cPlayer", "cPawn"). // All NoConstructor because they need a custom one + func(&cPlayer::GetName, "GetName"); + + SqPlus::SQClassDefNoConstructor("cPlugin"). + func(&cPlugin::SetName, "SetName"). + func(&cPlugin::GetName, "GetName"). + func(&cPlugin::GetVersion, "GetVersion"). + func(&cPlugin::OnChat, "OnChat"); + + + SqPlus::SQClassDef("cPlugin__Squirrel", "cPlugin"). + staticFunc(&cPlugin__Squirrel::constructor, "constructor"); + + + SqPlus::SQClassDefNoConstructor("cRoot"). + staticFunc(&cRoot::Get, "Get"). + func(static_cast(&cRoot::GetPluginManager), "GetPluginManager"); + + + SqPlus::SQClassDefNoConstructor("cPluginManager"). + overloadFunc(&cPluginManager::AddPlugin, "AddPlugin"). + func(&cPluginManager::GetPlugin, "GetPlugin"). + func(&cPluginManager::AddHook, "AddHook"). + enumInt( cPluginManager::E_PLUGIN_CHAT, "E_PLUGIN_CHAT"); + + + +} + +#endif diff --git a/source/SquirrelBindings.h b/source/SquirrelBindings.h index 858428414..06a3df716 100644 --- a/source/SquirrelBindings.h +++ b/source/SquirrelBindings.h @@ -1,15 +1,15 @@ -#pragma once - -#define USE_SQUIRREL 0 - -#if USE_SQUIRREL - -struct SQVM; -class SquirrelBindings -{ -public: - static void Bind( SQVM* a_SquirrelVM ); - static bool IsBound; -}; - -#endif +#pragma once + +#define USE_SQUIRREL 0 + +#if USE_SQUIRREL + +struct SQVM; +class SquirrelBindings +{ +public: + static void Bind( SQVM* a_SquirrelVM ); + static bool IsBound; +}; + +#endif diff --git a/source/StackWalker.cpp b/source/StackWalker.cpp index 37db4a563..bf18b9fc9 100644 --- a/source/StackWalker.cpp +++ b/source/StackWalker.cpp @@ -1,1345 +1,1345 @@ -/********************************************************************** - * - * StackWalker.cpp - * - * - * History: - * 2005-07-27 v1 - First public release on http://www.codeproject.com/ - * http://www.codeproject.com/threads/StackWalker.asp - * 2005-07-28 v2 - Changed the params of the constructor and ShowCallstack - * (to simplify the usage) - * 2005-08-01 v3 - Changed to use 'CONTEXT_FULL' instead of CONTEXT_ALL - * (should also be enough) - * - Changed to compile correctly with the PSDK of VC7.0 - * (GetFileVersionInfoSizeA and GetFileVersionInfoA is wrongly defined: - * it uses LPSTR instead of LPCSTR as first paremeter) - * - Added declarations to support VC5/6 without using 'dbghelp.h' - * - Added a 'pUserData' member to the ShowCallstack function and the - * PReadProcessMemoryRoutine declaration (to pass some user-defined data, - * which can be used in the readMemoryFunction-callback) - * 2005-08-02 v4 - OnSymInit now also outputs the OS-Version by default - * - Added example for doing an exception-callstack-walking in main.cpp - * (thanks to owillebo: http://www.codeproject.com/script/profile/whos_who.asp?id=536268) - * 2005-08-05 v5 - Removed most Lint (http://www.gimpel.com/) errors... thanks to Okko Willeboordse! - * 2008-08-04 v6 - Fixed Bug: Missing LEAK-end-tag - * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=2502890#xx2502890xx - * Fixed Bug: Compiled with "WIN32_LEAN_AND_MEAN" - * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=1824718#xx1824718xx - * Fixed Bug: Compiling with "/Wall" - * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=2638243#xx2638243xx - * Fixed Bug: Now checking SymUseSymSrv - * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1388979#xx1388979xx - * Fixed Bug: Support for recursive function calls - * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1434538#xx1434538xx - * Fixed Bug: Missing FreeLibrary call in "GetModuleListTH32" - * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1326923#xx1326923xx - * Fixed Bug: SymDia is number 7, not 9! - * 2008-09-11 v7 For some (undocumented) reason, dbhelp.h is needing a packing of 8! - * Thanks to Teajay which reported the bug... - * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=2718933#xx2718933xx - * 2008-11-27 v8 Debugging Tools for Windows are now stored in a different directory - * Thanks to Luiz Salamon which reported this "bug"... - * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=2822736#xx2822736xx - * 2009-04-10 v9 License slihtly corrected ( replaced) - * 2010-04-15 v10 Added support for VS2010 RTM - * 2010-05-2ß v11 Now using secure MyStrcCpy. Thanks to luke.simon: - * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=3477467#xx3477467xx - * - * LICENSE (http://www.opensource.org/licenses/bsd-license.php) - * - * Copyright (c) 2005-2010, Jochen Kalmbach - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * Neither the name of Jochen Kalmbach nor the names of its contributors may be - * used to endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - **********************************************************************/ -#include -#include -#include -#include -#pragma comment(lib, "version.lib") // for "VerQueryValue" -#pragma warning(disable:4826) - -#include "StackWalker.h" - - -// If VC7 and later, then use the shipped 'dbghelp.h'-file -#pragma pack(push,8) -#if _MSC_VER >= 1300 -#include -#else -// inline the important dbghelp.h-declarations... -typedef enum { - SymNone = 0, - SymCoff, - SymCv, - SymPdb, - SymExport, - SymDeferred, - SymSym, - SymDia, - SymVirtual, - NumSymTypes -} SYM_TYPE; -typedef struct _IMAGEHLP_LINE64 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) - PVOID Key; // internal - DWORD LineNumber; // line number in file - PCHAR FileName; // full filename - DWORD64 Address; // first instruction of line -} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64; -typedef struct _IMAGEHLP_MODULE64 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) - DWORD64 BaseOfImage; // base load address of module - DWORD ImageSize; // virtual size of the loaded module - DWORD TimeDateStamp; // date/time stamp from pe header - DWORD CheckSum; // checksum from the pe header - DWORD NumSyms; // number of symbols in the symbol table - SYM_TYPE SymType; // type of symbols loaded - CHAR ModuleName[32]; // module name - CHAR ImageName[256]; // image name - CHAR LoadedImageName[256]; // symbol file name -} IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64; -typedef struct _IMAGEHLP_SYMBOL64 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL64) - DWORD64 Address; // virtual address including dll base address - DWORD Size; // estimated size of symbol, can be zero - DWORD Flags; // info about the symbols, see the SYMF defines - DWORD MaxNameLength; // maximum size of symbol name in 'Name' - CHAR Name[1]; // symbol name (null terminated string) -} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64; -typedef enum { - AddrMode1616, - AddrMode1632, - AddrModeReal, - AddrModeFlat -} ADDRESS_MODE; -typedef struct _tagADDRESS64 { - DWORD64 Offset; - WORD Segment; - ADDRESS_MODE Mode; -} ADDRESS64, *LPADDRESS64; -typedef struct _KDHELP64 { - DWORD64 Thread; - DWORD ThCallbackStack; - DWORD ThCallbackBStore; - DWORD NextCallback; - DWORD FramePointer; - DWORD64 KiCallUserMode; - DWORD64 KeUserCallbackDispatcher; - DWORD64 SystemRangeStart; - DWORD64 Reserved[8]; -} KDHELP64, *PKDHELP64; -typedef struct _tagSTACKFRAME64 { - ADDRESS64 AddrPC; // program counter - ADDRESS64 AddrReturn; // return address - ADDRESS64 AddrFrame; // frame pointer - ADDRESS64 AddrStack; // stack pointer - ADDRESS64 AddrBStore; // backing store pointer - PVOID FuncTableEntry; // pointer to pdata/fpo or NULL - DWORD64 Params[4]; // possible arguments to the function - BOOL Far; // WOW far call - BOOL Virtual; // is this a virtual frame? - DWORD64 Reserved[3]; - KDHELP64 KdHelp; -} STACKFRAME64, *LPSTACKFRAME64; -typedef -BOOL -(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)( - HANDLE hProcess, - DWORD64 qwBaseAddress, - PVOID lpBuffer, - DWORD nSize, - LPDWORD lpNumberOfBytesRead - ); -typedef -PVOID -(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)( - HANDLE hProcess, - DWORD64 AddrBase - ); -typedef -DWORD64 -(__stdcall *PGET_MODULE_BASE_ROUTINE64)( - HANDLE hProcess, - DWORD64 Address - ); -typedef -DWORD64 -(__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)( - HANDLE hProcess, - HANDLE hThread, - LPADDRESS64 lpaddr - ); -#define SYMOPT_CASE_INSENSITIVE 0x00000001 -#define SYMOPT_UNDNAME 0x00000002 -#define SYMOPT_DEFERRED_LOADS 0x00000004 -#define SYMOPT_NO_CPP 0x00000008 -#define SYMOPT_LOAD_LINES 0x00000010 -#define SYMOPT_OMAP_FIND_NEAREST 0x00000020 -#define SYMOPT_LOAD_ANYTHING 0x00000040 -#define SYMOPT_IGNORE_CVREC 0x00000080 -#define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100 -#define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200 -#define SYMOPT_EXACT_SYMBOLS 0x00000400 -#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800 -#define SYMOPT_IGNORE_NT_SYMPATH 0x00001000 -#define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000 -#define SYMOPT_PUBLICS_ONLY 0x00004000 -#define SYMOPT_NO_PUBLICS 0x00008000 -#define SYMOPT_AUTO_PUBLICS 0x00010000 -#define SYMOPT_NO_IMAGE_SEARCH 0x00020000 -#define SYMOPT_SECURE 0x00040000 -#define SYMOPT_DEBUG 0x80000000 -#define UNDNAME_COMPLETE (0x0000) // Enable full undecoration -#define UNDNAME_NAME_ONLY (0x1000) // Crack only the name for primary declaration; -#endif // _MSC_VER < 1300 -#pragma pack(pop) - -// Some missing defines (for VC5/6): -#ifndef INVALID_FILE_ATTRIBUTES -#define INVALID_FILE_ATTRIBUTES ((DWORD)-1) -#endif - - -// secure-CRT_functions are only available starting with VC8 -#if _MSC_VER < 1400 -#define strcpy_s strcpy -#define strncpy_s strncpy -#define strcat_s(dst, len, src) strcat(dst, src) -#define _snprintf_s _snprintf -#define _tcscat_s _tcscat -#endif - -static void MyStrCpy(char* szDest, size_t nMaxDestSize, const char* szSrc) -{ - if (nMaxDestSize <= 0) return; - if (strlen(szSrc) < nMaxDestSize) - { - strcpy_s(szDest, nMaxDestSize, szSrc); - } - else - { - strncpy_s(szDest, nMaxDestSize, szSrc, nMaxDestSize); - szDest[nMaxDestSize-1] = 0; - } -} // MyStrCpy - -// Normally it should be enough to use 'CONTEXT_FULL' (better would be 'CONTEXT_ALL') -#define USED_CONTEXT_FLAGS CONTEXT_FULL - - -class StackWalkerInternal -{ -public: - StackWalkerInternal(StackWalker *parent, HANDLE hProcess) - { - m_parent = parent; - m_hDbhHelp = NULL; - pSC = NULL; - m_hProcess = hProcess; - m_szSymPath = NULL; - pSFTA = NULL; - pSGLFA = NULL; - pSGMB = NULL; - pSGMI = NULL; - pSGO = NULL; - pSGSFA = NULL; - pSI = NULL; - pSLM = NULL; - pSSO = NULL; - pSW = NULL; - pUDSN = NULL; - pSGSP = NULL; - } - ~StackWalkerInternal() - { - if (pSC != NULL) - pSC(m_hProcess); // SymCleanup - if (m_hDbhHelp != NULL) - FreeLibrary(m_hDbhHelp); - m_hDbhHelp = NULL; - m_parent = NULL; - if(m_szSymPath != NULL) - free(m_szSymPath); - m_szSymPath = NULL; - } - BOOL Init(LPCSTR szSymPath) - { - if (m_parent == NULL) - return FALSE; - // Dynamically load the Entry-Points for dbghelp.dll: - // First try to load the newsest one from - TCHAR szTemp[4096]; - // But before wqe do this, we first check if the ".local" file exists - if (GetModuleFileName(NULL, szTemp, 4096) > 0) - { - _tcscat_s(szTemp, _T(".local")); - if (GetFileAttributes(szTemp) == INVALID_FILE_ATTRIBUTES) - { - // ".local" file does not exist, so we can try to load the dbghelp.dll from the "Debugging Tools for Windows" - // Ok, first try the new path according to the archtitecture: -#ifdef _M_IX86 - if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) - { - _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (x86)\\dbghelp.dll")); - // now check if the file exists: - if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) - { - m_hDbhHelp = LoadLibrary(szTemp); - } - } -#elif _M_X64 - if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) - { - _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (x64)\\dbghelp.dll")); - // now check if the file exists: - if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) - { - m_hDbhHelp = LoadLibrary(szTemp); - } - } -#elif _M_IA64 - if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) - { - _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (ia64)\\dbghelp.dll")); - // now check if the file exists: - if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) - { - m_hDbhHelp = LoadLibrary(szTemp); - } - } -#endif - // If still not found, try the old directories... - if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) - { - _tcscat_s(szTemp, _T("\\Debugging Tools for Windows\\dbghelp.dll")); - // now check if the file exists: - if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) - { - m_hDbhHelp = LoadLibrary(szTemp); - } - } -#if defined _M_X64 || defined _M_IA64 - // Still not found? Then try to load the (old) 64-Bit version: - if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) - { - _tcscat_s(szTemp, _T("\\Debugging Tools for Windows 64-Bit\\dbghelp.dll")); - if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) - { - m_hDbhHelp = LoadLibrary(szTemp); - } - } -#endif - } - } - if (m_hDbhHelp == NULL) // if not already loaded, try to load a default-one - m_hDbhHelp = LoadLibrary( _T("dbghelp.dll") ); - if (m_hDbhHelp == NULL) - return FALSE; - pSI = (tSI) GetProcAddress(m_hDbhHelp, "SymInitialize" ); - pSC = (tSC) GetProcAddress(m_hDbhHelp, "SymCleanup" ); - - pSW = (tSW) GetProcAddress(m_hDbhHelp, "StackWalk64" ); - pSGO = (tSGO) GetProcAddress(m_hDbhHelp, "SymGetOptions" ); - pSSO = (tSSO) GetProcAddress(m_hDbhHelp, "SymSetOptions" ); - - pSFTA = (tSFTA) GetProcAddress(m_hDbhHelp, "SymFunctionTableAccess64" ); - pSGLFA = (tSGLFA) GetProcAddress(m_hDbhHelp, "SymGetLineFromAddr64" ); - pSGMB = (tSGMB) GetProcAddress(m_hDbhHelp, "SymGetModuleBase64" ); - pSGMI = (tSGMI) GetProcAddress(m_hDbhHelp, "SymGetModuleInfo64" ); - //pSGMI_V3 = (tSGMI_V3) GetProcAddress(m_hDbhHelp, "SymGetModuleInfo64" ); - pSGSFA = (tSGSFA) GetProcAddress(m_hDbhHelp, "SymGetSymFromAddr64" ); - pUDSN = (tUDSN) GetProcAddress(m_hDbhHelp, "UnDecorateSymbolName" ); - pSLM = (tSLM) GetProcAddress(m_hDbhHelp, "SymLoadModule64" ); - pSGSP =(tSGSP) GetProcAddress(m_hDbhHelp, "SymGetSearchPath" ); - - if ( pSC == NULL || pSFTA == NULL || pSGMB == NULL || pSGMI == NULL || - pSGO == NULL || pSGSFA == NULL || pSI == NULL || pSSO == NULL || - pSW == NULL || pUDSN == NULL || pSLM == NULL ) - { - FreeLibrary(m_hDbhHelp); - m_hDbhHelp = NULL; - pSC = NULL; - return FALSE; - } - - // SymInitialize - if (szSymPath != NULL) - m_szSymPath = _strdup(szSymPath); - if (this->pSI(m_hProcess, m_szSymPath, FALSE) == FALSE) - this->m_parent->OnDbgHelpErr("SymInitialize", GetLastError(), 0); - - DWORD symOptions = this->pSGO(); // SymGetOptions - symOptions |= SYMOPT_LOAD_LINES; - symOptions |= SYMOPT_FAIL_CRITICAL_ERRORS; - //symOptions |= SYMOPT_NO_PROMPTS; - // SymSetOptions - symOptions = this->pSSO(symOptions); - - char buf[StackWalker::STACKWALK_MAX_NAMELEN] = {0}; - if (this->pSGSP != NULL) - { - if (this->pSGSP(m_hProcess, buf, StackWalker::STACKWALK_MAX_NAMELEN) == FALSE) - this->m_parent->OnDbgHelpErr("SymGetSearchPath", GetLastError(), 0); - } - char szUserName[1024] = {0}; - DWORD dwSize = 1024; - GetUserNameA(szUserName, &dwSize); - this->m_parent->OnSymInit(buf, symOptions, szUserName); - - return TRUE; - } - - StackWalker *m_parent; - - HMODULE m_hDbhHelp; - HANDLE m_hProcess; - LPSTR m_szSymPath; - -/*typedef struct IMAGEHLP_MODULE64_V3 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) - DWORD64 BaseOfImage; // base load address of module - DWORD ImageSize; // virtual size of the loaded module - DWORD TimeDateStamp; // date/time stamp from pe header - DWORD CheckSum; // checksum from the pe header - DWORD NumSyms; // number of symbols in the symbol table - SYM_TYPE SymType; // type of symbols loaded - CHAR ModuleName[32]; // module name - CHAR ImageName[256]; // image name - // new elements: 07-Jun-2002 - CHAR LoadedImageName[256]; // symbol file name - CHAR LoadedPdbName[256]; // pdb file name - DWORD CVSig; // Signature of the CV record in the debug directories - CHAR CVData[MAX_PATH * 3]; // Contents of the CV record - DWORD PdbSig; // Signature of PDB - GUID PdbSig70; // Signature of PDB (VC 7 and up) - DWORD PdbAge; // DBI age of pdb - BOOL PdbUnmatched; // loaded an unmatched pdb - BOOL DbgUnmatched; // loaded an unmatched dbg - BOOL LineNumbers; // we have line number information - BOOL GlobalSymbols; // we have internal symbol information - BOOL TypeInfo; // we have type information - // new elements: 17-Dec-2003 - BOOL SourceIndexed; // pdb supports source server - BOOL Publics; // contains public symbols -}; -*/ - -#pragma pack(push,8) -typedef struct IMAGEHLP_MODULE64_V2 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) - DWORD64 BaseOfImage; // base load address of module - DWORD ImageSize; // virtual size of the loaded module - DWORD TimeDateStamp; // date/time stamp from pe header - DWORD CheckSum; // checksum from the pe header - DWORD NumSyms; // number of symbols in the symbol table - SYM_TYPE SymType; // type of symbols loaded - CHAR ModuleName[32]; // module name - CHAR ImageName[256]; // image name - CHAR LoadedImageName[256]; // symbol file name -}; -#pragma pack(pop) - - - // SymCleanup() - typedef BOOL (__stdcall *tSC)( IN HANDLE hProcess ); - tSC pSC; - - // SymFunctionTableAccess64() - typedef PVOID (__stdcall *tSFTA)( HANDLE hProcess, DWORD64 AddrBase ); - tSFTA pSFTA; - - // SymGetLineFromAddr64() - typedef BOOL (__stdcall *tSGLFA)( IN HANDLE hProcess, IN DWORD64 dwAddr, - OUT PDWORD pdwDisplacement, OUT PIMAGEHLP_LINE64 Line ); - tSGLFA pSGLFA; - - // SymGetModuleBase64() - typedef DWORD64 (__stdcall *tSGMB)( IN HANDLE hProcess, IN DWORD64 dwAddr ); - tSGMB pSGMB; - - // SymGetModuleInfo64() - typedef BOOL (__stdcall *tSGMI)( IN HANDLE hProcess, IN DWORD64 dwAddr, OUT IMAGEHLP_MODULE64_V2 *ModuleInfo ); - tSGMI pSGMI; - -// // SymGetModuleInfo64() -// typedef BOOL (__stdcall *tSGMI_V3)( IN HANDLE hProcess, IN DWORD64 dwAddr, OUT IMAGEHLP_MODULE64_V3 *ModuleInfo ); -// tSGMI_V3 pSGMI_V3; - - // SymGetOptions() - typedef DWORD (__stdcall *tSGO)( VOID ); - tSGO pSGO; - - // SymGetSymFromAddr64() - typedef BOOL (__stdcall *tSGSFA)( IN HANDLE hProcess, IN DWORD64 dwAddr, - OUT PDWORD64 pdwDisplacement, OUT PIMAGEHLP_SYMBOL64 Symbol ); - tSGSFA pSGSFA; - - // SymInitialize() - typedef BOOL (__stdcall *tSI)( IN HANDLE hProcess, IN PSTR UserSearchPath, IN BOOL fInvadeProcess ); - tSI pSI; - - // SymLoadModule64() - typedef DWORD64 (__stdcall *tSLM)( IN HANDLE hProcess, IN HANDLE hFile, - IN PSTR ImageName, IN PSTR ModuleName, IN DWORD64 BaseOfDll, IN DWORD SizeOfDll ); - tSLM pSLM; - - // SymSetOptions() - typedef DWORD (__stdcall *tSSO)( IN DWORD SymOptions ); - tSSO pSSO; - - // StackWalk64() - typedef BOOL (__stdcall *tSW)( - DWORD MachineType, - HANDLE hProcess, - HANDLE hThread, - LPSTACKFRAME64 StackFrame, - PVOID ContextRecord, - PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, - PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, - PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, - PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress ); - tSW pSW; - - // UnDecorateSymbolName() - typedef DWORD (__stdcall WINAPI *tUDSN)( PCSTR DecoratedName, PSTR UnDecoratedName, - DWORD UndecoratedLength, DWORD Flags ); - tUDSN pUDSN; - - typedef BOOL (__stdcall WINAPI *tSGSP)(HANDLE hProcess, PSTR SearchPath, DWORD SearchPathLength); - tSGSP pSGSP; - - -private: - // **************************************** ToolHelp32 ************************ - #define MAX_MODULE_NAME32 255 - #define TH32CS_SNAPMODULE 0x00000008 - #pragma pack( push, 8 ) - typedef struct tagMODULEENTRY32 - { - DWORD dwSize; - DWORD th32ModuleID; // This module - DWORD th32ProcessID; // owning process - DWORD GlblcntUsage; // Global usage count on the module - DWORD ProccntUsage; // Module usage count in th32ProcessID's context - BYTE * modBaseAddr; // Base address of module in th32ProcessID's context - DWORD modBaseSize; // Size in bytes of module starting at modBaseAddr - HMODULE hModule; // The hModule of this module in th32ProcessID's context - char szModule[MAX_MODULE_NAME32 + 1]; - char szExePath[MAX_PATH]; - } MODULEENTRY32; - typedef MODULEENTRY32 * PMODULEENTRY32; - typedef MODULEENTRY32 * LPMODULEENTRY32; - #pragma pack( pop ) - - BOOL GetModuleListTH32(HANDLE hProcess, DWORD pid) - { - // CreateToolhelp32Snapshot() - typedef HANDLE (__stdcall *tCT32S)(DWORD dwFlags, DWORD th32ProcessID); - // Module32First() - typedef BOOL (__stdcall *tM32F)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); - // Module32Next() - typedef BOOL (__stdcall *tM32N)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); - - // try both dlls... - const TCHAR *dllname[] = { _T("kernel32.dll"), _T("tlhelp32.dll") }; - HINSTANCE hToolhelp = NULL; - tCT32S pCT32S = NULL; - tM32F pM32F = NULL; - tM32N pM32N = NULL; - - HANDLE hSnap; - MODULEENTRY32 me; - me.dwSize = sizeof(me); - BOOL keepGoing; - size_t i; - - for (i = 0; i<(sizeof(dllname) / sizeof(dllname[0])); i++ ) - { - hToolhelp = LoadLibrary( dllname[i] ); - if (hToolhelp == NULL) - continue; - pCT32S = (tCT32S) GetProcAddress(hToolhelp, "CreateToolhelp32Snapshot"); - pM32F = (tM32F) GetProcAddress(hToolhelp, "Module32First"); - pM32N = (tM32N) GetProcAddress(hToolhelp, "Module32Next"); - if ( (pCT32S != NULL) && (pM32F != NULL) && (pM32N != NULL) ) - break; // found the functions! - FreeLibrary(hToolhelp); - hToolhelp = NULL; - } - - if (hToolhelp == NULL) - return FALSE; - - hSnap = pCT32S( TH32CS_SNAPMODULE, pid ); - if (hSnap == (HANDLE) -1) - { - FreeLibrary(hToolhelp); - return FALSE; - } - - keepGoing = !!pM32F( hSnap, &me ); - int cnt = 0; - while (keepGoing) - { - this->LoadModule(hProcess, me.szExePath, me.szModule, (DWORD64) me.modBaseAddr, me.modBaseSize); - cnt++; - keepGoing = !!pM32N( hSnap, &me ); - } - CloseHandle(hSnap); - FreeLibrary(hToolhelp); - if (cnt <= 0) - return FALSE; - return TRUE; - } // GetModuleListTH32 - - // **************************************** PSAPI ************************ - typedef struct _MODULEINFO { - LPVOID lpBaseOfDll; - DWORD SizeOfImage; - LPVOID EntryPoint; - } MODULEINFO, *LPMODULEINFO; - - BOOL GetModuleListPSAPI(HANDLE hProcess) - { - // EnumProcessModules() - typedef BOOL (__stdcall *tEPM)(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded ); - // GetModuleFileNameEx() - typedef DWORD (__stdcall *tGMFNE)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize ); - // GetModuleBaseName() - typedef DWORD (__stdcall *tGMBN)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize ); - // GetModuleInformation() - typedef BOOL (__stdcall *tGMI)(HANDLE hProcess, HMODULE hModule, LPMODULEINFO pmi, DWORD nSize ); - - HINSTANCE hPsapi; - tEPM pEPM; - tGMFNE pGMFNE; - tGMBN pGMBN; - tGMI pGMI; - - DWORD i; - //ModuleEntry e; - DWORD cbNeeded; - MODULEINFO mi; - HMODULE *hMods = 0; - char *tt = NULL; - char *tt2 = NULL; - const SIZE_T TTBUFLEN = 8096; - int cnt = 0; - - hPsapi = LoadLibrary( _T("psapi.dll") ); - if (hPsapi == NULL) - return FALSE; - - pEPM = (tEPM) GetProcAddress( hPsapi, "EnumProcessModules" ); - pGMFNE = (tGMFNE) GetProcAddress( hPsapi, "GetModuleFileNameExA" ); - pGMBN = (tGMFNE) GetProcAddress( hPsapi, "GetModuleBaseNameA" ); - pGMI = (tGMI) GetProcAddress( hPsapi, "GetModuleInformation" ); - if ( (pEPM == NULL) || (pGMFNE == NULL) || (pGMBN == NULL) || (pGMI == NULL) ) - { - // we couldn´t find all functions - FreeLibrary(hPsapi); - return FALSE; - } - - hMods = (HMODULE*) malloc(sizeof(HMODULE) * (TTBUFLEN / sizeof HMODULE)); - tt = (char*) malloc(sizeof(char) * TTBUFLEN); - tt2 = (char*) malloc(sizeof(char) * TTBUFLEN); - if ( (hMods == NULL) || (tt == NULL) || (tt2 == NULL) ) - goto cleanup; - - if ( ! pEPM( hProcess, hMods, TTBUFLEN, &cbNeeded ) ) - { - //_ftprintf(fLogFile, _T("%lu: EPM failed, GetLastError = %lu\n"), g_dwShowCount, gle ); - goto cleanup; - } - - if ( cbNeeded > TTBUFLEN ) - { - //_ftprintf(fLogFile, _T("%lu: More than %lu module handles. Huh?\n"), g_dwShowCount, lenof( hMods ) ); - goto cleanup; - } - - for ( i = 0; i < cbNeeded / sizeof hMods[0]; i++ ) - { - // base address, size - pGMI(hProcess, hMods[i], &mi, sizeof mi ); - // image file name - tt[0] = 0; - pGMFNE(hProcess, hMods[i], tt, TTBUFLEN ); - // module name - tt2[0] = 0; - pGMBN(hProcess, hMods[i], tt2, TTBUFLEN ); - - DWORD dwRes = this->LoadModule(hProcess, tt, tt2, (DWORD64) mi.lpBaseOfDll, mi.SizeOfImage); - if (dwRes != ERROR_SUCCESS) - this->m_parent->OnDbgHelpErr("LoadModule", dwRes, 0); - cnt++; - } - - cleanup: - if (hPsapi != NULL) FreeLibrary(hPsapi); - if (tt2 != NULL) free(tt2); - if (tt != NULL) free(tt); - if (hMods != NULL) free(hMods); - - return cnt != 0; - } // GetModuleListPSAPI - - DWORD LoadModule(HANDLE hProcess, LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size) - { - CHAR *szImg = _strdup(img); - CHAR *szMod = _strdup(mod); - DWORD result = ERROR_SUCCESS; - if ( (szImg == NULL) || (szMod == NULL) ) - result = ERROR_NOT_ENOUGH_MEMORY; - else - { - if (pSLM(hProcess, 0, szImg, szMod, baseAddr, size) == 0) - result = GetLastError(); - } - ULONGLONG fileVersion = 0; - if ( (m_parent != NULL) && (szImg != NULL) ) - { - // try to retrive the file-version: - if ( (this->m_parent->m_options & StackWalker::RetrieveFileVersion) != 0) - { - VS_FIXEDFILEINFO *fInfo = NULL; - DWORD dwHandle; - DWORD dwSize = GetFileVersionInfoSizeA(szImg, &dwHandle); - if (dwSize > 0) - { - LPVOID vData = malloc(dwSize); - if (vData != NULL) - { - if (GetFileVersionInfoA(szImg, dwHandle, dwSize, vData) != 0) - { - UINT len; - TCHAR szSubBlock[] = _T("\\"); - if (VerQueryValue(vData, szSubBlock, (LPVOID*) &fInfo, &len) == 0) - fInfo = NULL; - else - { - fileVersion = ((ULONGLONG)fInfo->dwFileVersionLS) + ((ULONGLONG)fInfo->dwFileVersionMS << 32); - } - } - free(vData); - } - } - } - - // Retrive some additional-infos about the module - IMAGEHLP_MODULE64_V2 Module; - const char *szSymType = "-unknown-"; - if (this->GetModuleInfo(hProcess, baseAddr, &Module) != FALSE) - { - switch(Module.SymType) - { - case SymNone: - szSymType = "-nosymbols-"; - break; - case SymCoff: // 1 - szSymType = "COFF"; - break; - case SymCv: // 2 - szSymType = "CV"; - break; - case SymPdb: // 3 - szSymType = "PDB"; - break; - case SymExport: // 4 - szSymType = "-exported-"; - break; - case SymDeferred: // 5 - szSymType = "-deferred-"; - break; - case SymSym: // 6 - szSymType = "SYM"; - break; - case 7: // SymDia: - szSymType = "DIA"; - break; - case 8: //SymVirtual: - szSymType = "Virtual"; - break; - } - } - this->m_parent->OnLoadModule(img, mod, baseAddr, size, result, szSymType, Module.LoadedImageName, fileVersion); - } - if (szImg != NULL) free(szImg); - if (szMod != NULL) free(szMod); - return result; - } -public: - BOOL LoadModules(HANDLE hProcess, DWORD dwProcessId) - { - // first try toolhelp32 - if (GetModuleListTH32(hProcess, dwProcessId)) - return true; - // then try psapi - return GetModuleListPSAPI(hProcess); - } - - - BOOL GetModuleInfo(HANDLE hProcess, DWORD64 baseAddr, IMAGEHLP_MODULE64_V2 *pModuleInfo) - { - if(this->pSGMI == NULL) - { - SetLastError(ERROR_DLL_INIT_FAILED); - return FALSE; - } - // First try to use the larger ModuleInfo-Structure -// memset(pModuleInfo, 0, sizeof(IMAGEHLP_MODULE64_V3)); -// pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V3); -// if (this->pSGMI_V3 != NULL) -// { -// if (this->pSGMI_V3(hProcess, baseAddr, pModuleInfo) != FALSE) -// return TRUE; -// // check if the parameter was wrong (size is bad...) -// if (GetLastError() != ERROR_INVALID_PARAMETER) -// return FALSE; -// } - // could not retrive the bigger structure, try with the smaller one (as defined in VC7.1)... - pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2); - void *pData = malloc(4096); // reserve enough memory, so the bug in v6.3.5.1 does not lead to memory-overwrites... - if (pData == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - memcpy(pData, pModuleInfo, sizeof(IMAGEHLP_MODULE64_V2)); - if (this->pSGMI(hProcess, baseAddr, (IMAGEHLP_MODULE64_V2*) pData) != FALSE) - { - // only copy as much memory as is reserved... - memcpy(pModuleInfo, pData, sizeof(IMAGEHLP_MODULE64_V2)); - pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2); - free(pData); - return TRUE; - } - free(pData); - SetLastError(ERROR_DLL_INIT_FAILED); - return FALSE; - } -}; - -// ############################################################# -StackWalker::StackWalker(DWORD dwProcessId, HANDLE hProcess) -{ - this->m_options = OptionsAll; - this->m_modulesLoaded = FALSE; - this->m_hProcess = hProcess; - this->m_sw = new StackWalkerInternal(this, this->m_hProcess); - this->m_dwProcessId = dwProcessId; - this->m_szSymPath = NULL; - this->m_MaxRecursionCount = 1000; -} -StackWalker::StackWalker(int options, LPCSTR szSymPath, DWORD dwProcessId, HANDLE hProcess) -{ - this->m_options = options; - this->m_modulesLoaded = FALSE; - this->m_hProcess = hProcess; - this->m_sw = new StackWalkerInternal(this, this->m_hProcess); - this->m_dwProcessId = dwProcessId; - if (szSymPath != NULL) - { - this->m_szSymPath = _strdup(szSymPath); - this->m_options |= SymBuildPath; - } - else - this->m_szSymPath = NULL; - this->m_MaxRecursionCount = 1000; -} - -StackWalker::~StackWalker() -{ - if (m_szSymPath != NULL) - free(m_szSymPath); - m_szSymPath = NULL; - if (this->m_sw != NULL) - delete this->m_sw; - this->m_sw = NULL; -} - -BOOL StackWalker::LoadModules() -{ - if (this->m_sw == NULL) - { - SetLastError(ERROR_DLL_INIT_FAILED); - return FALSE; - } - if (m_modulesLoaded != FALSE) - return TRUE; - - // Build the sym-path: - char *szSymPath = NULL; - if ( (this->m_options & SymBuildPath) != 0) - { - const size_t nSymPathLen = 4096; - szSymPath = (char*) malloc(nSymPathLen); - if (szSymPath == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - szSymPath[0] = 0; - // Now first add the (optional) provided sympath: - if (this->m_szSymPath != NULL) - { - strcat_s(szSymPath, nSymPathLen, this->m_szSymPath); - strcat_s(szSymPath, nSymPathLen, ";"); - } - - strcat_s(szSymPath, nSymPathLen, ".;"); - - const size_t nTempLen = 1024; - char szTemp[nTempLen]; - // Now add the current directory: - if (GetCurrentDirectoryA(nTempLen, szTemp) > 0) - { - szTemp[nTempLen-1] = 0; - strcat_s(szSymPath, nSymPathLen, szTemp); - strcat_s(szSymPath, nSymPathLen, ";"); - } - - // Now add the path for the main-module: - if (GetModuleFileNameA(NULL, szTemp, nTempLen) > 0) - { - szTemp[nTempLen-1] = 0; - for (char *p = (szTemp+strlen(szTemp)-1); p >= szTemp; --p) - { - // locate the rightmost path separator - if ( (*p == '\\') || (*p == '/') || (*p == ':') ) - { - *p = 0; - break; - } - } // for (search for path separator...) - if (strlen(szTemp) > 0) - { - strcat_s(szSymPath, nSymPathLen, szTemp); - strcat_s(szSymPath, nSymPathLen, ";"); - } - } - if (GetEnvironmentVariableA("_NT_SYMBOL_PATH", szTemp, nTempLen) > 0) - { - szTemp[nTempLen-1] = 0; - strcat_s(szSymPath, nSymPathLen, szTemp); - strcat_s(szSymPath, nSymPathLen, ";"); - } - if (GetEnvironmentVariableA("_NT_ALTERNATE_SYMBOL_PATH", szTemp, nTempLen) > 0) - { - szTemp[nTempLen-1] = 0; - strcat_s(szSymPath, nSymPathLen, szTemp); - strcat_s(szSymPath, nSymPathLen, ";"); - } - if (GetEnvironmentVariableA("SYSTEMROOT", szTemp, nTempLen) > 0) - { - szTemp[nTempLen-1] = 0; - strcat_s(szSymPath, nSymPathLen, szTemp); - strcat_s(szSymPath, nSymPathLen, ";"); - // also add the "system32"-directory: - strcat_s(szTemp, nTempLen, "\\system32"); - strcat_s(szSymPath, nSymPathLen, szTemp); - strcat_s(szSymPath, nSymPathLen, ";"); - } - - if ( (this->m_options & SymUseSymSrv) != 0) - { - if (GetEnvironmentVariableA("SYSTEMDRIVE", szTemp, nTempLen) > 0) - { - szTemp[nTempLen-1] = 0; - strcat_s(szSymPath, nSymPathLen, "SRV*"); - strcat_s(szSymPath, nSymPathLen, szTemp); - strcat_s(szSymPath, nSymPathLen, "\\websymbols"); - strcat_s(szSymPath, nSymPathLen, "*http://msdl.microsoft.com/download/symbols;"); - } - else - strcat_s(szSymPath, nSymPathLen, "SRV*c:\\websymbols*http://msdl.microsoft.com/download/symbols;"); - } - } // if SymBuildPath - - // First Init the whole stuff... - BOOL bRet = this->m_sw->Init(szSymPath); - if (szSymPath != NULL) free(szSymPath); szSymPath = NULL; - if (bRet == FALSE) - { - this->OnDbgHelpErr("Error while initializing dbghelp.dll", 0, 0); - SetLastError(ERROR_DLL_INIT_FAILED); - return FALSE; - } - - bRet = this->m_sw->LoadModules(this->m_hProcess, this->m_dwProcessId); - if (bRet != FALSE) - m_modulesLoaded = TRUE; - return bRet; -} - - -// The following is used to pass the "userData"-Pointer to the user-provided readMemoryFunction -// This has to be done due to a problem with the "hProcess"-parameter in x64... -// Because this class is in no case multi-threading-enabled (because of the limitations -// of dbghelp.dll) it is "safe" to use a static-variable -static StackWalker::PReadProcessMemoryRoutine s_readMemoryFunction = NULL; -static LPVOID s_readMemoryFunction_UserData = NULL; - -BOOL StackWalker::ShowCallstack(HANDLE hThread, const CONTEXT *context, PReadProcessMemoryRoutine readMemoryFunction, LPVOID pUserData) -{ - CONTEXT c; - CallstackEntry csEntry; - IMAGEHLP_SYMBOL64 *pSym = NULL; - StackWalkerInternal::IMAGEHLP_MODULE64_V2 Module; - IMAGEHLP_LINE64 Line; - int frameNum; - bool bLastEntryCalled = true; - int curRecursionCount = 0; - - if (m_modulesLoaded == FALSE) - this->LoadModules(); // ignore the result... - - if (this->m_sw->m_hDbhHelp == NULL) - { - SetLastError(ERROR_DLL_INIT_FAILED); - return FALSE; - } - - s_readMemoryFunction = readMemoryFunction; - s_readMemoryFunction_UserData = pUserData; - - if (context == NULL) - { - // If no context is provided, capture the context - if (hThread == GetCurrentThread()) - { - GET_CURRENT_CONTEXT(c, USED_CONTEXT_FLAGS); - } - else - { - SuspendThread(hThread); - memset(&c, 0, sizeof(CONTEXT)); - c.ContextFlags = USED_CONTEXT_FLAGS; - if (GetThreadContext(hThread, &c) == FALSE) - { - ResumeThread(hThread); - return FALSE; - } - } - } - else - c = *context; - - // init STACKFRAME for first call - STACKFRAME64 s; // in/out stackframe - memset(&s, 0, sizeof(s)); - DWORD imageType; -#ifdef _M_IX86 - // normally, call ImageNtHeader() and use machine info from PE header - imageType = IMAGE_FILE_MACHINE_I386; - s.AddrPC.Offset = c.Eip; - s.AddrPC.Mode = AddrModeFlat; - s.AddrFrame.Offset = c.Ebp; - s.AddrFrame.Mode = AddrModeFlat; - s.AddrStack.Offset = c.Esp; - s.AddrStack.Mode = AddrModeFlat; -#elif _M_X64 - imageType = IMAGE_FILE_MACHINE_AMD64; - s.AddrPC.Offset = c.Rip; - s.AddrPC.Mode = AddrModeFlat; - s.AddrFrame.Offset = c.Rsp; - s.AddrFrame.Mode = AddrModeFlat; - s.AddrStack.Offset = c.Rsp; - s.AddrStack.Mode = AddrModeFlat; -#elif _M_IA64 - imageType = IMAGE_FILE_MACHINE_IA64; - s.AddrPC.Offset = c.StIIP; - s.AddrPC.Mode = AddrModeFlat; - s.AddrFrame.Offset = c.IntSp; - s.AddrFrame.Mode = AddrModeFlat; - s.AddrBStore.Offset = c.RsBSP; - s.AddrBStore.Mode = AddrModeFlat; - s.AddrStack.Offset = c.IntSp; - s.AddrStack.Mode = AddrModeFlat; -#else -#error "Platform not supported!" -#endif - - pSym = (IMAGEHLP_SYMBOL64 *) malloc(sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN); - if (!pSym) goto cleanup; // not enough memory... - memset(pSym, 0, sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN); - pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); - pSym->MaxNameLength = STACKWALK_MAX_NAMELEN; - - memset(&Line, 0, sizeof(Line)); - Line.SizeOfStruct = sizeof(Line); - - memset(&Module, 0, sizeof(Module)); - Module.SizeOfStruct = sizeof(Module); - - for (frameNum = 0; ; ++frameNum ) - { - // get next stack frame (StackWalk64(), SymFunctionTableAccess64(), SymGetModuleBase64()) - // if this returns ERROR_INVALID_ADDRESS (487) or ERROR_NOACCESS (998), you can - // assume that either you are done, or that the stack is so hosed that the next - // deeper frame could not be found. - // CONTEXT need not to be suplied if imageTyp is IMAGE_FILE_MACHINE_I386! - if ( ! this->m_sw->pSW(imageType, this->m_hProcess, hThread, &s, &c, myReadProcMem, this->m_sw->pSFTA, this->m_sw->pSGMB, NULL) ) - { - // INFO: "StackWalk64" does not set "GetLastError"... - this->OnDbgHelpErr("StackWalk64", 0, s.AddrPC.Offset); - break; - } - - csEntry.offset = s.AddrPC.Offset; - csEntry.name[0] = 0; - csEntry.undName[0] = 0; - csEntry.undFullName[0] = 0; - csEntry.offsetFromSmybol = 0; - csEntry.offsetFromLine = 0; - csEntry.lineFileName[0] = 0; - csEntry.lineNumber = 0; - csEntry.loadedImageName[0] = 0; - csEntry.moduleName[0] = 0; - if (s.AddrPC.Offset == s.AddrReturn.Offset) - { - if ( (this->m_MaxRecursionCount > 0) && (curRecursionCount > m_MaxRecursionCount) ) - { - this->OnDbgHelpErr("StackWalk64-Endless-Callstack!", 0, s.AddrPC.Offset); - break; - } - curRecursionCount++; - } - else - curRecursionCount = 0; - if (s.AddrPC.Offset != 0) - { - // we seem to have a valid PC - // show procedure info (SymGetSymFromAddr64()) - if (this->m_sw->pSGSFA(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromSmybol), pSym) != FALSE) - { - MyStrCpy(csEntry.name, STACKWALK_MAX_NAMELEN, pSym->Name); - // UnDecorateSymbolName() - this->m_sw->pUDSN( pSym->Name, csEntry.undName, STACKWALK_MAX_NAMELEN, UNDNAME_NAME_ONLY ); - this->m_sw->pUDSN( pSym->Name, csEntry.undFullName, STACKWALK_MAX_NAMELEN, UNDNAME_COMPLETE ); - } - else - { - this->OnDbgHelpErr("SymGetSymFromAddr64", GetLastError(), s.AddrPC.Offset); - } - - // show line number info, NT5.0-method (SymGetLineFromAddr64()) - if (this->m_sw->pSGLFA != NULL ) - { // yes, we have SymGetLineFromAddr64() - if (this->m_sw->pSGLFA(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromLine), &Line) != FALSE) - { - csEntry.lineNumber = Line.LineNumber; - MyStrCpy(csEntry.lineFileName, STACKWALK_MAX_NAMELEN, Line.FileName); - } - else - { - this->OnDbgHelpErr("SymGetLineFromAddr64", GetLastError(), s.AddrPC.Offset); - } - } // yes, we have SymGetLineFromAddr64() - - // show module info (SymGetModuleInfo64()) - if (this->m_sw->GetModuleInfo(this->m_hProcess, s.AddrPC.Offset, &Module ) != FALSE) - { // got module info OK - switch ( Module.SymType ) - { - case SymNone: - csEntry.symTypeString = "-nosymbols-"; - break; - case SymCoff: - csEntry.symTypeString = "COFF"; - break; - case SymCv: - csEntry.symTypeString = "CV"; - break; - case SymPdb: - csEntry.symTypeString = "PDB"; - break; - case SymExport: - csEntry.symTypeString = "-exported-"; - break; - case SymDeferred: - csEntry.symTypeString = "-deferred-"; - break; - case SymSym: - csEntry.symTypeString = "SYM"; - break; -#if API_VERSION_NUMBER >= 9 - case SymDia: - csEntry.symTypeString = "DIA"; - break; -#endif - case 8: //SymVirtual: - csEntry.symTypeString = "Virtual"; - break; - default: - //_snprintf( ty, sizeof ty, "symtype=%ld", (long) Module.SymType ); - csEntry.symTypeString = NULL; - break; - } - - // TODO: Mache dies sicher...! - MyStrCpy(csEntry.moduleName, STACKWALK_MAX_NAMELEN, Module.ModuleName); - csEntry.baseOfImage = Module.BaseOfImage; - MyStrCpy(csEntry.loadedImageName, STACKWALK_MAX_NAMELEN, Module.LoadedImageName); - } // got module info OK - else - { - this->OnDbgHelpErr("SymGetModuleInfo64", GetLastError(), s.AddrPC.Offset); - } - } // we seem to have a valid PC - - CallstackEntryType et = nextEntry; - if (frameNum == 0) - et = firstEntry; - bLastEntryCalled = false; - this->OnCallstackEntry(et, csEntry); - - if (s.AddrReturn.Offset == 0) - { - bLastEntryCalled = true; - this->OnCallstackEntry(lastEntry, csEntry); - SetLastError(ERROR_SUCCESS); - break; - } - } // for ( frameNum ) - - cleanup: - if (pSym) free( pSym ); - - if (bLastEntryCalled == false) - this->OnCallstackEntry(lastEntry, csEntry); - - if (context == NULL) - ResumeThread(hThread); - - return TRUE; -} - -BOOL __stdcall StackWalker::myReadProcMem( - HANDLE hProcess, - DWORD64 qwBaseAddress, - PVOID lpBuffer, - DWORD nSize, - LPDWORD lpNumberOfBytesRead - ) -{ - if (s_readMemoryFunction == NULL) - { - SIZE_T st; - BOOL bRet = ReadProcessMemory(hProcess, (LPVOID) qwBaseAddress, lpBuffer, nSize, &st); - *lpNumberOfBytesRead = (DWORD) st; - //printf("ReadMemory: hProcess: %p, baseAddr: %p, buffer: %p, size: %d, read: %d, result: %d\n", hProcess, (LPVOID) qwBaseAddress, lpBuffer, nSize, (DWORD) st, (DWORD) bRet); - return bRet; - } - else - { - return s_readMemoryFunction(hProcess, qwBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead, s_readMemoryFunction_UserData); - } -} - -void StackWalker::OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion) -{ - CHAR buffer[STACKWALK_MAX_NAMELEN]; - if (fileVersion == 0) - _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s'\n", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName); - else - { - DWORD v4 = (DWORD) fileVersion & 0xFFFF; - DWORD v3 = (DWORD) (fileVersion>>16) & 0xFFFF; - DWORD v2 = (DWORD) (fileVersion>>32) & 0xFFFF; - DWORD v1 = (DWORD) (fileVersion>>48) & 0xFFFF; - _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s', fileVersion: %d.%d.%d.%d\n", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName, v1, v2, v3, v4); - } - OnOutput(buffer); -} - -void StackWalker::OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry) -{ - CHAR buffer[STACKWALK_MAX_NAMELEN]; - if ( (eType != lastEntry) && (entry.offset != 0) ) - { - if (entry.name[0] == 0) - MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, "(function-name not available)"); - if (entry.undName[0] != 0) - MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, entry.undName); - if (entry.undFullName[0] != 0) - MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, entry.undFullName); - if (entry.lineFileName[0] == 0) - { - MyStrCpy(entry.lineFileName, STACKWALK_MAX_NAMELEN, "(filename not available)"); - if (entry.moduleName[0] == 0) - MyStrCpy(entry.moduleName, STACKWALK_MAX_NAMELEN, "(module-name not available)"); - _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%p (%s): %s: %s\n", (LPVOID) entry.offset, entry.moduleName, entry.lineFileName, entry.name); - } - else - _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s (%d): %s\n", entry.lineFileName, entry.lineNumber, entry.name); - buffer[STACKWALK_MAX_NAMELEN-1] = 0; - OnOutput(buffer); - } -} - -void StackWalker::OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr) -{ - CHAR buffer[STACKWALK_MAX_NAMELEN]; - _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "ERROR: %s, GetLastError: %d (Address: %p)\n", szFuncName, gle, (LPVOID) addr); - OnOutput(buffer); -} - -void StackWalker::OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName) -{ - CHAR buffer[STACKWALK_MAX_NAMELEN]; - _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "SymInit: Symbol-SearchPath: '%s', symOptions: %d, UserName: '%s'\n", szSearchPath, symOptions, szUserName); - OnOutput(buffer); - // Also display the OS-version -#if _MSC_VER <= 1200 - OSVERSIONINFOA ver; - ZeroMemory(&ver, sizeof(OSVERSIONINFOA)); - ver.dwOSVersionInfoSize = sizeof(ver); - if (GetVersionExA(&ver) != FALSE) - { - _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "OS-Version: %d.%d.%d (%s)\n", - ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber, - ver.szCSDVersion); - OnOutput(buffer); - } -#else - OSVERSIONINFOEXA ver; - ZeroMemory(&ver, sizeof(OSVERSIONINFOEXA)); - ver.dwOSVersionInfoSize = sizeof(ver); - if (GetVersionExA( (OSVERSIONINFOA*) &ver) != FALSE) - { - _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "OS-Version: %d.%d.%d (%s) 0x%x-0x%x\n", - ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber, - ver.szCSDVersion, ver.wSuiteMask, ver.wProductType); - OnOutput(buffer); - } -#endif -} - -void StackWalker::OnOutput(LPCSTR buffer) -{ - OutputDebugStringA(buffer); -} +/********************************************************************** + * + * StackWalker.cpp + * + * + * History: + * 2005-07-27 v1 - First public release on http://www.codeproject.com/ + * http://www.codeproject.com/threads/StackWalker.asp + * 2005-07-28 v2 - Changed the params of the constructor and ShowCallstack + * (to simplify the usage) + * 2005-08-01 v3 - Changed to use 'CONTEXT_FULL' instead of CONTEXT_ALL + * (should also be enough) + * - Changed to compile correctly with the PSDK of VC7.0 + * (GetFileVersionInfoSizeA and GetFileVersionInfoA is wrongly defined: + * it uses LPSTR instead of LPCSTR as first paremeter) + * - Added declarations to support VC5/6 without using 'dbghelp.h' + * - Added a 'pUserData' member to the ShowCallstack function and the + * PReadProcessMemoryRoutine declaration (to pass some user-defined data, + * which can be used in the readMemoryFunction-callback) + * 2005-08-02 v4 - OnSymInit now also outputs the OS-Version by default + * - Added example for doing an exception-callstack-walking in main.cpp + * (thanks to owillebo: http://www.codeproject.com/script/profile/whos_who.asp?id=536268) + * 2005-08-05 v5 - Removed most Lint (http://www.gimpel.com/) errors... thanks to Okko Willeboordse! + * 2008-08-04 v6 - Fixed Bug: Missing LEAK-end-tag + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=2502890#xx2502890xx + * Fixed Bug: Compiled with "WIN32_LEAN_AND_MEAN" + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=1824718#xx1824718xx + * Fixed Bug: Compiling with "/Wall" + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=2638243#xx2638243xx + * Fixed Bug: Now checking SymUseSymSrv + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1388979#xx1388979xx + * Fixed Bug: Support for recursive function calls + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1434538#xx1434538xx + * Fixed Bug: Missing FreeLibrary call in "GetModuleListTH32" + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1326923#xx1326923xx + * Fixed Bug: SymDia is number 7, not 9! + * 2008-09-11 v7 For some (undocumented) reason, dbhelp.h is needing a packing of 8! + * Thanks to Teajay which reported the bug... + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=2718933#xx2718933xx + * 2008-11-27 v8 Debugging Tools for Windows are now stored in a different directory + * Thanks to Luiz Salamon which reported this "bug"... + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=2822736#xx2822736xx + * 2009-04-10 v9 License slihtly corrected ( replaced) + * 2010-04-15 v10 Added support for VS2010 RTM + * 2010-05-2ß v11 Now using secure MyStrcCpy. Thanks to luke.simon: + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=3477467#xx3477467xx + * + * LICENSE (http://www.opensource.org/licenses/bsd-license.php) + * + * Copyright (c) 2005-2010, Jochen Kalmbach + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of Jochen Kalmbach nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ +#include +#include +#include +#include +#pragma comment(lib, "version.lib") // for "VerQueryValue" +#pragma warning(disable:4826) + +#include "StackWalker.h" + + +// If VC7 and later, then use the shipped 'dbghelp.h'-file +#pragma pack(push,8) +#if _MSC_VER >= 1300 +#include +#else +// inline the important dbghelp.h-declarations... +typedef enum { + SymNone = 0, + SymCoff, + SymCv, + SymPdb, + SymExport, + SymDeferred, + SymSym, + SymDia, + SymVirtual, + NumSymTypes +} SYM_TYPE; +typedef struct _IMAGEHLP_LINE64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) + PVOID Key; // internal + DWORD LineNumber; // line number in file + PCHAR FileName; // full filename + DWORD64 Address; // first instruction of line +} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64; +typedef struct _IMAGEHLP_MODULE64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) + DWORD64 BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + CHAR ModuleName[32]; // module name + CHAR ImageName[256]; // image name + CHAR LoadedImageName[256]; // symbol file name +} IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64; +typedef struct _IMAGEHLP_SYMBOL64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL64) + DWORD64 Address; // virtual address including dll base address + DWORD Size; // estimated size of symbol, can be zero + DWORD Flags; // info about the symbols, see the SYMF defines + DWORD MaxNameLength; // maximum size of symbol name in 'Name' + CHAR Name[1]; // symbol name (null terminated string) +} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64; +typedef enum { + AddrMode1616, + AddrMode1632, + AddrModeReal, + AddrModeFlat +} ADDRESS_MODE; +typedef struct _tagADDRESS64 { + DWORD64 Offset; + WORD Segment; + ADDRESS_MODE Mode; +} ADDRESS64, *LPADDRESS64; +typedef struct _KDHELP64 { + DWORD64 Thread; + DWORD ThCallbackStack; + DWORD ThCallbackBStore; + DWORD NextCallback; + DWORD FramePointer; + DWORD64 KiCallUserMode; + DWORD64 KeUserCallbackDispatcher; + DWORD64 SystemRangeStart; + DWORD64 Reserved[8]; +} KDHELP64, *PKDHELP64; +typedef struct _tagSTACKFRAME64 { + ADDRESS64 AddrPC; // program counter + ADDRESS64 AddrReturn; // return address + ADDRESS64 AddrFrame; // frame pointer + ADDRESS64 AddrStack; // stack pointer + ADDRESS64 AddrBStore; // backing store pointer + PVOID FuncTableEntry; // pointer to pdata/fpo or NULL + DWORD64 Params[4]; // possible arguments to the function + BOOL Far; // WOW far call + BOOL Virtual; // is this a virtual frame? + DWORD64 Reserved[3]; + KDHELP64 KdHelp; +} STACKFRAME64, *LPSTACKFRAME64; +typedef +BOOL +(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)( + HANDLE hProcess, + DWORD64 qwBaseAddress, + PVOID lpBuffer, + DWORD nSize, + LPDWORD lpNumberOfBytesRead + ); +typedef +PVOID +(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)( + HANDLE hProcess, + DWORD64 AddrBase + ); +typedef +DWORD64 +(__stdcall *PGET_MODULE_BASE_ROUTINE64)( + HANDLE hProcess, + DWORD64 Address + ); +typedef +DWORD64 +(__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)( + HANDLE hProcess, + HANDLE hThread, + LPADDRESS64 lpaddr + ); +#define SYMOPT_CASE_INSENSITIVE 0x00000001 +#define SYMOPT_UNDNAME 0x00000002 +#define SYMOPT_DEFERRED_LOADS 0x00000004 +#define SYMOPT_NO_CPP 0x00000008 +#define SYMOPT_LOAD_LINES 0x00000010 +#define SYMOPT_OMAP_FIND_NEAREST 0x00000020 +#define SYMOPT_LOAD_ANYTHING 0x00000040 +#define SYMOPT_IGNORE_CVREC 0x00000080 +#define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100 +#define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200 +#define SYMOPT_EXACT_SYMBOLS 0x00000400 +#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800 +#define SYMOPT_IGNORE_NT_SYMPATH 0x00001000 +#define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000 +#define SYMOPT_PUBLICS_ONLY 0x00004000 +#define SYMOPT_NO_PUBLICS 0x00008000 +#define SYMOPT_AUTO_PUBLICS 0x00010000 +#define SYMOPT_NO_IMAGE_SEARCH 0x00020000 +#define SYMOPT_SECURE 0x00040000 +#define SYMOPT_DEBUG 0x80000000 +#define UNDNAME_COMPLETE (0x0000) // Enable full undecoration +#define UNDNAME_NAME_ONLY (0x1000) // Crack only the name for primary declaration; +#endif // _MSC_VER < 1300 +#pragma pack(pop) + +// Some missing defines (for VC5/6): +#ifndef INVALID_FILE_ATTRIBUTES +#define INVALID_FILE_ATTRIBUTES ((DWORD)-1) +#endif + + +// secure-CRT_functions are only available starting with VC8 +#if _MSC_VER < 1400 +#define strcpy_s strcpy +#define strncpy_s strncpy +#define strcat_s(dst, len, src) strcat(dst, src) +#define _snprintf_s _snprintf +#define _tcscat_s _tcscat +#endif + +static void MyStrCpy(char* szDest, size_t nMaxDestSize, const char* szSrc) +{ + if (nMaxDestSize <= 0) return; + if (strlen(szSrc) < nMaxDestSize) + { + strcpy_s(szDest, nMaxDestSize, szSrc); + } + else + { + strncpy_s(szDest, nMaxDestSize, szSrc, nMaxDestSize); + szDest[nMaxDestSize-1] = 0; + } +} // MyStrCpy + +// Normally it should be enough to use 'CONTEXT_FULL' (better would be 'CONTEXT_ALL') +#define USED_CONTEXT_FLAGS CONTEXT_FULL + + +class StackWalkerInternal +{ +public: + StackWalkerInternal(StackWalker *parent, HANDLE hProcess) + { + m_parent = parent; + m_hDbhHelp = NULL; + pSC = NULL; + m_hProcess = hProcess; + m_szSymPath = NULL; + pSFTA = NULL; + pSGLFA = NULL; + pSGMB = NULL; + pSGMI = NULL; + pSGO = NULL; + pSGSFA = NULL; + pSI = NULL; + pSLM = NULL; + pSSO = NULL; + pSW = NULL; + pUDSN = NULL; + pSGSP = NULL; + } + ~StackWalkerInternal() + { + if (pSC != NULL) + pSC(m_hProcess); // SymCleanup + if (m_hDbhHelp != NULL) + FreeLibrary(m_hDbhHelp); + m_hDbhHelp = NULL; + m_parent = NULL; + if(m_szSymPath != NULL) + free(m_szSymPath); + m_szSymPath = NULL; + } + BOOL Init(LPCSTR szSymPath) + { + if (m_parent == NULL) + return FALSE; + // Dynamically load the Entry-Points for dbghelp.dll: + // First try to load the newsest one from + TCHAR szTemp[4096]; + // But before wqe do this, we first check if the ".local" file exists + if (GetModuleFileName(NULL, szTemp, 4096) > 0) + { + _tcscat_s(szTemp, _T(".local")); + if (GetFileAttributes(szTemp) == INVALID_FILE_ATTRIBUTES) + { + // ".local" file does not exist, so we can try to load the dbghelp.dll from the "Debugging Tools for Windows" + // Ok, first try the new path according to the archtitecture: +#ifdef _M_IX86 + if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) + { + _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (x86)\\dbghelp.dll")); + // now check if the file exists: + if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) + { + m_hDbhHelp = LoadLibrary(szTemp); + } + } +#elif _M_X64 + if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) + { + _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (x64)\\dbghelp.dll")); + // now check if the file exists: + if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) + { + m_hDbhHelp = LoadLibrary(szTemp); + } + } +#elif _M_IA64 + if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) + { + _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (ia64)\\dbghelp.dll")); + // now check if the file exists: + if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) + { + m_hDbhHelp = LoadLibrary(szTemp); + } + } +#endif + // If still not found, try the old directories... + if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) + { + _tcscat_s(szTemp, _T("\\Debugging Tools for Windows\\dbghelp.dll")); + // now check if the file exists: + if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) + { + m_hDbhHelp = LoadLibrary(szTemp); + } + } +#if defined _M_X64 || defined _M_IA64 + // Still not found? Then try to load the (old) 64-Bit version: + if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) + { + _tcscat_s(szTemp, _T("\\Debugging Tools for Windows 64-Bit\\dbghelp.dll")); + if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) + { + m_hDbhHelp = LoadLibrary(szTemp); + } + } +#endif + } + } + if (m_hDbhHelp == NULL) // if not already loaded, try to load a default-one + m_hDbhHelp = LoadLibrary( _T("dbghelp.dll") ); + if (m_hDbhHelp == NULL) + return FALSE; + pSI = (tSI) GetProcAddress(m_hDbhHelp, "SymInitialize" ); + pSC = (tSC) GetProcAddress(m_hDbhHelp, "SymCleanup" ); + + pSW = (tSW) GetProcAddress(m_hDbhHelp, "StackWalk64" ); + pSGO = (tSGO) GetProcAddress(m_hDbhHelp, "SymGetOptions" ); + pSSO = (tSSO) GetProcAddress(m_hDbhHelp, "SymSetOptions" ); + + pSFTA = (tSFTA) GetProcAddress(m_hDbhHelp, "SymFunctionTableAccess64" ); + pSGLFA = (tSGLFA) GetProcAddress(m_hDbhHelp, "SymGetLineFromAddr64" ); + pSGMB = (tSGMB) GetProcAddress(m_hDbhHelp, "SymGetModuleBase64" ); + pSGMI = (tSGMI) GetProcAddress(m_hDbhHelp, "SymGetModuleInfo64" ); + //pSGMI_V3 = (tSGMI_V3) GetProcAddress(m_hDbhHelp, "SymGetModuleInfo64" ); + pSGSFA = (tSGSFA) GetProcAddress(m_hDbhHelp, "SymGetSymFromAddr64" ); + pUDSN = (tUDSN) GetProcAddress(m_hDbhHelp, "UnDecorateSymbolName" ); + pSLM = (tSLM) GetProcAddress(m_hDbhHelp, "SymLoadModule64" ); + pSGSP =(tSGSP) GetProcAddress(m_hDbhHelp, "SymGetSearchPath" ); + + if ( pSC == NULL || pSFTA == NULL || pSGMB == NULL || pSGMI == NULL || + pSGO == NULL || pSGSFA == NULL || pSI == NULL || pSSO == NULL || + pSW == NULL || pUDSN == NULL || pSLM == NULL ) + { + FreeLibrary(m_hDbhHelp); + m_hDbhHelp = NULL; + pSC = NULL; + return FALSE; + } + + // SymInitialize + if (szSymPath != NULL) + m_szSymPath = _strdup(szSymPath); + if (this->pSI(m_hProcess, m_szSymPath, FALSE) == FALSE) + this->m_parent->OnDbgHelpErr("SymInitialize", GetLastError(), 0); + + DWORD symOptions = this->pSGO(); // SymGetOptions + symOptions |= SYMOPT_LOAD_LINES; + symOptions |= SYMOPT_FAIL_CRITICAL_ERRORS; + //symOptions |= SYMOPT_NO_PROMPTS; + // SymSetOptions + symOptions = this->pSSO(symOptions); + + char buf[StackWalker::STACKWALK_MAX_NAMELEN] = {0}; + if (this->pSGSP != NULL) + { + if (this->pSGSP(m_hProcess, buf, StackWalker::STACKWALK_MAX_NAMELEN) == FALSE) + this->m_parent->OnDbgHelpErr("SymGetSearchPath", GetLastError(), 0); + } + char szUserName[1024] = {0}; + DWORD dwSize = 1024; + GetUserNameA(szUserName, &dwSize); + this->m_parent->OnSymInit(buf, symOptions, szUserName); + + return TRUE; + } + + StackWalker *m_parent; + + HMODULE m_hDbhHelp; + HANDLE m_hProcess; + LPSTR m_szSymPath; + +/*typedef struct IMAGEHLP_MODULE64_V3 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) + DWORD64 BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + CHAR ModuleName[32]; // module name + CHAR ImageName[256]; // image name + // new elements: 07-Jun-2002 + CHAR LoadedImageName[256]; // symbol file name + CHAR LoadedPdbName[256]; // pdb file name + DWORD CVSig; // Signature of the CV record in the debug directories + CHAR CVData[MAX_PATH * 3]; // Contents of the CV record + DWORD PdbSig; // Signature of PDB + GUID PdbSig70; // Signature of PDB (VC 7 and up) + DWORD PdbAge; // DBI age of pdb + BOOL PdbUnmatched; // loaded an unmatched pdb + BOOL DbgUnmatched; // loaded an unmatched dbg + BOOL LineNumbers; // we have line number information + BOOL GlobalSymbols; // we have internal symbol information + BOOL TypeInfo; // we have type information + // new elements: 17-Dec-2003 + BOOL SourceIndexed; // pdb supports source server + BOOL Publics; // contains public symbols +}; +*/ + +#pragma pack(push,8) +typedef struct IMAGEHLP_MODULE64_V2 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) + DWORD64 BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + CHAR ModuleName[32]; // module name + CHAR ImageName[256]; // image name + CHAR LoadedImageName[256]; // symbol file name +}; +#pragma pack(pop) + + + // SymCleanup() + typedef BOOL (__stdcall *tSC)( IN HANDLE hProcess ); + tSC pSC; + + // SymFunctionTableAccess64() + typedef PVOID (__stdcall *tSFTA)( HANDLE hProcess, DWORD64 AddrBase ); + tSFTA pSFTA; + + // SymGetLineFromAddr64() + typedef BOOL (__stdcall *tSGLFA)( IN HANDLE hProcess, IN DWORD64 dwAddr, + OUT PDWORD pdwDisplacement, OUT PIMAGEHLP_LINE64 Line ); + tSGLFA pSGLFA; + + // SymGetModuleBase64() + typedef DWORD64 (__stdcall *tSGMB)( IN HANDLE hProcess, IN DWORD64 dwAddr ); + tSGMB pSGMB; + + // SymGetModuleInfo64() + typedef BOOL (__stdcall *tSGMI)( IN HANDLE hProcess, IN DWORD64 dwAddr, OUT IMAGEHLP_MODULE64_V2 *ModuleInfo ); + tSGMI pSGMI; + +// // SymGetModuleInfo64() +// typedef BOOL (__stdcall *tSGMI_V3)( IN HANDLE hProcess, IN DWORD64 dwAddr, OUT IMAGEHLP_MODULE64_V3 *ModuleInfo ); +// tSGMI_V3 pSGMI_V3; + + // SymGetOptions() + typedef DWORD (__stdcall *tSGO)( VOID ); + tSGO pSGO; + + // SymGetSymFromAddr64() + typedef BOOL (__stdcall *tSGSFA)( IN HANDLE hProcess, IN DWORD64 dwAddr, + OUT PDWORD64 pdwDisplacement, OUT PIMAGEHLP_SYMBOL64 Symbol ); + tSGSFA pSGSFA; + + // SymInitialize() + typedef BOOL (__stdcall *tSI)( IN HANDLE hProcess, IN PSTR UserSearchPath, IN BOOL fInvadeProcess ); + tSI pSI; + + // SymLoadModule64() + typedef DWORD64 (__stdcall *tSLM)( IN HANDLE hProcess, IN HANDLE hFile, + IN PSTR ImageName, IN PSTR ModuleName, IN DWORD64 BaseOfDll, IN DWORD SizeOfDll ); + tSLM pSLM; + + // SymSetOptions() + typedef DWORD (__stdcall *tSSO)( IN DWORD SymOptions ); + tSSO pSSO; + + // StackWalk64() + typedef BOOL (__stdcall *tSW)( + DWORD MachineType, + HANDLE hProcess, + HANDLE hThread, + LPSTACKFRAME64 StackFrame, + PVOID ContextRecord, + PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, + PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, + PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, + PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress ); + tSW pSW; + + // UnDecorateSymbolName() + typedef DWORD (__stdcall WINAPI *tUDSN)( PCSTR DecoratedName, PSTR UnDecoratedName, + DWORD UndecoratedLength, DWORD Flags ); + tUDSN pUDSN; + + typedef BOOL (__stdcall WINAPI *tSGSP)(HANDLE hProcess, PSTR SearchPath, DWORD SearchPathLength); + tSGSP pSGSP; + + +private: + // **************************************** ToolHelp32 ************************ + #define MAX_MODULE_NAME32 255 + #define TH32CS_SNAPMODULE 0x00000008 + #pragma pack( push, 8 ) + typedef struct tagMODULEENTRY32 + { + DWORD dwSize; + DWORD th32ModuleID; // This module + DWORD th32ProcessID; // owning process + DWORD GlblcntUsage; // Global usage count on the module + DWORD ProccntUsage; // Module usage count in th32ProcessID's context + BYTE * modBaseAddr; // Base address of module in th32ProcessID's context + DWORD modBaseSize; // Size in bytes of module starting at modBaseAddr + HMODULE hModule; // The hModule of this module in th32ProcessID's context + char szModule[MAX_MODULE_NAME32 + 1]; + char szExePath[MAX_PATH]; + } MODULEENTRY32; + typedef MODULEENTRY32 * PMODULEENTRY32; + typedef MODULEENTRY32 * LPMODULEENTRY32; + #pragma pack( pop ) + + BOOL GetModuleListTH32(HANDLE hProcess, DWORD pid) + { + // CreateToolhelp32Snapshot() + typedef HANDLE (__stdcall *tCT32S)(DWORD dwFlags, DWORD th32ProcessID); + // Module32First() + typedef BOOL (__stdcall *tM32F)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); + // Module32Next() + typedef BOOL (__stdcall *tM32N)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); + + // try both dlls... + const TCHAR *dllname[] = { _T("kernel32.dll"), _T("tlhelp32.dll") }; + HINSTANCE hToolhelp = NULL; + tCT32S pCT32S = NULL; + tM32F pM32F = NULL; + tM32N pM32N = NULL; + + HANDLE hSnap; + MODULEENTRY32 me; + me.dwSize = sizeof(me); + BOOL keepGoing; + size_t i; + + for (i = 0; i<(sizeof(dllname) / sizeof(dllname[0])); i++ ) + { + hToolhelp = LoadLibrary( dllname[i] ); + if (hToolhelp == NULL) + continue; + pCT32S = (tCT32S) GetProcAddress(hToolhelp, "CreateToolhelp32Snapshot"); + pM32F = (tM32F) GetProcAddress(hToolhelp, "Module32First"); + pM32N = (tM32N) GetProcAddress(hToolhelp, "Module32Next"); + if ( (pCT32S != NULL) && (pM32F != NULL) && (pM32N != NULL) ) + break; // found the functions! + FreeLibrary(hToolhelp); + hToolhelp = NULL; + } + + if (hToolhelp == NULL) + return FALSE; + + hSnap = pCT32S( TH32CS_SNAPMODULE, pid ); + if (hSnap == (HANDLE) -1) + { + FreeLibrary(hToolhelp); + return FALSE; + } + + keepGoing = !!pM32F( hSnap, &me ); + int cnt = 0; + while (keepGoing) + { + this->LoadModule(hProcess, me.szExePath, me.szModule, (DWORD64) me.modBaseAddr, me.modBaseSize); + cnt++; + keepGoing = !!pM32N( hSnap, &me ); + } + CloseHandle(hSnap); + FreeLibrary(hToolhelp); + if (cnt <= 0) + return FALSE; + return TRUE; + } // GetModuleListTH32 + + // **************************************** PSAPI ************************ + typedef struct _MODULEINFO { + LPVOID lpBaseOfDll; + DWORD SizeOfImage; + LPVOID EntryPoint; + } MODULEINFO, *LPMODULEINFO; + + BOOL GetModuleListPSAPI(HANDLE hProcess) + { + // EnumProcessModules() + typedef BOOL (__stdcall *tEPM)(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded ); + // GetModuleFileNameEx() + typedef DWORD (__stdcall *tGMFNE)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize ); + // GetModuleBaseName() + typedef DWORD (__stdcall *tGMBN)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize ); + // GetModuleInformation() + typedef BOOL (__stdcall *tGMI)(HANDLE hProcess, HMODULE hModule, LPMODULEINFO pmi, DWORD nSize ); + + HINSTANCE hPsapi; + tEPM pEPM; + tGMFNE pGMFNE; + tGMBN pGMBN; + tGMI pGMI; + + DWORD i; + //ModuleEntry e; + DWORD cbNeeded; + MODULEINFO mi; + HMODULE *hMods = 0; + char *tt = NULL; + char *tt2 = NULL; + const SIZE_T TTBUFLEN = 8096; + int cnt = 0; + + hPsapi = LoadLibrary( _T("psapi.dll") ); + if (hPsapi == NULL) + return FALSE; + + pEPM = (tEPM) GetProcAddress( hPsapi, "EnumProcessModules" ); + pGMFNE = (tGMFNE) GetProcAddress( hPsapi, "GetModuleFileNameExA" ); + pGMBN = (tGMFNE) GetProcAddress( hPsapi, "GetModuleBaseNameA" ); + pGMI = (tGMI) GetProcAddress( hPsapi, "GetModuleInformation" ); + if ( (pEPM == NULL) || (pGMFNE == NULL) || (pGMBN == NULL) || (pGMI == NULL) ) + { + // we couldn´t find all functions + FreeLibrary(hPsapi); + return FALSE; + } + + hMods = (HMODULE*) malloc(sizeof(HMODULE) * (TTBUFLEN / sizeof HMODULE)); + tt = (char*) malloc(sizeof(char) * TTBUFLEN); + tt2 = (char*) malloc(sizeof(char) * TTBUFLEN); + if ( (hMods == NULL) || (tt == NULL) || (tt2 == NULL) ) + goto cleanup; + + if ( ! pEPM( hProcess, hMods, TTBUFLEN, &cbNeeded ) ) + { + //_ftprintf(fLogFile, _T("%lu: EPM failed, GetLastError = %lu\n"), g_dwShowCount, gle ); + goto cleanup; + } + + if ( cbNeeded > TTBUFLEN ) + { + //_ftprintf(fLogFile, _T("%lu: More than %lu module handles. Huh?\n"), g_dwShowCount, lenof( hMods ) ); + goto cleanup; + } + + for ( i = 0; i < cbNeeded / sizeof hMods[0]; i++ ) + { + // base address, size + pGMI(hProcess, hMods[i], &mi, sizeof mi ); + // image file name + tt[0] = 0; + pGMFNE(hProcess, hMods[i], tt, TTBUFLEN ); + // module name + tt2[0] = 0; + pGMBN(hProcess, hMods[i], tt2, TTBUFLEN ); + + DWORD dwRes = this->LoadModule(hProcess, tt, tt2, (DWORD64) mi.lpBaseOfDll, mi.SizeOfImage); + if (dwRes != ERROR_SUCCESS) + this->m_parent->OnDbgHelpErr("LoadModule", dwRes, 0); + cnt++; + } + + cleanup: + if (hPsapi != NULL) FreeLibrary(hPsapi); + if (tt2 != NULL) free(tt2); + if (tt != NULL) free(tt); + if (hMods != NULL) free(hMods); + + return cnt != 0; + } // GetModuleListPSAPI + + DWORD LoadModule(HANDLE hProcess, LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size) + { + CHAR *szImg = _strdup(img); + CHAR *szMod = _strdup(mod); + DWORD result = ERROR_SUCCESS; + if ( (szImg == NULL) || (szMod == NULL) ) + result = ERROR_NOT_ENOUGH_MEMORY; + else + { + if (pSLM(hProcess, 0, szImg, szMod, baseAddr, size) == 0) + result = GetLastError(); + } + ULONGLONG fileVersion = 0; + if ( (m_parent != NULL) && (szImg != NULL) ) + { + // try to retrive the file-version: + if ( (this->m_parent->m_options & StackWalker::RetrieveFileVersion) != 0) + { + VS_FIXEDFILEINFO *fInfo = NULL; + DWORD dwHandle; + DWORD dwSize = GetFileVersionInfoSizeA(szImg, &dwHandle); + if (dwSize > 0) + { + LPVOID vData = malloc(dwSize); + if (vData != NULL) + { + if (GetFileVersionInfoA(szImg, dwHandle, dwSize, vData) != 0) + { + UINT len; + TCHAR szSubBlock[] = _T("\\"); + if (VerQueryValue(vData, szSubBlock, (LPVOID*) &fInfo, &len) == 0) + fInfo = NULL; + else + { + fileVersion = ((ULONGLONG)fInfo->dwFileVersionLS) + ((ULONGLONG)fInfo->dwFileVersionMS << 32); + } + } + free(vData); + } + } + } + + // Retrive some additional-infos about the module + IMAGEHLP_MODULE64_V2 Module; + const char *szSymType = "-unknown-"; + if (this->GetModuleInfo(hProcess, baseAddr, &Module) != FALSE) + { + switch(Module.SymType) + { + case SymNone: + szSymType = "-nosymbols-"; + break; + case SymCoff: // 1 + szSymType = "COFF"; + break; + case SymCv: // 2 + szSymType = "CV"; + break; + case SymPdb: // 3 + szSymType = "PDB"; + break; + case SymExport: // 4 + szSymType = "-exported-"; + break; + case SymDeferred: // 5 + szSymType = "-deferred-"; + break; + case SymSym: // 6 + szSymType = "SYM"; + break; + case 7: // SymDia: + szSymType = "DIA"; + break; + case 8: //SymVirtual: + szSymType = "Virtual"; + break; + } + } + this->m_parent->OnLoadModule(img, mod, baseAddr, size, result, szSymType, Module.LoadedImageName, fileVersion); + } + if (szImg != NULL) free(szImg); + if (szMod != NULL) free(szMod); + return result; + } +public: + BOOL LoadModules(HANDLE hProcess, DWORD dwProcessId) + { + // first try toolhelp32 + if (GetModuleListTH32(hProcess, dwProcessId)) + return true; + // then try psapi + return GetModuleListPSAPI(hProcess); + } + + + BOOL GetModuleInfo(HANDLE hProcess, DWORD64 baseAddr, IMAGEHLP_MODULE64_V2 *pModuleInfo) + { + if(this->pSGMI == NULL) + { + SetLastError(ERROR_DLL_INIT_FAILED); + return FALSE; + } + // First try to use the larger ModuleInfo-Structure +// memset(pModuleInfo, 0, sizeof(IMAGEHLP_MODULE64_V3)); +// pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V3); +// if (this->pSGMI_V3 != NULL) +// { +// if (this->pSGMI_V3(hProcess, baseAddr, pModuleInfo) != FALSE) +// return TRUE; +// // check if the parameter was wrong (size is bad...) +// if (GetLastError() != ERROR_INVALID_PARAMETER) +// return FALSE; +// } + // could not retrive the bigger structure, try with the smaller one (as defined in VC7.1)... + pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2); + void *pData = malloc(4096); // reserve enough memory, so the bug in v6.3.5.1 does not lead to memory-overwrites... + if (pData == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + memcpy(pData, pModuleInfo, sizeof(IMAGEHLP_MODULE64_V2)); + if (this->pSGMI(hProcess, baseAddr, (IMAGEHLP_MODULE64_V2*) pData) != FALSE) + { + // only copy as much memory as is reserved... + memcpy(pModuleInfo, pData, sizeof(IMAGEHLP_MODULE64_V2)); + pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2); + free(pData); + return TRUE; + } + free(pData); + SetLastError(ERROR_DLL_INIT_FAILED); + return FALSE; + } +}; + +// ############################################################# +StackWalker::StackWalker(DWORD dwProcessId, HANDLE hProcess) +{ + this->m_options = OptionsAll; + this->m_modulesLoaded = FALSE; + this->m_hProcess = hProcess; + this->m_sw = new StackWalkerInternal(this, this->m_hProcess); + this->m_dwProcessId = dwProcessId; + this->m_szSymPath = NULL; + this->m_MaxRecursionCount = 1000; +} +StackWalker::StackWalker(int options, LPCSTR szSymPath, DWORD dwProcessId, HANDLE hProcess) +{ + this->m_options = options; + this->m_modulesLoaded = FALSE; + this->m_hProcess = hProcess; + this->m_sw = new StackWalkerInternal(this, this->m_hProcess); + this->m_dwProcessId = dwProcessId; + if (szSymPath != NULL) + { + this->m_szSymPath = _strdup(szSymPath); + this->m_options |= SymBuildPath; + } + else + this->m_szSymPath = NULL; + this->m_MaxRecursionCount = 1000; +} + +StackWalker::~StackWalker() +{ + if (m_szSymPath != NULL) + free(m_szSymPath); + m_szSymPath = NULL; + if (this->m_sw != NULL) + delete this->m_sw; + this->m_sw = NULL; +} + +BOOL StackWalker::LoadModules() +{ + if (this->m_sw == NULL) + { + SetLastError(ERROR_DLL_INIT_FAILED); + return FALSE; + } + if (m_modulesLoaded != FALSE) + return TRUE; + + // Build the sym-path: + char *szSymPath = NULL; + if ( (this->m_options & SymBuildPath) != 0) + { + const size_t nSymPathLen = 4096; + szSymPath = (char*) malloc(nSymPathLen); + if (szSymPath == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + szSymPath[0] = 0; + // Now first add the (optional) provided sympath: + if (this->m_szSymPath != NULL) + { + strcat_s(szSymPath, nSymPathLen, this->m_szSymPath); + strcat_s(szSymPath, nSymPathLen, ";"); + } + + strcat_s(szSymPath, nSymPathLen, ".;"); + + const size_t nTempLen = 1024; + char szTemp[nTempLen]; + // Now add the current directory: + if (GetCurrentDirectoryA(nTempLen, szTemp) > 0) + { + szTemp[nTempLen-1] = 0; + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + } + + // Now add the path for the main-module: + if (GetModuleFileNameA(NULL, szTemp, nTempLen) > 0) + { + szTemp[nTempLen-1] = 0; + for (char *p = (szTemp+strlen(szTemp)-1); p >= szTemp; --p) + { + // locate the rightmost path separator + if ( (*p == '\\') || (*p == '/') || (*p == ':') ) + { + *p = 0; + break; + } + } // for (search for path separator...) + if (strlen(szTemp) > 0) + { + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + } + } + if (GetEnvironmentVariableA("_NT_SYMBOL_PATH", szTemp, nTempLen) > 0) + { + szTemp[nTempLen-1] = 0; + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + } + if (GetEnvironmentVariableA("_NT_ALTERNATE_SYMBOL_PATH", szTemp, nTempLen) > 0) + { + szTemp[nTempLen-1] = 0; + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + } + if (GetEnvironmentVariableA("SYSTEMROOT", szTemp, nTempLen) > 0) + { + szTemp[nTempLen-1] = 0; + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + // also add the "system32"-directory: + strcat_s(szTemp, nTempLen, "\\system32"); + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + } + + if ( (this->m_options & SymUseSymSrv) != 0) + { + if (GetEnvironmentVariableA("SYSTEMDRIVE", szTemp, nTempLen) > 0) + { + szTemp[nTempLen-1] = 0; + strcat_s(szSymPath, nSymPathLen, "SRV*"); + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, "\\websymbols"); + strcat_s(szSymPath, nSymPathLen, "*http://msdl.microsoft.com/download/symbols;"); + } + else + strcat_s(szSymPath, nSymPathLen, "SRV*c:\\websymbols*http://msdl.microsoft.com/download/symbols;"); + } + } // if SymBuildPath + + // First Init the whole stuff... + BOOL bRet = this->m_sw->Init(szSymPath); + if (szSymPath != NULL) free(szSymPath); szSymPath = NULL; + if (bRet == FALSE) + { + this->OnDbgHelpErr("Error while initializing dbghelp.dll", 0, 0); + SetLastError(ERROR_DLL_INIT_FAILED); + return FALSE; + } + + bRet = this->m_sw->LoadModules(this->m_hProcess, this->m_dwProcessId); + if (bRet != FALSE) + m_modulesLoaded = TRUE; + return bRet; +} + + +// The following is used to pass the "userData"-Pointer to the user-provided readMemoryFunction +// This has to be done due to a problem with the "hProcess"-parameter in x64... +// Because this class is in no case multi-threading-enabled (because of the limitations +// of dbghelp.dll) it is "safe" to use a static-variable +static StackWalker::PReadProcessMemoryRoutine s_readMemoryFunction = NULL; +static LPVOID s_readMemoryFunction_UserData = NULL; + +BOOL StackWalker::ShowCallstack(HANDLE hThread, const CONTEXT *context, PReadProcessMemoryRoutine readMemoryFunction, LPVOID pUserData) +{ + CONTEXT c; + CallstackEntry csEntry; + IMAGEHLP_SYMBOL64 *pSym = NULL; + StackWalkerInternal::IMAGEHLP_MODULE64_V2 Module; + IMAGEHLP_LINE64 Line; + int frameNum; + bool bLastEntryCalled = true; + int curRecursionCount = 0; + + if (m_modulesLoaded == FALSE) + this->LoadModules(); // ignore the result... + + if (this->m_sw->m_hDbhHelp == NULL) + { + SetLastError(ERROR_DLL_INIT_FAILED); + return FALSE; + } + + s_readMemoryFunction = readMemoryFunction; + s_readMemoryFunction_UserData = pUserData; + + if (context == NULL) + { + // If no context is provided, capture the context + if (hThread == GetCurrentThread()) + { + GET_CURRENT_CONTEXT(c, USED_CONTEXT_FLAGS); + } + else + { + SuspendThread(hThread); + memset(&c, 0, sizeof(CONTEXT)); + c.ContextFlags = USED_CONTEXT_FLAGS; + if (GetThreadContext(hThread, &c) == FALSE) + { + ResumeThread(hThread); + return FALSE; + } + } + } + else + c = *context; + + // init STACKFRAME for first call + STACKFRAME64 s; // in/out stackframe + memset(&s, 0, sizeof(s)); + DWORD imageType; +#ifdef _M_IX86 + // normally, call ImageNtHeader() and use machine info from PE header + imageType = IMAGE_FILE_MACHINE_I386; + s.AddrPC.Offset = c.Eip; + s.AddrPC.Mode = AddrModeFlat; + s.AddrFrame.Offset = c.Ebp; + s.AddrFrame.Mode = AddrModeFlat; + s.AddrStack.Offset = c.Esp; + s.AddrStack.Mode = AddrModeFlat; +#elif _M_X64 + imageType = IMAGE_FILE_MACHINE_AMD64; + s.AddrPC.Offset = c.Rip; + s.AddrPC.Mode = AddrModeFlat; + s.AddrFrame.Offset = c.Rsp; + s.AddrFrame.Mode = AddrModeFlat; + s.AddrStack.Offset = c.Rsp; + s.AddrStack.Mode = AddrModeFlat; +#elif _M_IA64 + imageType = IMAGE_FILE_MACHINE_IA64; + s.AddrPC.Offset = c.StIIP; + s.AddrPC.Mode = AddrModeFlat; + s.AddrFrame.Offset = c.IntSp; + s.AddrFrame.Mode = AddrModeFlat; + s.AddrBStore.Offset = c.RsBSP; + s.AddrBStore.Mode = AddrModeFlat; + s.AddrStack.Offset = c.IntSp; + s.AddrStack.Mode = AddrModeFlat; +#else +#error "Platform not supported!" +#endif + + pSym = (IMAGEHLP_SYMBOL64 *) malloc(sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN); + if (!pSym) goto cleanup; // not enough memory... + memset(pSym, 0, sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN); + pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); + pSym->MaxNameLength = STACKWALK_MAX_NAMELEN; + + memset(&Line, 0, sizeof(Line)); + Line.SizeOfStruct = sizeof(Line); + + memset(&Module, 0, sizeof(Module)); + Module.SizeOfStruct = sizeof(Module); + + for (frameNum = 0; ; ++frameNum ) + { + // get next stack frame (StackWalk64(), SymFunctionTableAccess64(), SymGetModuleBase64()) + // if this returns ERROR_INVALID_ADDRESS (487) or ERROR_NOACCESS (998), you can + // assume that either you are done, or that the stack is so hosed that the next + // deeper frame could not be found. + // CONTEXT need not to be suplied if imageTyp is IMAGE_FILE_MACHINE_I386! + if ( ! this->m_sw->pSW(imageType, this->m_hProcess, hThread, &s, &c, myReadProcMem, this->m_sw->pSFTA, this->m_sw->pSGMB, NULL) ) + { + // INFO: "StackWalk64" does not set "GetLastError"... + this->OnDbgHelpErr("StackWalk64", 0, s.AddrPC.Offset); + break; + } + + csEntry.offset = s.AddrPC.Offset; + csEntry.name[0] = 0; + csEntry.undName[0] = 0; + csEntry.undFullName[0] = 0; + csEntry.offsetFromSmybol = 0; + csEntry.offsetFromLine = 0; + csEntry.lineFileName[0] = 0; + csEntry.lineNumber = 0; + csEntry.loadedImageName[0] = 0; + csEntry.moduleName[0] = 0; + if (s.AddrPC.Offset == s.AddrReturn.Offset) + { + if ( (this->m_MaxRecursionCount > 0) && (curRecursionCount > m_MaxRecursionCount) ) + { + this->OnDbgHelpErr("StackWalk64-Endless-Callstack!", 0, s.AddrPC.Offset); + break; + } + curRecursionCount++; + } + else + curRecursionCount = 0; + if (s.AddrPC.Offset != 0) + { + // we seem to have a valid PC + // show procedure info (SymGetSymFromAddr64()) + if (this->m_sw->pSGSFA(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromSmybol), pSym) != FALSE) + { + MyStrCpy(csEntry.name, STACKWALK_MAX_NAMELEN, pSym->Name); + // UnDecorateSymbolName() + this->m_sw->pUDSN( pSym->Name, csEntry.undName, STACKWALK_MAX_NAMELEN, UNDNAME_NAME_ONLY ); + this->m_sw->pUDSN( pSym->Name, csEntry.undFullName, STACKWALK_MAX_NAMELEN, UNDNAME_COMPLETE ); + } + else + { + this->OnDbgHelpErr("SymGetSymFromAddr64", GetLastError(), s.AddrPC.Offset); + } + + // show line number info, NT5.0-method (SymGetLineFromAddr64()) + if (this->m_sw->pSGLFA != NULL ) + { // yes, we have SymGetLineFromAddr64() + if (this->m_sw->pSGLFA(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromLine), &Line) != FALSE) + { + csEntry.lineNumber = Line.LineNumber; + MyStrCpy(csEntry.lineFileName, STACKWALK_MAX_NAMELEN, Line.FileName); + } + else + { + this->OnDbgHelpErr("SymGetLineFromAddr64", GetLastError(), s.AddrPC.Offset); + } + } // yes, we have SymGetLineFromAddr64() + + // show module info (SymGetModuleInfo64()) + if (this->m_sw->GetModuleInfo(this->m_hProcess, s.AddrPC.Offset, &Module ) != FALSE) + { // got module info OK + switch ( Module.SymType ) + { + case SymNone: + csEntry.symTypeString = "-nosymbols-"; + break; + case SymCoff: + csEntry.symTypeString = "COFF"; + break; + case SymCv: + csEntry.symTypeString = "CV"; + break; + case SymPdb: + csEntry.symTypeString = "PDB"; + break; + case SymExport: + csEntry.symTypeString = "-exported-"; + break; + case SymDeferred: + csEntry.symTypeString = "-deferred-"; + break; + case SymSym: + csEntry.symTypeString = "SYM"; + break; +#if API_VERSION_NUMBER >= 9 + case SymDia: + csEntry.symTypeString = "DIA"; + break; +#endif + case 8: //SymVirtual: + csEntry.symTypeString = "Virtual"; + break; + default: + //_snprintf( ty, sizeof ty, "symtype=%ld", (long) Module.SymType ); + csEntry.symTypeString = NULL; + break; + } + + // TODO: Mache dies sicher...! + MyStrCpy(csEntry.moduleName, STACKWALK_MAX_NAMELEN, Module.ModuleName); + csEntry.baseOfImage = Module.BaseOfImage; + MyStrCpy(csEntry.loadedImageName, STACKWALK_MAX_NAMELEN, Module.LoadedImageName); + } // got module info OK + else + { + this->OnDbgHelpErr("SymGetModuleInfo64", GetLastError(), s.AddrPC.Offset); + } + } // we seem to have a valid PC + + CallstackEntryType et = nextEntry; + if (frameNum == 0) + et = firstEntry; + bLastEntryCalled = false; + this->OnCallstackEntry(et, csEntry); + + if (s.AddrReturn.Offset == 0) + { + bLastEntryCalled = true; + this->OnCallstackEntry(lastEntry, csEntry); + SetLastError(ERROR_SUCCESS); + break; + } + } // for ( frameNum ) + + cleanup: + if (pSym) free( pSym ); + + if (bLastEntryCalled == false) + this->OnCallstackEntry(lastEntry, csEntry); + + if (context == NULL) + ResumeThread(hThread); + + return TRUE; +} + +BOOL __stdcall StackWalker::myReadProcMem( + HANDLE hProcess, + DWORD64 qwBaseAddress, + PVOID lpBuffer, + DWORD nSize, + LPDWORD lpNumberOfBytesRead + ) +{ + if (s_readMemoryFunction == NULL) + { + SIZE_T st; + BOOL bRet = ReadProcessMemory(hProcess, (LPVOID) qwBaseAddress, lpBuffer, nSize, &st); + *lpNumberOfBytesRead = (DWORD) st; + //printf("ReadMemory: hProcess: %p, baseAddr: %p, buffer: %p, size: %d, read: %d, result: %d\n", hProcess, (LPVOID) qwBaseAddress, lpBuffer, nSize, (DWORD) st, (DWORD) bRet); + return bRet; + } + else + { + return s_readMemoryFunction(hProcess, qwBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead, s_readMemoryFunction_UserData); + } +} + +void StackWalker::OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion) +{ + CHAR buffer[STACKWALK_MAX_NAMELEN]; + if (fileVersion == 0) + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s'\n", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName); + else + { + DWORD v4 = (DWORD) fileVersion & 0xFFFF; + DWORD v3 = (DWORD) (fileVersion>>16) & 0xFFFF; + DWORD v2 = (DWORD) (fileVersion>>32) & 0xFFFF; + DWORD v1 = (DWORD) (fileVersion>>48) & 0xFFFF; + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s', fileVersion: %d.%d.%d.%d\n", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName, v1, v2, v3, v4); + } + OnOutput(buffer); +} + +void StackWalker::OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry) +{ + CHAR buffer[STACKWALK_MAX_NAMELEN]; + if ( (eType != lastEntry) && (entry.offset != 0) ) + { + if (entry.name[0] == 0) + MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, "(function-name not available)"); + if (entry.undName[0] != 0) + MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, entry.undName); + if (entry.undFullName[0] != 0) + MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, entry.undFullName); + if (entry.lineFileName[0] == 0) + { + MyStrCpy(entry.lineFileName, STACKWALK_MAX_NAMELEN, "(filename not available)"); + if (entry.moduleName[0] == 0) + MyStrCpy(entry.moduleName, STACKWALK_MAX_NAMELEN, "(module-name not available)"); + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%p (%s): %s: %s\n", (LPVOID) entry.offset, entry.moduleName, entry.lineFileName, entry.name); + } + else + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s (%d): %s\n", entry.lineFileName, entry.lineNumber, entry.name); + buffer[STACKWALK_MAX_NAMELEN-1] = 0; + OnOutput(buffer); + } +} + +void StackWalker::OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr) +{ + CHAR buffer[STACKWALK_MAX_NAMELEN]; + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "ERROR: %s, GetLastError: %d (Address: %p)\n", szFuncName, gle, (LPVOID) addr); + OnOutput(buffer); +} + +void StackWalker::OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName) +{ + CHAR buffer[STACKWALK_MAX_NAMELEN]; + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "SymInit: Symbol-SearchPath: '%s', symOptions: %d, UserName: '%s'\n", szSearchPath, symOptions, szUserName); + OnOutput(buffer); + // Also display the OS-version +#if _MSC_VER <= 1200 + OSVERSIONINFOA ver; + ZeroMemory(&ver, sizeof(OSVERSIONINFOA)); + ver.dwOSVersionInfoSize = sizeof(ver); + if (GetVersionExA(&ver) != FALSE) + { + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "OS-Version: %d.%d.%d (%s)\n", + ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber, + ver.szCSDVersion); + OnOutput(buffer); + } +#else + OSVERSIONINFOEXA ver; + ZeroMemory(&ver, sizeof(OSVERSIONINFOEXA)); + ver.dwOSVersionInfoSize = sizeof(ver); + if (GetVersionExA( (OSVERSIONINFOA*) &ver) != FALSE) + { + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "OS-Version: %d.%d.%d (%s) 0x%x-0x%x\n", + ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber, + ver.szCSDVersion, ver.wSuiteMask, ver.wProductType); + OnOutput(buffer); + } +#endif +} + +void StackWalker::OnOutput(LPCSTR buffer) +{ + OutputDebugStringA(buffer); +} diff --git a/source/StackWalker.h b/source/StackWalker.h index 212e02a9f..bf47d3726 100644 --- a/source/StackWalker.h +++ b/source/StackWalker.h @@ -1,214 +1,214 @@ -/********************************************************************** - * - * StackWalker.h - * - * - * - * LICENSE (http://www.opensource.org/licenses/bsd-license.php) - * - * Copyright (c) 2005-2010, Jochen Kalmbach - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * Neither the name of Jochen Kalmbach nor the names of its contributors may be - * used to endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * **********************************************************************/ -// #pragma once is supported starting with _MCS_VER 1000, -// so we need not to check the version (because we only support _MSC_VER >= 1100)! -#pragma once - -#include - -// special defines for VC5/6 (if no actual PSDK is installed): -#if _MSC_VER < 1300 -typedef unsigned __int64 DWORD64, *PDWORD64; -#if defined(_WIN64) -typedef unsigned __int64 SIZE_T, *PSIZE_T; -#else -typedef unsigned long SIZE_T, *PSIZE_T; -#endif -#endif // _MSC_VER < 1300 - -class StackWalkerInternal; // forward -class StackWalker -{ -public: - typedef enum StackWalkOptions - { - // No addition info will be retrived - // (only the address is available) - RetrieveNone = 0, - - // Try to get the symbol-name - RetrieveSymbol = 1, - - // Try to get the line for this symbol - RetrieveLine = 2, - - // Try to retrieve the module-infos - RetrieveModuleInfo = 4, - - // Also retrieve the version for the DLL/EXE - RetrieveFileVersion = 8, - - // Contains all the abouve - RetrieveVerbose = 0xF, - - // Generate a "good" symbol-search-path - SymBuildPath = 0x10, - - // Also use the public Microsoft-Symbol-Server - SymUseSymSrv = 0x20, - - // Contains all the abouve "Sym"-options - SymAll = 0x30, - - // Contains all options (default) - OptionsAll = 0x3F - } StackWalkOptions; - - StackWalker( - int options = OptionsAll, // 'int' is by design, to combine the enum-flags - LPCSTR szSymPath = NULL, - DWORD dwProcessId = GetCurrentProcessId(), - HANDLE hProcess = GetCurrentProcess() - ); - StackWalker(DWORD dwProcessId, HANDLE hProcess); - virtual ~StackWalker(); - - typedef BOOL (__stdcall *PReadProcessMemoryRoutine)( - HANDLE hProcess, - DWORD64 qwBaseAddress, - PVOID lpBuffer, - DWORD nSize, - LPDWORD lpNumberOfBytesRead, - LPVOID pUserData // optional data, which was passed in "ShowCallstack" - ); - - BOOL LoadModules(); - - BOOL ShowCallstack( - HANDLE hThread = GetCurrentThread(), - const CONTEXT *context = NULL, - PReadProcessMemoryRoutine readMemoryFunction = NULL, - LPVOID pUserData = NULL // optional to identify some data in the 'readMemoryFunction'-callback - ); - -#if _MSC_VER >= 1300 -// due to some reasons, the "STACKWALK_MAX_NAMELEN" must be declared as "public" -// in older compilers in order to use it... starting with VC7 we can declare it as "protected" -protected: -#endif - enum { STACKWALK_MAX_NAMELEN = 1024 }; // max name length for found symbols - -protected: - // Entry for each Callstack-Entry - typedef struct CallstackEntry - { - DWORD64 offset; // if 0, we have no valid entry - CHAR name[STACKWALK_MAX_NAMELEN]; - CHAR undName[STACKWALK_MAX_NAMELEN]; - CHAR undFullName[STACKWALK_MAX_NAMELEN]; - DWORD64 offsetFromSmybol; - DWORD offsetFromLine; - DWORD lineNumber; - CHAR lineFileName[STACKWALK_MAX_NAMELEN]; - DWORD symType; - LPCSTR symTypeString; - CHAR moduleName[STACKWALK_MAX_NAMELEN]; - DWORD64 baseOfImage; - CHAR loadedImageName[STACKWALK_MAX_NAMELEN]; - } CallstackEntry; - - typedef enum CallstackEntryType {firstEntry, nextEntry, lastEntry}; - - virtual void OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName); - virtual void OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion); - virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry); - virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr); - virtual void OnOutput(LPCSTR szText); - - StackWalkerInternal *m_sw; - HANDLE m_hProcess; - DWORD m_dwProcessId; - BOOL m_modulesLoaded; - LPSTR m_szSymPath; - - int m_options; - int m_MaxRecursionCount; - - static BOOL __stdcall myReadProcMem(HANDLE hProcess, DWORD64 qwBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead); - - friend StackWalkerInternal; -}; - - -// The "ugly" assembler-implementation is needed for systems before XP -// If you have a new PSDK and you only compile for XP and later, then you can use -// the "RtlCaptureContext" -// Currently there is no define which determines the PSDK-Version... -// So we just use the compiler-version (and assumes that the PSDK is -// the one which was installed by the VS-IDE) - -// INFO: If you want, you can use the RtlCaptureContext if you only target XP and later... -// But I currently use it in x64/IA64 environments... -//#if defined(_M_IX86) && (_WIN32_WINNT <= 0x0500) && (_MSC_VER < 1400) - -#if defined(_M_IX86) -#ifdef CURRENT_THREAD_VIA_EXCEPTION -// TODO: The following is not a "good" implementation, -// because the callstack is only valid in the "__except" block... -#define GET_CURRENT_CONTEXT(c, contextFlags) \ - do { \ - memset(&c, 0, sizeof(CONTEXT)); \ - EXCEPTION_POINTERS *pExp = NULL; \ - __try { \ - throw 0; \ - } __except( ( (pExp = GetExceptionInformation()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_EXECUTE_HANDLER)) {} \ - if (pExp != NULL) \ - memcpy(&c, pExp->ContextRecord, sizeof(CONTEXT)); \ - c.ContextFlags = contextFlags; \ - } while(0); -#else -// The following should be enough for walking the callstack... -#define GET_CURRENT_CONTEXT(c, contextFlags) \ - do { \ - memset(&c, 0, sizeof(CONTEXT)); \ - c.ContextFlags = contextFlags; \ - __asm call x \ - __asm x: pop eax \ - __asm mov c.Eip, eax \ - __asm mov c.Ebp, ebp \ - __asm mov c.Esp, esp \ - } while(0); -#endif - -#else - -// The following is defined for x86 (XP and higher), x64 and IA64: -#define GET_CURRENT_CONTEXT(c, contextFlags) \ - do { \ - memset(&c, 0, sizeof(CONTEXT)); \ - c.ContextFlags = contextFlags; \ - RtlCaptureContext(&c); \ -} while(0); -#endif +/********************************************************************** + * + * StackWalker.h + * + * + * + * LICENSE (http://www.opensource.org/licenses/bsd-license.php) + * + * Copyright (c) 2005-2010, Jochen Kalmbach + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of Jochen Kalmbach nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * **********************************************************************/ +// #pragma once is supported starting with _MCS_VER 1000, +// so we need not to check the version (because we only support _MSC_VER >= 1100)! +#pragma once + +#include + +// special defines for VC5/6 (if no actual PSDK is installed): +#if _MSC_VER < 1300 +typedef unsigned __int64 DWORD64, *PDWORD64; +#if defined(_WIN64) +typedef unsigned __int64 SIZE_T, *PSIZE_T; +#else +typedef unsigned long SIZE_T, *PSIZE_T; +#endif +#endif // _MSC_VER < 1300 + +class StackWalkerInternal; // forward +class StackWalker +{ +public: + typedef enum StackWalkOptions + { + // No addition info will be retrived + // (only the address is available) + RetrieveNone = 0, + + // Try to get the symbol-name + RetrieveSymbol = 1, + + // Try to get the line for this symbol + RetrieveLine = 2, + + // Try to retrieve the module-infos + RetrieveModuleInfo = 4, + + // Also retrieve the version for the DLL/EXE + RetrieveFileVersion = 8, + + // Contains all the abouve + RetrieveVerbose = 0xF, + + // Generate a "good" symbol-search-path + SymBuildPath = 0x10, + + // Also use the public Microsoft-Symbol-Server + SymUseSymSrv = 0x20, + + // Contains all the abouve "Sym"-options + SymAll = 0x30, + + // Contains all options (default) + OptionsAll = 0x3F + } StackWalkOptions; + + StackWalker( + int options = OptionsAll, // 'int' is by design, to combine the enum-flags + LPCSTR szSymPath = NULL, + DWORD dwProcessId = GetCurrentProcessId(), + HANDLE hProcess = GetCurrentProcess() + ); + StackWalker(DWORD dwProcessId, HANDLE hProcess); + virtual ~StackWalker(); + + typedef BOOL (__stdcall *PReadProcessMemoryRoutine)( + HANDLE hProcess, + DWORD64 qwBaseAddress, + PVOID lpBuffer, + DWORD nSize, + LPDWORD lpNumberOfBytesRead, + LPVOID pUserData // optional data, which was passed in "ShowCallstack" + ); + + BOOL LoadModules(); + + BOOL ShowCallstack( + HANDLE hThread = GetCurrentThread(), + const CONTEXT *context = NULL, + PReadProcessMemoryRoutine readMemoryFunction = NULL, + LPVOID pUserData = NULL // optional to identify some data in the 'readMemoryFunction'-callback + ); + +#if _MSC_VER >= 1300 +// due to some reasons, the "STACKWALK_MAX_NAMELEN" must be declared as "public" +// in older compilers in order to use it... starting with VC7 we can declare it as "protected" +protected: +#endif + enum { STACKWALK_MAX_NAMELEN = 1024 }; // max name length for found symbols + +protected: + // Entry for each Callstack-Entry + typedef struct CallstackEntry + { + DWORD64 offset; // if 0, we have no valid entry + CHAR name[STACKWALK_MAX_NAMELEN]; + CHAR undName[STACKWALK_MAX_NAMELEN]; + CHAR undFullName[STACKWALK_MAX_NAMELEN]; + DWORD64 offsetFromSmybol; + DWORD offsetFromLine; + DWORD lineNumber; + CHAR lineFileName[STACKWALK_MAX_NAMELEN]; + DWORD symType; + LPCSTR symTypeString; + CHAR moduleName[STACKWALK_MAX_NAMELEN]; + DWORD64 baseOfImage; + CHAR loadedImageName[STACKWALK_MAX_NAMELEN]; + } CallstackEntry; + + typedef enum CallstackEntryType {firstEntry, nextEntry, lastEntry}; + + virtual void OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName); + virtual void OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion); + virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry); + virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr); + virtual void OnOutput(LPCSTR szText); + + StackWalkerInternal *m_sw; + HANDLE m_hProcess; + DWORD m_dwProcessId; + BOOL m_modulesLoaded; + LPSTR m_szSymPath; + + int m_options; + int m_MaxRecursionCount; + + static BOOL __stdcall myReadProcMem(HANDLE hProcess, DWORD64 qwBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead); + + friend StackWalkerInternal; +}; + + +// The "ugly" assembler-implementation is needed for systems before XP +// If you have a new PSDK and you only compile for XP and later, then you can use +// the "RtlCaptureContext" +// Currently there is no define which determines the PSDK-Version... +// So we just use the compiler-version (and assumes that the PSDK is +// the one which was installed by the VS-IDE) + +// INFO: If you want, you can use the RtlCaptureContext if you only target XP and later... +// But I currently use it in x64/IA64 environments... +//#if defined(_M_IX86) && (_WIN32_WINNT <= 0x0500) && (_MSC_VER < 1400) + +#if defined(_M_IX86) +#ifdef CURRENT_THREAD_VIA_EXCEPTION +// TODO: The following is not a "good" implementation, +// because the callstack is only valid in the "__except" block... +#define GET_CURRENT_CONTEXT(c, contextFlags) \ + do { \ + memset(&c, 0, sizeof(CONTEXT)); \ + EXCEPTION_POINTERS *pExp = NULL; \ + __try { \ + throw 0; \ + } __except( ( (pExp = GetExceptionInformation()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_EXECUTE_HANDLER)) {} \ + if (pExp != NULL) \ + memcpy(&c, pExp->ContextRecord, sizeof(CONTEXT)); \ + c.ContextFlags = contextFlags; \ + } while(0); +#else +// The following should be enough for walking the callstack... +#define GET_CURRENT_CONTEXT(c, contextFlags) \ + do { \ + memset(&c, 0, sizeof(CONTEXT)); \ + c.ContextFlags = contextFlags; \ + __asm call x \ + __asm x: pop eax \ + __asm mov c.Eip, eax \ + __asm mov c.Ebp, ebp \ + __asm mov c.Esp, esp \ + } while(0); +#endif + +#else + +// The following is defined for x86 (XP and higher), x64 and IA64: +#define GET_CURRENT_CONTEXT(c, contextFlags) \ + do { \ + memset(&c, 0, sizeof(CONTEXT)); \ + c.ContextFlags = contextFlags; \ + RtlCaptureContext(&c); \ +} while(0); +#endif diff --git a/source/StringCompression.cpp b/source/StringCompression.cpp index 96d94fe9d..b7e08cb11 100644 --- a/source/StringCompression.cpp +++ b/source/StringCompression.cpp @@ -1,55 +1,55 @@ - -// StringCompression.cpp - -// Implements the wrapping functions for compression and decompression using AString as their data - -#include "Globals.h" -#include "StringCompression.h" -#include "zlib.h" - - - - - -/// Compresses a_Data into a_Compressed; return Z_XXX error constants same as zlib's compress2() -int CompressString(const char * a_Data, int a_Length, AString & a_Compressed) -{ - uLongf CompressedSize = compressBound(a_Length); - - // HACK: We're assuming that AString returns its internal buffer in its data() call and we're overwriting that buffer! - // It saves us one allocation and one memcpy of the entire compressed data - // It may not work on some STL implementations! (Confirmed working on MSVC 2008 & 2010) - a_Compressed.resize(CompressedSize); - int errorcode = compress2( (Bytef*)a_Compressed.data(), &CompressedSize, (const Bytef*)a_Data, a_Length, Z_DEFAULT_COMPRESSION); - if (errorcode != Z_OK) - { - return errorcode; - } - a_Compressed.resize(CompressedSize); - return Z_OK; -} - - - - - -/// Uncompresses a_Data into a_Decompressed; returns Z_XXX error constants same as zlib's uncompress() -int UncompressString(const char * a_Data, int a_Length, AString & a_Uncompressed, int a_UncompressedSize) -{ - // HACK: We're assuming that AString returns its internal buffer in its data() call and we're overwriting that buffer! - // It saves us one allocation and one memcpy of the entire compressed data - // It may not work on some STL implementations! (Confirmed working on MSVC 2008 & 2010) - a_Uncompressed.resize(a_UncompressedSize); - uLongf UncompressedSize = (uLongf)a_UncompressedSize; // On some architectures the uLongf is different in size to int, that may be the cause of the -5 error - int errorcode = uncompress((Bytef*)a_Uncompressed.data(), &UncompressedSize, (const Bytef*)a_Data, a_Length); - if (errorcode != Z_OK) - { - return errorcode; - } - a_Uncompressed.resize(UncompressedSize); - return Z_OK; -} - - - - + +// StringCompression.cpp + +// Implements the wrapping functions for compression and decompression using AString as their data + +#include "Globals.h" +#include "StringCompression.h" +#include "zlib.h" + + + + + +/// Compresses a_Data into a_Compressed; return Z_XXX error constants same as zlib's compress2() +int CompressString(const char * a_Data, int a_Length, AString & a_Compressed) +{ + uLongf CompressedSize = compressBound(a_Length); + + // HACK: We're assuming that AString returns its internal buffer in its data() call and we're overwriting that buffer! + // It saves us one allocation and one memcpy of the entire compressed data + // It may not work on some STL implementations! (Confirmed working on MSVC 2008 & 2010) + a_Compressed.resize(CompressedSize); + int errorcode = compress2( (Bytef*)a_Compressed.data(), &CompressedSize, (const Bytef*)a_Data, a_Length, Z_DEFAULT_COMPRESSION); + if (errorcode != Z_OK) + { + return errorcode; + } + a_Compressed.resize(CompressedSize); + return Z_OK; +} + + + + + +/// Uncompresses a_Data into a_Decompressed; returns Z_XXX error constants same as zlib's uncompress() +int UncompressString(const char * a_Data, int a_Length, AString & a_Uncompressed, int a_UncompressedSize) +{ + // HACK: We're assuming that AString returns its internal buffer in its data() call and we're overwriting that buffer! + // It saves us one allocation and one memcpy of the entire compressed data + // It may not work on some STL implementations! (Confirmed working on MSVC 2008 & 2010) + a_Uncompressed.resize(a_UncompressedSize); + uLongf UncompressedSize = (uLongf)a_UncompressedSize; // On some architectures the uLongf is different in size to int, that may be the cause of the -5 error + int errorcode = uncompress((Bytef*)a_Uncompressed.data(), &UncompressedSize, (const Bytef*)a_Data, a_Length); + if (errorcode != Z_OK) + { + return errorcode; + } + a_Uncompressed.resize(UncompressedSize); + return Z_OK; +} + + + + diff --git a/source/StringCompression.h b/source/StringCompression.h index 976fd2ecd..5afd4c37f 100644 --- a/source/StringCompression.h +++ b/source/StringCompression.h @@ -1,17 +1,17 @@ - -// StringCompression.h - -// Interfaces to the wrapping functions for compression and decompression using AString as their data - - - - -/// Compresses a_Data into a_Compressed; return Z_XXX error constants same as zlib's compress2() -extern int CompressString(const char * a_Data, int a_Length, AString & a_Compressed); - -/// Uncompresses a_Data into a_Decompressed; returns Z_XXX error constants same as zlib's decompress() -extern int UncompressString(const char * a_Data, int a_Length, AString & a_Uncompressed, int a_UncompressedSize); - - - - + +// StringCompression.h + +// Interfaces to the wrapping functions for compression and decompression using AString as their data + + + + +/// Compresses a_Data into a_Compressed; return Z_XXX error constants same as zlib's compress2() +extern int CompressString(const char * a_Data, int a_Length, AString & a_Compressed); + +/// Uncompresses a_Data into a_Decompressed; returns Z_XXX error constants same as zlib's decompress() +extern int UncompressString(const char * a_Data, int a_Length, AString & a_Uncompressed, int a_UncompressedSize); + + + + diff --git a/source/StringUtils.cpp b/source/StringUtils.cpp index df2e72a17..652c680c7 100644 --- a/source/StringUtils.cpp +++ b/source/StringUtils.cpp @@ -1,232 +1,232 @@ - -// StringUtils.cpp - -// Implements the various string helper functions: - -#include "Globals.h" - - - - - -AString & AppendVPrintf(AString & str, const char *format, va_list args) -{ - ASSERT(format != NULL); - - char buffer[2048]; - size_t len; - #ifdef _MSC_VER - // MS CRT provides secure printf that doesn't behave like in the C99 standard - if ((len = _vsnprintf_s(buffer, ARRAYCOUNT(buffer), _TRUNCATE, format, args)) != -1) - #else // _MSC_VER - if ((len = vsnprintf(buffer, ARRAYCOUNT(buffer), format, args)) < ARRAYCOUNT(buffer)) - #endif // else _MSC_VER - { - // The result did fit into the static buffer - str.append(buffer, len); - return str; - } - - // The result did not fit into the static buffer - #ifdef _MSC_VER - // for MS CRT, we need to calculate the result length - len = _vscprintf(format, args); - if (len == -1) - { - return str; - } - #endif // _MSC_VER - - // Allocate a buffer and printf into it: - str.resize(len + 1); - // HACK: we're accessing AString's internal buffer in a way that is NOT guaranteed to always work. But it works on all STL implementations tested. - // I can't think of any other way that is safe, doesn't allocate twice as much space as needed and doesn't use C++11 features like the move constructor - #ifdef _MSC_VER - vsprintf_s((char *)str.data(), len + 1, format, args); - #else // _MSC_VER - vsnprintf((char *)str.data(), len + 1, format, args); - #endif // else _MSC_VER - str.resize(len); - return str; -} - - - - - -AString & Printf(AString & str, const char *format, ...) -{ - str.clear(); - va_list args; - va_start(args, format); - std::string &retval = AppendVPrintf(str, format, args); - va_end(args); - return retval; -} - - - - - -AString & AppendPrintf(AString &str, const char *format, ...) -{ - va_list args; - va_start(args, format); - std::string &retval = AppendVPrintf(str, format, args); - va_end(args); - return retval; -} - - - - - -AStringVector StringSplit(const AString & str, const AString & delim) -{ - AStringVector results; - size_t cutAt = 0; - size_t Prev = 0; - while ((cutAt = str.find_first_of(delim, Prev)) != str.npos) - { - results.push_back(str.substr(Prev, cutAt - Prev)); - Prev = cutAt + delim.length(); - } - if (Prev < str.length()) - { - results.push_back(str.substr(Prev)); - } - return results; -} - - - - -AString TrimString(const AString & str) -{ - size_t len = str.length(); - size_t start = 0; - while (start < len) - { - if (str[start] > 32) - { - break; - } - ++start; - } - if (start == len) - { - return ""; - } - - size_t end = len; - while (end >= start) - { - if (str[end] > 32) - { - break; - } - --end; - } - - return str.substr(start, end - start + 1); -} - - - - - -AString & StrToUpper(AString & s) -{ - AString::iterator i = s.begin(); - AString::iterator end = s.end(); - - while (i != end) - { - *i = (char)toupper(*i); - ++i; - } - return s; -} - - - - - -int NoCaseCompare(const AString & s1, const AString & s2) -{ - #ifdef _MSC_VER - // MSVC has stricmp that compares case-insensitive: - return _stricmp(s1.c_str(), s2.c_str()); - #else - // Do it the hard way: - AString s1Copy(s1); - AString s2Copy(s2); - return StrToUpper(s1Copy).compare(StrToUpper(s2Copy)); - #endif // else _MSC_VER -} - - - - - -void ReplaceString(AString & iHayStack, const AString & iNeedle, const AString & iReplaceWith) -{ - size_t pos1 = iHayStack.find(iNeedle); - while (pos1 != AString::npos) - { - iHayStack.replace( pos1, iNeedle.size(), iReplaceWith); - pos1 = iHayStack.find(iNeedle, pos1); - } -} - - - - -AStringList GetDirectoryContents(const char * a_Directory) -{ - AStringList AllFiles; - - #ifdef _WIN32 - - AString FileFilter = AString(a_Directory) + "*.*"; - HANDLE hFind; - WIN32_FIND_DATA FindFileData; - - if ((hFind = FindFirstFile(FileFilter.c_str(), &FindFileData)) != INVALID_HANDLE_VALUE) - { - do - { - AllFiles.push_back(FindFileData.cFileName); - } while (FindNextFile(hFind, &FindFileData)); - FindClose(hFind); - } - - #else // _WIN32 - - DIR * dp; - struct dirent *dirp; - if (*a_Directory == 0) - { - a_Directory = "."; - } - if ((dp = opendir(a_Directory)) == NULL) - { - LOGERROR("Error (%i) opening directory \"%s\"\n", errno, a_Directory ); - } - else - { - while ((dirp = readdir(dp)) != NULL) - { - AllFiles.push_back(dirp->d_name); - } - closedir(dp); - } - - #endif // else _WIN32 - - return AllFiles; -} - - - - + +// StringUtils.cpp + +// Implements the various string helper functions: + +#include "Globals.h" + + + + + +AString & AppendVPrintf(AString & str, const char *format, va_list args) +{ + ASSERT(format != NULL); + + char buffer[2048]; + size_t len; + #ifdef _MSC_VER + // MS CRT provides secure printf that doesn't behave like in the C99 standard + if ((len = _vsnprintf_s(buffer, ARRAYCOUNT(buffer), _TRUNCATE, format, args)) != -1) + #else // _MSC_VER + if ((len = vsnprintf(buffer, ARRAYCOUNT(buffer), format, args)) < ARRAYCOUNT(buffer)) + #endif // else _MSC_VER + { + // The result did fit into the static buffer + str.append(buffer, len); + return str; + } + + // The result did not fit into the static buffer + #ifdef _MSC_VER + // for MS CRT, we need to calculate the result length + len = _vscprintf(format, args); + if (len == -1) + { + return str; + } + #endif // _MSC_VER + + // Allocate a buffer and printf into it: + str.resize(len + 1); + // HACK: we're accessing AString's internal buffer in a way that is NOT guaranteed to always work. But it works on all STL implementations tested. + // I can't think of any other way that is safe, doesn't allocate twice as much space as needed and doesn't use C++11 features like the move constructor + #ifdef _MSC_VER + vsprintf_s((char *)str.data(), len + 1, format, args); + #else // _MSC_VER + vsnprintf((char *)str.data(), len + 1, format, args); + #endif // else _MSC_VER + str.resize(len); + return str; +} + + + + + +AString & Printf(AString & str, const char *format, ...) +{ + str.clear(); + va_list args; + va_start(args, format); + std::string &retval = AppendVPrintf(str, format, args); + va_end(args); + return retval; +} + + + + + +AString & AppendPrintf(AString &str, const char *format, ...) +{ + va_list args; + va_start(args, format); + std::string &retval = AppendVPrintf(str, format, args); + va_end(args); + return retval; +} + + + + + +AStringVector StringSplit(const AString & str, const AString & delim) +{ + AStringVector results; + size_t cutAt = 0; + size_t Prev = 0; + while ((cutAt = str.find_first_of(delim, Prev)) != str.npos) + { + results.push_back(str.substr(Prev, cutAt - Prev)); + Prev = cutAt + delim.length(); + } + if (Prev < str.length()) + { + results.push_back(str.substr(Prev)); + } + return results; +} + + + + +AString TrimString(const AString & str) +{ + size_t len = str.length(); + size_t start = 0; + while (start < len) + { + if (str[start] > 32) + { + break; + } + ++start; + } + if (start == len) + { + return ""; + } + + size_t end = len; + while (end >= start) + { + if (str[end] > 32) + { + break; + } + --end; + } + + return str.substr(start, end - start + 1); +} + + + + + +AString & StrToUpper(AString & s) +{ + AString::iterator i = s.begin(); + AString::iterator end = s.end(); + + while (i != end) + { + *i = (char)toupper(*i); + ++i; + } + return s; +} + + + + + +int NoCaseCompare(const AString & s1, const AString & s2) +{ + #ifdef _MSC_VER + // MSVC has stricmp that compares case-insensitive: + return _stricmp(s1.c_str(), s2.c_str()); + #else + // Do it the hard way: + AString s1Copy(s1); + AString s2Copy(s2); + return StrToUpper(s1Copy).compare(StrToUpper(s2Copy)); + #endif // else _MSC_VER +} + + + + + +void ReplaceString(AString & iHayStack, const AString & iNeedle, const AString & iReplaceWith) +{ + size_t pos1 = iHayStack.find(iNeedle); + while (pos1 != AString::npos) + { + iHayStack.replace( pos1, iNeedle.size(), iReplaceWith); + pos1 = iHayStack.find(iNeedle, pos1); + } +} + + + + +AStringList GetDirectoryContents(const char * a_Directory) +{ + AStringList AllFiles; + + #ifdef _WIN32 + + AString FileFilter = AString(a_Directory) + "*.*"; + HANDLE hFind; + WIN32_FIND_DATA FindFileData; + + if ((hFind = FindFirstFile(FileFilter.c_str(), &FindFileData)) != INVALID_HANDLE_VALUE) + { + do + { + AllFiles.push_back(FindFileData.cFileName); + } while (FindNextFile(hFind, &FindFileData)); + FindClose(hFind); + } + + #else // _WIN32 + + DIR * dp; + struct dirent *dirp; + if (*a_Directory == 0) + { + a_Directory = "."; + } + if ((dp = opendir(a_Directory)) == NULL) + { + LOGERROR("Error (%i) opening directory \"%s\"\n", errno, a_Directory ); + } + else + { + while ((dirp = readdir(dp)) != NULL) + { + AllFiles.push_back(dirp->d_name); + } + closedir(dp); + } + + #endif // else _WIN32 + + return AllFiles; +} + + + + diff --git a/source/StringUtils.h b/source/StringUtils.h index be0b02445..fee71481e 100644 --- a/source/StringUtils.h +++ b/source/StringUtils.h @@ -1,62 +1,62 @@ - -// StringUtils.h - -// Interfaces to various string helper functions - - - - -#ifndef STRINGUTILS_H_INCLUDED -#define STRINGUTILS_H_INCLUDED - - - - - -typedef std::string AString; -typedef std::vector AStringVector; -typedef std::list AStringList; - - - - - -/// Add the formated string to the existing data in the string -extern AString & AppendVPrintf(AString & str, const char * format, va_list args); - -/// Output the formatted text into the string -extern AString & Printf (AString & str, const char * format, ...); - -/// Add the formatted string to the existing data in the string -extern AString & AppendPrintf (AString & str, const char * format, ...); - -/// Split the string at delimiters, return as a stringvector -extern AStringVector StringSplit(const AString & str, const AString & delim); - -/// Trime whitespace at both ends of the string -extern AString TrimString(const AString & str); - -/// In-place string conversion to uppercase; returns the same string -extern AString & StrToUpper(AString & s); - -/// Case-insensitive string comparison; returns 0 if the strings are the same -extern int NoCaseCompare(const AString & s1, const AString & s2); - -/// Replaces *each* occurence of iNeedle in iHayStack with iReplaceWith -extern void ReplaceString(AString & iHayStack, const AString & iNeedle, const AString & iReplaceWith); - -/// Returns the list of all items in the specified directory (files, folders, nix pipes, whatever's there) -extern AStringList GetDirectoryContents(const char * a_Directory); - - - -// If you have any other string helper functions, declare them here - - - - -#endif // STRINGUTILS_H_INCLUDED - - - - + +// StringUtils.h + +// Interfaces to various string helper functions + + + + +#ifndef STRINGUTILS_H_INCLUDED +#define STRINGUTILS_H_INCLUDED + + + + + +typedef std::string AString; +typedef std::vector AStringVector; +typedef std::list AStringList; + + + + + +/// Add the formated string to the existing data in the string +extern AString & AppendVPrintf(AString & str, const char * format, va_list args); + +/// Output the formatted text into the string +extern AString & Printf (AString & str, const char * format, ...); + +/// Add the formatted string to the existing data in the string +extern AString & AppendPrintf (AString & str, const char * format, ...); + +/// Split the string at delimiters, return as a stringvector +extern AStringVector StringSplit(const AString & str, const AString & delim); + +/// Trime whitespace at both ends of the string +extern AString TrimString(const AString & str); + +/// In-place string conversion to uppercase; returns the same string +extern AString & StrToUpper(AString & s); + +/// Case-insensitive string comparison; returns 0 if the strings are the same +extern int NoCaseCompare(const AString & s1, const AString & s2); + +/// Replaces *each* occurence of iNeedle in iHayStack with iReplaceWith +extern void ReplaceString(AString & iHayStack, const AString & iNeedle, const AString & iReplaceWith); + +/// Returns the list of all items in the specified directory (files, folders, nix pipes, whatever's there) +extern AStringList GetDirectoryContents(const char * a_Directory); + + + +// If you have any other string helper functions, declare them here + + + + +#endif // STRINGUTILS_H_INCLUDED + + + + diff --git a/source/StructGen.cpp b/source/StructGen.cpp index 5f1d9da74..aa3632204 100644 --- a/source/StructGen.cpp +++ b/source/StructGen.cpp @@ -1,464 +1,464 @@ - -// StructGen.h - -#include "Globals.h" -#include "StructGen.h" -#include "BlockID.h" -#include "Trees.h" - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cStructGenOreNests configuration: - -const int MAX_HEIGHT_COAL = 127; -const int NUM_NESTS_COAL = 60; -const int NEST_SIZE_COAL = 10; - -const int MAX_HEIGHT_IRON = 70; -const int NUM_NESTS_IRON = 30; -const int NEST_SIZE_IRON = 6; - -const int MAX_HEIGHT_REDSTONE = 40; -const int NUM_NESTS_REDSTONE = 10; -const int NEST_SIZE_REDSTONE = 6; - -const int MAX_HEIGHT_GOLD = 35; -const int NUM_NESTS_GOLD = 6; -const int NEST_SIZE_GOLD = 6; - -const int MAX_HEIGHT_DIAMOND = 16; -const int NUM_NESTS_DIAMOND = 6; -const int NEST_SIZE_DIAMOND = 5; - -const int MAX_HEIGHT_LAPIS = 30; -const int NUM_NESTS_LAPIS = 6; -const int NEST_SIZE_LAPIS = 5; - - - - - -template T Clamp(T a_Value, T a_Min, T a_Max) -{ - return (a_Value < a_Min) ? a_Min : ((a_Value > a_Max) ? a_Max : a_Value); -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cStructGenTrees: - -void cStructGenTrees::GenStructures( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change - cChunkDef::BlockNibbles & a_BlockMetas, // Block meta to read and change - cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data - cEntityList & a_Entities, // Entities may be added or deleted - cBlockEntityList & a_BlockEntities // Block entities may be added or deleted -) -{ - cChunkDef::BlockTypes WorkerBlockTypes; - cChunkDef::BlockNibbles WorkerBlockMeta; - cChunkDef::HeightMap WorkerHeight; - - cEntityList Entities; - cBlockEntityList BlockEntities; - - // Generate trees: - for (int x = 0; x <= 2; x++) - { - int BaseX = a_ChunkX + x - 1; - for (int z = 0; z <= 2; z++) - { - int BaseZ = a_ChunkZ + z - 1; - sSetBlockVector Outside; - - cChunkDef::BlockTypes * BlT; - cChunkDef::BlockNibbles * BlM; - cChunkDef::HeightMap * Hei; - - cChunkDef::BiomeMap Biomes; - m_BiomeGen->GenBiomes(BaseX, BaseZ, Biomes); - - if ((x != 1) || (z != 1)) - { - BlT = &WorkerBlockTypes; - BlM = &WorkerBlockMeta; - Hei = &WorkerHeight; - - m_HeightGen->GenHeightMap (BaseX, BaseZ, *Hei); - m_CompositionGen->ComposeTerrain(BaseX, BaseZ, *BlT, *BlM, *Hei, Biomes, Entities, BlockEntities); - // TODO: Free the entity lists - } - else - { - BlT = &a_BlockTypes; - BlM = &a_BlockMetas; - Hei = &a_HeightMap; - } - - int NumTrees = GetNumTrees(BaseX, BaseZ, Biomes); - - for (int i = 0; i < NumTrees; i++) - { - GenerateSingleTree(BaseX, BaseZ, i, *BlT, *BlM, *Hei, Biomes, Outside); - } - - // Integrate blocks in Outside into chunk: - for (sSetBlockVector::const_iterator itr = Outside.begin(); itr != Outside.end(); ++itr) - { - if ((itr->ChunkX != a_ChunkX) || (itr->ChunkZ != a_ChunkZ)) - { - continue; - } - switch (cChunkDef::GetBlock(a_BlockTypes, itr->x, itr->y, itr->z)) - { - CASE_TREE_OVERWRITTEN_BLOCKS: - { - cChunkDef::SetBlock (a_BlockTypes, itr->x, itr->y, itr->z, itr->BlockType); - cChunkDef::SetNibble(a_BlockMetas, itr->x, itr->y, itr->z, itr->BlockMeta); - break; - } - } // switch (GetBlock()) - } // for itr - Outside[] - } // for z - } // for x - - // Update the heightmap: - for (int x = 0; x < cChunkDef::Width; x++) - { - for (int z = 0; z < cChunkDef::Width; z++) - { - for (int y = cChunkDef::Height - 1; y >= 0; y--) - { - if (cChunkDef::GetBlock(a_BlockTypes, x, y, z) != E_BLOCK_AIR) - { - cChunkDef::SetHeight(a_HeightMap, x, z, y); - break; - } - } // for y - } // for z - } // for x -} - - - - - -void cStructGenTrees::GenerateSingleTree( - int a_ChunkX, int a_ChunkZ, int a_Seq, - cChunkDef::BlockTypes & a_BlockTypes, - cChunkDef::BlockNibbles & a_BlockMetas, - const cChunkDef::HeightMap & a_Height, - const cChunkDef::BiomeMap & a_Biomes, - sSetBlockVector & a_Blocks -) -{ - int x = m_Noise.IntNoise3DInt(a_ChunkX + a_ChunkZ, a_ChunkZ, a_Seq) % cChunkDef::Width; - int z = m_Noise.IntNoise3DInt(a_ChunkX - a_ChunkZ, a_Seq, a_ChunkZ) % cChunkDef::Width; - - int Height = a_Height[x + cChunkDef::Width * z]; - - if ((Height <= 0) || (Height > 240)) - { - return; - } - - // Check the block underneath the tree: - BLOCKTYPE TopBlock = cChunkDef::GetBlock(a_BlockTypes, x, Height, z); - if ((TopBlock != E_BLOCK_DIRT) && (TopBlock != E_BLOCK_GRASS) && (TopBlock != E_BLOCK_SOIL)) - { - return; - } - - sSetBlockVector TreeBlocks; - GetTreeImageByBiome(a_ChunkX * cChunkDef::Width + x, Height + 1, a_ChunkZ * cChunkDef::Width + z, m_Noise, a_Seq, a_Biomes[x + cChunkDef::Width * z], TreeBlocks); - - // Check if the generated image fits the terrain: - for (sSetBlockVector::const_iterator itr = TreeBlocks.begin(); itr != TreeBlocks.end(); ++itr) - { - if ((itr->ChunkX != a_ChunkX) || (itr->ChunkZ != a_ChunkZ) || (itr->BlockType != E_BLOCK_LOG)) - { - // Outside the chunk, or not a log (we don't check non-logs) - continue; - } - - BLOCKTYPE Block = cChunkDef::GetBlock(a_BlockTypes, itr->x, itr->y, itr->z); - switch (Block) - { - CASE_TREE_ALLOWED_BLOCKS: - { - break; - } - default: - { - // There's something in the way, abort this tree altogether - return; - } - } - } - - // Put the generated image into a_BlockTypes, push things outside this chunk into a_Blocks - for (sSetBlockVector::const_iterator itr = TreeBlocks.begin(); itr != TreeBlocks.end(); ++itr) - { - if ((itr->ChunkX == a_ChunkX) && (itr->ChunkZ == a_ChunkZ)) - { - // Inside this chunk, integrate into a_BlockTypes: - switch (cChunkDef::GetBlock(a_BlockTypes, itr->x, itr->y, itr->z)) - { - CASE_TREE_OVERWRITTEN_BLOCKS: - { - cChunkDef::SetBlock (a_BlockTypes, itr->x, itr->y, itr->z, itr->BlockType); - cChunkDef::SetNibble(a_BlockMetas, itr->x, itr->y, itr->z, itr->BlockMeta); - break; - } - } // switch (GetBlock()) - continue; - } - - // Outside the chunk, push into a_Blocks; check if already present there: - bool Found = false; - for (sSetBlockVector::iterator itrB = a_Blocks.begin(); itrB != a_Blocks.end(); ++itrB) - { - if ( - (itr->ChunkX == itrB->ChunkX) && - (itr->ChunkZ == itrB->ChunkZ) && - (itr->x == itrB->x) && - (itr->y == itrB->y) && - (itr->z == itrB->z) - ) - { - // Same coords already found in a_Blocks, overwrite with wood, if requested: - if (itr->BlockType == E_BLOCK_LOG) - { - itrB->BlockType = itr->BlockType; - itrB->BlockMeta = itr->BlockMeta; - } - Found = true; - break; - } - } // for itrB - a_Blocks[] - if (!Found) - { - a_Blocks.push_back(*itr); - } - } -} - - - - - -int cStructGenTrees::GetNumTrees( - int a_ChunkX, int a_ChunkZ, - const cChunkDef::BiomeMap & a_Biomes -) -{ - int NumTrees = 0; - for (int x = 0; x < cChunkDef::Width; x++) for (int z = 0; z < cChunkDef::Width; z++) - { - int Add = 0; - switch (a_Biomes[x + cChunkDef::Width * z]) - { - case biPlains: Add = 1; break; - case biExtremeHills: Add = 3; break; - case biForest: Add = 30; break; - case biTaiga: Add = 30; break; - case biSwampland: Add = 8; break; - case biIcePlains: Add = 1; break; - case biIceMountains: Add = 1; break; - case biMushroomIsland: Add = 3; break; - case biMushroomShore: Add = 3; break; - case biForestHills: Add = 20; break; - case biTaigaHills: Add = 20; break; - case biExtremeHillsEdge: Add = 5; break; - case biJungle: Add = 120; break; - case biJungleHills: Add = 90; break; - } - NumTrees += Add; - } - return NumTrees / 1024; -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cStructGenMarbleCaves: - -static float GetMarbleNoise( float x, float y, float z, cNoise & a_Noise ) -{ - static const float PI_2 = 1.57079633f; - float oct1 = (a_Noise.CubicNoise3D(x * 0.1f, y * 0.1f, z * 0.1f )) * 4; - - oct1 = oct1 * oct1 * oct1; - if (oct1 < 0.f) oct1 = PI_2; - if (oct1 > PI_2) oct1 = PI_2; - - return oct1; -} - - - - - -void cStructGenMarbleCaves::GenStructures( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change - cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change - cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data - cEntityList & a_Entities, // Entities may be added or deleted - cBlockEntityList & a_BlockEntities // Block entities may be added or deleted -) -{ - cNoise Noise(m_Seed); - for (int z = 0; z < cChunkDef::Width; z++) - { - const float zz = (float)(a_ChunkZ * cChunkDef::Width + z); - for (int x = 0; x < cChunkDef::Width; x++) - { - const float xx = (float)(a_ChunkX * cChunkDef::Width + x); - - int Top = cChunkDef::GetHeight(a_HeightMap, x, z); - for (int y = 1; y < Top; ++y ) - { - if (cChunkDef::GetBlock(a_BlockTypes, x, y, z) != E_BLOCK_STONE) - { - continue; - } - - const float yy = (float)y; - const float WaveNoise = 1; - if (cosf(GetMarbleNoise(xx, yy * 0.5f, zz, Noise)) * fabs(cosf(yy * 0.2f + WaveNoise * 2) * 0.75f + WaveNoise) > 0.0005f) - { - if (y > 4) - { - cChunkDef::SetBlock(a_BlockTypes, x, y, z, E_BLOCK_AIR); - } - else - { - cChunkDef::SetBlock(a_BlockTypes, x, y, z, E_BLOCK_STATIONARY_LAVA); - } - } - } // for y - } // for x - } // for z -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cStructGenOreNests: - -void cStructGenOreNests::GenStructures( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change - cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change - cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data - cEntityList & a_Entities, // Entities may be added or deleted - cBlockEntityList & a_BlockEntities // Block entities may be added or deleted -) -{ - GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_COAL_ORE, MAX_HEIGHT_COAL, NUM_NESTS_COAL, NEST_SIZE_COAL, a_BlockTypes, 1); - GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_IRON_ORE, MAX_HEIGHT_IRON, NUM_NESTS_IRON, NEST_SIZE_IRON, a_BlockTypes, 2); - GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_REDSTONE_ORE, MAX_HEIGHT_REDSTONE, NUM_NESTS_REDSTONE, NEST_SIZE_REDSTONE, a_BlockTypes, 3); - GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_GOLD_ORE, MAX_HEIGHT_GOLD, NUM_NESTS_GOLD, NEST_SIZE_GOLD, a_BlockTypes, 4); - GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_DIAMOND_ORE, MAX_HEIGHT_DIAMOND, NUM_NESTS_DIAMOND, NEST_SIZE_DIAMOND, a_BlockTypes, 5); - GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_LAPIS_ORE, MAX_HEIGHT_LAPIS, NUM_NESTS_LAPIS, NEST_SIZE_LAPIS, a_BlockTypes, 6); -} - - - - - -void cStructGenOreNests::GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_OreType, int a_MaxHeight, int a_NumNests, int a_NestSize, cChunkDef::BlockTypes & a_BlockTypes, int a_Seq) -{ - // This function generates several "nests" of ore, each nest consisting of number of ore blocks relatively adjacent to each other. - // It does so by making a random XYZ walk and adding ore along the way in cuboids of different (random) sizes - // Only stone gets replaced with ore, all other blocks stay (so the nest can actually be smaller than specified). - - for (int i = 0; i < a_NumNests; i++) - { - int rnd = m_Noise.IntNoise3DInt(a_ChunkX + i, a_Seq, a_ChunkZ + 64 * i) / 8; - int BaseX = rnd % cChunkDef::Width; - rnd /= cChunkDef::Width; - int BaseZ = rnd % cChunkDef::Width; - rnd /= cChunkDef::Width; - int BaseY = rnd % a_MaxHeight; - rnd /= a_MaxHeight; - int NestSize = a_NestSize + (rnd % (a_NestSize / 4)); // The actual nest size may be up to 1/4 larger - int Num = 0; - while (Num < NestSize) - { - // Put a cuboid around [BaseX, BaseY, BaseZ] - int rnd = m_Noise.IntNoise3DInt(a_ChunkX + 64 * i, 2 * a_Seq + Num, a_ChunkZ + 32 * i) / 8; - int xsize = rnd % 2; - int ysize = (rnd / 4) % 2; - int zsize = (rnd / 16) % 2; - rnd >>= 8; - for (int x = xsize; x >= 0; --x) - { - int BlockX = BaseX + x; - if ((BlockX < 0) || (BlockX >= cChunkDef::Width)) - { - Num++; // So that the cycle finishes even if the base coords wander away from the chunk - continue; - } - for (int y = ysize; y >= 0; --y) - { - int BlockY = BaseY + y; - if ((BlockY < 0) || (BlockY >= cChunkDef::Height)) - { - Num++; // So that the cycle finishes even if the base coords wander away from the chunk - continue; - } - for (int z = zsize; z >= 0; --z) - { - int BlockZ = BaseZ + z; - if ((BlockZ < 0) || (BlockZ >= cChunkDef::Width)) - { - Num++; // So that the cycle finishes even if the base coords wander away from the chunk - continue; - } - - int Index = cChunkDef::MakeIndexNoCheck(BlockX, BlockY, BlockZ); - if (a_BlockTypes[Index] == E_BLOCK_STONE) - { - a_BlockTypes[Index] = a_OreType; - } - Num++; - } // for z - } // for y - } // for x - - // Move the base to a neighbor voxel - switch (rnd % 4) - { - case 0: BaseX--; break; - case 1: BaseX++; break; - } - switch ((rnd >> 3) % 4) - { - case 0: BaseY--; break; - case 1: BaseY++; break; - } - switch ((rnd >> 6) % 4) - { - case 0: BaseZ--; break; - case 1: BaseZ++; break; - } - } // while (Num < NumBlocks) - } // for i - NumNests -} - - - - + +// StructGen.h + +#include "Globals.h" +#include "StructGen.h" +#include "BlockID.h" +#include "Trees.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cStructGenOreNests configuration: + +const int MAX_HEIGHT_COAL = 127; +const int NUM_NESTS_COAL = 60; +const int NEST_SIZE_COAL = 10; + +const int MAX_HEIGHT_IRON = 70; +const int NUM_NESTS_IRON = 30; +const int NEST_SIZE_IRON = 6; + +const int MAX_HEIGHT_REDSTONE = 40; +const int NUM_NESTS_REDSTONE = 10; +const int NEST_SIZE_REDSTONE = 6; + +const int MAX_HEIGHT_GOLD = 35; +const int NUM_NESTS_GOLD = 6; +const int NEST_SIZE_GOLD = 6; + +const int MAX_HEIGHT_DIAMOND = 16; +const int NUM_NESTS_DIAMOND = 6; +const int NEST_SIZE_DIAMOND = 5; + +const int MAX_HEIGHT_LAPIS = 30; +const int NUM_NESTS_LAPIS = 6; +const int NEST_SIZE_LAPIS = 5; + + + + + +template T Clamp(T a_Value, T a_Min, T a_Max) +{ + return (a_Value < a_Min) ? a_Min : ((a_Value > a_Max) ? a_Max : a_Value); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cStructGenTrees: + +void cStructGenTrees::GenStructures( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMetas, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted +) +{ + cChunkDef::BlockTypes WorkerBlockTypes; + cChunkDef::BlockNibbles WorkerBlockMeta; + cChunkDef::HeightMap WorkerHeight; + + cEntityList Entities; + cBlockEntityList BlockEntities; + + // Generate trees: + for (int x = 0; x <= 2; x++) + { + int BaseX = a_ChunkX + x - 1; + for (int z = 0; z <= 2; z++) + { + int BaseZ = a_ChunkZ + z - 1; + sSetBlockVector Outside; + + cChunkDef::BlockTypes * BlT; + cChunkDef::BlockNibbles * BlM; + cChunkDef::HeightMap * Hei; + + cChunkDef::BiomeMap Biomes; + m_BiomeGen->GenBiomes(BaseX, BaseZ, Biomes); + + if ((x != 1) || (z != 1)) + { + BlT = &WorkerBlockTypes; + BlM = &WorkerBlockMeta; + Hei = &WorkerHeight; + + m_HeightGen->GenHeightMap (BaseX, BaseZ, *Hei); + m_CompositionGen->ComposeTerrain(BaseX, BaseZ, *BlT, *BlM, *Hei, Biomes, Entities, BlockEntities); + // TODO: Free the entity lists + } + else + { + BlT = &a_BlockTypes; + BlM = &a_BlockMetas; + Hei = &a_HeightMap; + } + + int NumTrees = GetNumTrees(BaseX, BaseZ, Biomes); + + for (int i = 0; i < NumTrees; i++) + { + GenerateSingleTree(BaseX, BaseZ, i, *BlT, *BlM, *Hei, Biomes, Outside); + } + + // Integrate blocks in Outside into chunk: + for (sSetBlockVector::const_iterator itr = Outside.begin(); itr != Outside.end(); ++itr) + { + if ((itr->ChunkX != a_ChunkX) || (itr->ChunkZ != a_ChunkZ)) + { + continue; + } + switch (cChunkDef::GetBlock(a_BlockTypes, itr->x, itr->y, itr->z)) + { + CASE_TREE_OVERWRITTEN_BLOCKS: + { + cChunkDef::SetBlock (a_BlockTypes, itr->x, itr->y, itr->z, itr->BlockType); + cChunkDef::SetNibble(a_BlockMetas, itr->x, itr->y, itr->z, itr->BlockMeta); + break; + } + } // switch (GetBlock()) + } // for itr - Outside[] + } // for z + } // for x + + // Update the heightmap: + for (int x = 0; x < cChunkDef::Width; x++) + { + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int y = cChunkDef::Height - 1; y >= 0; y--) + { + if (cChunkDef::GetBlock(a_BlockTypes, x, y, z) != E_BLOCK_AIR) + { + cChunkDef::SetHeight(a_HeightMap, x, z, y); + break; + } + } // for y + } // for z + } // for x +} + + + + + +void cStructGenTrees::GenerateSingleTree( + int a_ChunkX, int a_ChunkZ, int a_Seq, + cChunkDef::BlockTypes & a_BlockTypes, + cChunkDef::BlockNibbles & a_BlockMetas, + const cChunkDef::HeightMap & a_Height, + const cChunkDef::BiomeMap & a_Biomes, + sSetBlockVector & a_Blocks +) +{ + int x = m_Noise.IntNoise3DInt(a_ChunkX + a_ChunkZ, a_ChunkZ, a_Seq) % cChunkDef::Width; + int z = m_Noise.IntNoise3DInt(a_ChunkX - a_ChunkZ, a_Seq, a_ChunkZ) % cChunkDef::Width; + + int Height = a_Height[x + cChunkDef::Width * z]; + + if ((Height <= 0) || (Height > 240)) + { + return; + } + + // Check the block underneath the tree: + BLOCKTYPE TopBlock = cChunkDef::GetBlock(a_BlockTypes, x, Height, z); + if ((TopBlock != E_BLOCK_DIRT) && (TopBlock != E_BLOCK_GRASS) && (TopBlock != E_BLOCK_SOIL)) + { + return; + } + + sSetBlockVector TreeBlocks; + GetTreeImageByBiome(a_ChunkX * cChunkDef::Width + x, Height + 1, a_ChunkZ * cChunkDef::Width + z, m_Noise, a_Seq, a_Biomes[x + cChunkDef::Width * z], TreeBlocks); + + // Check if the generated image fits the terrain: + for (sSetBlockVector::const_iterator itr = TreeBlocks.begin(); itr != TreeBlocks.end(); ++itr) + { + if ((itr->ChunkX != a_ChunkX) || (itr->ChunkZ != a_ChunkZ) || (itr->BlockType != E_BLOCK_LOG)) + { + // Outside the chunk, or not a log (we don't check non-logs) + continue; + } + + BLOCKTYPE Block = cChunkDef::GetBlock(a_BlockTypes, itr->x, itr->y, itr->z); + switch (Block) + { + CASE_TREE_ALLOWED_BLOCKS: + { + break; + } + default: + { + // There's something in the way, abort this tree altogether + return; + } + } + } + + // Put the generated image into a_BlockTypes, push things outside this chunk into a_Blocks + for (sSetBlockVector::const_iterator itr = TreeBlocks.begin(); itr != TreeBlocks.end(); ++itr) + { + if ((itr->ChunkX == a_ChunkX) && (itr->ChunkZ == a_ChunkZ)) + { + // Inside this chunk, integrate into a_BlockTypes: + switch (cChunkDef::GetBlock(a_BlockTypes, itr->x, itr->y, itr->z)) + { + CASE_TREE_OVERWRITTEN_BLOCKS: + { + cChunkDef::SetBlock (a_BlockTypes, itr->x, itr->y, itr->z, itr->BlockType); + cChunkDef::SetNibble(a_BlockMetas, itr->x, itr->y, itr->z, itr->BlockMeta); + break; + } + } // switch (GetBlock()) + continue; + } + + // Outside the chunk, push into a_Blocks; check if already present there: + bool Found = false; + for (sSetBlockVector::iterator itrB = a_Blocks.begin(); itrB != a_Blocks.end(); ++itrB) + { + if ( + (itr->ChunkX == itrB->ChunkX) && + (itr->ChunkZ == itrB->ChunkZ) && + (itr->x == itrB->x) && + (itr->y == itrB->y) && + (itr->z == itrB->z) + ) + { + // Same coords already found in a_Blocks, overwrite with wood, if requested: + if (itr->BlockType == E_BLOCK_LOG) + { + itrB->BlockType = itr->BlockType; + itrB->BlockMeta = itr->BlockMeta; + } + Found = true; + break; + } + } // for itrB - a_Blocks[] + if (!Found) + { + a_Blocks.push_back(*itr); + } + } +} + + + + + +int cStructGenTrees::GetNumTrees( + int a_ChunkX, int a_ChunkZ, + const cChunkDef::BiomeMap & a_Biomes +) +{ + int NumTrees = 0; + for (int x = 0; x < cChunkDef::Width; x++) for (int z = 0; z < cChunkDef::Width; z++) + { + int Add = 0; + switch (a_Biomes[x + cChunkDef::Width * z]) + { + case biPlains: Add = 1; break; + case biExtremeHills: Add = 3; break; + case biForest: Add = 30; break; + case biTaiga: Add = 30; break; + case biSwampland: Add = 8; break; + case biIcePlains: Add = 1; break; + case biIceMountains: Add = 1; break; + case biMushroomIsland: Add = 3; break; + case biMushroomShore: Add = 3; break; + case biForestHills: Add = 20; break; + case biTaigaHills: Add = 20; break; + case biExtremeHillsEdge: Add = 5; break; + case biJungle: Add = 120; break; + case biJungleHills: Add = 90; break; + } + NumTrees += Add; + } + return NumTrees / 1024; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cStructGenMarbleCaves: + +static float GetMarbleNoise( float x, float y, float z, cNoise & a_Noise ) +{ + static const float PI_2 = 1.57079633f; + float oct1 = (a_Noise.CubicNoise3D(x * 0.1f, y * 0.1f, z * 0.1f )) * 4; + + oct1 = oct1 * oct1 * oct1; + if (oct1 < 0.f) oct1 = PI_2; + if (oct1 > PI_2) oct1 = PI_2; + + return oct1; +} + + + + + +void cStructGenMarbleCaves::GenStructures( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted +) +{ + cNoise Noise(m_Seed); + for (int z = 0; z < cChunkDef::Width; z++) + { + const float zz = (float)(a_ChunkZ * cChunkDef::Width + z); + for (int x = 0; x < cChunkDef::Width; x++) + { + const float xx = (float)(a_ChunkX * cChunkDef::Width + x); + + int Top = cChunkDef::GetHeight(a_HeightMap, x, z); + for (int y = 1; y < Top; ++y ) + { + if (cChunkDef::GetBlock(a_BlockTypes, x, y, z) != E_BLOCK_STONE) + { + continue; + } + + const float yy = (float)y; + const float WaveNoise = 1; + if (cosf(GetMarbleNoise(xx, yy * 0.5f, zz, Noise)) * fabs(cosf(yy * 0.2f + WaveNoise * 2) * 0.75f + WaveNoise) > 0.0005f) + { + if (y > 4) + { + cChunkDef::SetBlock(a_BlockTypes, x, y, z, E_BLOCK_AIR); + } + else + { + cChunkDef::SetBlock(a_BlockTypes, x, y, z, E_BLOCK_STATIONARY_LAVA); + } + } + } // for y + } // for x + } // for z +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cStructGenOreNests: + +void cStructGenOreNests::GenStructures( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted +) +{ + GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_COAL_ORE, MAX_HEIGHT_COAL, NUM_NESTS_COAL, NEST_SIZE_COAL, a_BlockTypes, 1); + GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_IRON_ORE, MAX_HEIGHT_IRON, NUM_NESTS_IRON, NEST_SIZE_IRON, a_BlockTypes, 2); + GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_REDSTONE_ORE, MAX_HEIGHT_REDSTONE, NUM_NESTS_REDSTONE, NEST_SIZE_REDSTONE, a_BlockTypes, 3); + GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_GOLD_ORE, MAX_HEIGHT_GOLD, NUM_NESTS_GOLD, NEST_SIZE_GOLD, a_BlockTypes, 4); + GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_DIAMOND_ORE, MAX_HEIGHT_DIAMOND, NUM_NESTS_DIAMOND, NEST_SIZE_DIAMOND, a_BlockTypes, 5); + GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_LAPIS_ORE, MAX_HEIGHT_LAPIS, NUM_NESTS_LAPIS, NEST_SIZE_LAPIS, a_BlockTypes, 6); +} + + + + + +void cStructGenOreNests::GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_OreType, int a_MaxHeight, int a_NumNests, int a_NestSize, cChunkDef::BlockTypes & a_BlockTypes, int a_Seq) +{ + // This function generates several "nests" of ore, each nest consisting of number of ore blocks relatively adjacent to each other. + // It does so by making a random XYZ walk and adding ore along the way in cuboids of different (random) sizes + // Only stone gets replaced with ore, all other blocks stay (so the nest can actually be smaller than specified). + + for (int i = 0; i < a_NumNests; i++) + { + int rnd = m_Noise.IntNoise3DInt(a_ChunkX + i, a_Seq, a_ChunkZ + 64 * i) / 8; + int BaseX = rnd % cChunkDef::Width; + rnd /= cChunkDef::Width; + int BaseZ = rnd % cChunkDef::Width; + rnd /= cChunkDef::Width; + int BaseY = rnd % a_MaxHeight; + rnd /= a_MaxHeight; + int NestSize = a_NestSize + (rnd % (a_NestSize / 4)); // The actual nest size may be up to 1/4 larger + int Num = 0; + while (Num < NestSize) + { + // Put a cuboid around [BaseX, BaseY, BaseZ] + int rnd = m_Noise.IntNoise3DInt(a_ChunkX + 64 * i, 2 * a_Seq + Num, a_ChunkZ + 32 * i) / 8; + int xsize = rnd % 2; + int ysize = (rnd / 4) % 2; + int zsize = (rnd / 16) % 2; + rnd >>= 8; + for (int x = xsize; x >= 0; --x) + { + int BlockX = BaseX + x; + if ((BlockX < 0) || (BlockX >= cChunkDef::Width)) + { + Num++; // So that the cycle finishes even if the base coords wander away from the chunk + continue; + } + for (int y = ysize; y >= 0; --y) + { + int BlockY = BaseY + y; + if ((BlockY < 0) || (BlockY >= cChunkDef::Height)) + { + Num++; // So that the cycle finishes even if the base coords wander away from the chunk + continue; + } + for (int z = zsize; z >= 0; --z) + { + int BlockZ = BaseZ + z; + if ((BlockZ < 0) || (BlockZ >= cChunkDef::Width)) + { + Num++; // So that the cycle finishes even if the base coords wander away from the chunk + continue; + } + + int Index = cChunkDef::MakeIndexNoCheck(BlockX, BlockY, BlockZ); + if (a_BlockTypes[Index] == E_BLOCK_STONE) + { + a_BlockTypes[Index] = a_OreType; + } + Num++; + } // for z + } // for y + } // for x + + // Move the base to a neighbor voxel + switch (rnd % 4) + { + case 0: BaseX--; break; + case 1: BaseX++; break; + } + switch ((rnd >> 3) % 4) + { + case 0: BaseY--; break; + case 1: BaseY++; break; + } + switch ((rnd >> 6) % 4) + { + case 0: BaseZ--; break; + case 1: BaseZ++; break; + } + } // while (Num < NumBlocks) + } // for i - NumNests +} + + + + diff --git a/source/StructGen.h b/source/StructGen.h index 3f5c2e2a2..8b799d013 100644 --- a/source/StructGen.h +++ b/source/StructGen.h @@ -1,122 +1,122 @@ - -// StructGen.h - -/* Interfaces to the various structure generators: - - cStructGenTrees - - cStructGenMarbleCaves - - cStructGenOres -*/ - - - - - -#pragma once - -#include "cChunkGenerator.h" -#include "cNoise.h" - - - - - -class cStructGenTrees : - public cStructureGen -{ -public: - cStructGenTrees(int a_Seed, cBiomeGen * a_BiomeGen, cTerrainHeightGen * a_HeightGen, cTerrainCompositionGen * a_CompositionGen) : - m_Seed(a_Seed), - m_Noise(a_Seed), - m_BiomeGen(a_BiomeGen), - m_HeightGen(a_HeightGen), - m_CompositionGen(a_CompositionGen) - {} - -protected: - - int m_Seed; - cNoise m_Noise; - cBiomeGen * m_BiomeGen; - cTerrainHeightGen * m_HeightGen; - cTerrainCompositionGen * m_CompositionGen; - - void GenerateSingleTree( - int a_ChunkX, int a_ChunkZ, int a_Seq, - cChunkDef::BlockTypes & a_BlockTypes, - cChunkDef::BlockNibbles & a_BlockMetas, - const cChunkDef::HeightMap & a_Height, - const cChunkDef::BiomeMap & a_Biomes, - sSetBlockVector & a_Blocks - ) ; - - int GetNumTrees( - int a_ChunkX, int a_ChunkZ, - const cChunkDef::BiomeMap & a_Biomes - ); - - // cStructureGen override: - virtual void GenStructures( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change - cChunkDef::BlockNibbles & a_BlockMetas, // Block meta to read and change - cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data - cEntityList & a_Entities, // Entities may be added or deleted - cBlockEntityList & a_BlockEntities // Block entities may be added or deleted - ) override; -} ; - - - - - -class cStructGenMarbleCaves : - public cStructureGen -{ -public: - cStructGenMarbleCaves(int a_Seed) : m_Seed(a_Seed) {} - -protected: - - int m_Seed; - - // cStructureGen override: - virtual void GenStructures( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change - cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change - cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data - cEntityList & a_Entities, // Entities may be added or deleted - cBlockEntityList & a_BlockEntities // Block entities may be added or deleted - ) override; -} ; - - - - - -class cStructGenOreNests : - public cStructureGen -{ -public: - cStructGenOreNests(int a_Seed) : m_Noise(a_Seed), m_Seed(a_Seed) {} - -protected: - cNoise m_Noise; - int m_Seed; - - // cStructureGen override: - virtual void GenStructures( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change - cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change - cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data - cEntityList & a_Entities, // Entities may be added or deleted - cBlockEntityList & a_BlockEntities // Block entities may be added or deleted - ) override; - - void GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_OreType, int a_MaxHeight, int a_NumNests, int a_NestSize, cChunkDef::BlockTypes & a_BlockTypes, int a_Seq); -} ; - - - - + +// StructGen.h + +/* Interfaces to the various structure generators: + - cStructGenTrees + - cStructGenMarbleCaves + - cStructGenOres +*/ + + + + + +#pragma once + +#include "cChunkGenerator.h" +#include "cNoise.h" + + + + + +class cStructGenTrees : + public cStructureGen +{ +public: + cStructGenTrees(int a_Seed, cBiomeGen * a_BiomeGen, cTerrainHeightGen * a_HeightGen, cTerrainCompositionGen * a_CompositionGen) : + m_Seed(a_Seed), + m_Noise(a_Seed), + m_BiomeGen(a_BiomeGen), + m_HeightGen(a_HeightGen), + m_CompositionGen(a_CompositionGen) + {} + +protected: + + int m_Seed; + cNoise m_Noise; + cBiomeGen * m_BiomeGen; + cTerrainHeightGen * m_HeightGen; + cTerrainCompositionGen * m_CompositionGen; + + void GenerateSingleTree( + int a_ChunkX, int a_ChunkZ, int a_Seq, + cChunkDef::BlockTypes & a_BlockTypes, + cChunkDef::BlockNibbles & a_BlockMetas, + const cChunkDef::HeightMap & a_Height, + const cChunkDef::BiomeMap & a_Biomes, + sSetBlockVector & a_Blocks + ) ; + + int GetNumTrees( + int a_ChunkX, int a_ChunkZ, + const cChunkDef::BiomeMap & a_Biomes + ); + + // cStructureGen override: + virtual void GenStructures( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMetas, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) override; +} ; + + + + + +class cStructGenMarbleCaves : + public cStructureGen +{ +public: + cStructGenMarbleCaves(int a_Seed) : m_Seed(a_Seed) {} + +protected: + + int m_Seed; + + // cStructureGen override: + virtual void GenStructures( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) override; +} ; + + + + + +class cStructGenOreNests : + public cStructureGen +{ +public: + cStructGenOreNests(int a_Seed) : m_Noise(a_Seed), m_Seed(a_Seed) {} + +protected: + cNoise m_Noise; + int m_Seed; + + // cStructureGen override: + virtual void GenStructures( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) override; + + void GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_OreType, int a_MaxHeight, int a_NumNests, int a_NestSize, cChunkDef::BlockTypes & a_BlockTypes, int a_Seq); +} ; + + + + diff --git a/source/Trees.cpp b/source/Trees.cpp index 7d82c3ef9..f6734d85c 100644 --- a/source/Trees.cpp +++ b/source/Trees.cpp @@ -1,538 +1,538 @@ - -// Trees.cpp - -// Implements helper functions used for generating trees - -#include "Globals.h" -#include "Trees.h" -#include "BlockID.h" - - - - - -typedef struct -{ - int x, z; -} sCoords; - -typedef struct -{ - int x, z; - NIBBLETYPE Meta; -} sMetaCoords; - -static const sCoords Corners[] = -{ - {-1, -1}, - {-1, 1}, - {1, -1}, - {1, 1}, -} ; - -static const sCoords BigO1[] = -{ - {0, -1}, - {-1, 0}, {1, 0}, - {0, 1}, -} ; - -static const sCoords BigO2[] = -{ - {-1, -2}, {0, -2}, {1, -2}, - {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1}, - {-2, 0}, {-1, 0}, {1, 0}, {2, 0}, - {-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1}, - {-1, 2}, {0, 2}, {1, 2}, -} ; - -static const sCoords BigO3[] = -{ - {-2, -3}, {-1, -3}, {0, -3}, {1, -3}, {2, -3}, - {-3, -2}, {-2, -2}, {-1, -2}, {0, -2}, {1, -2}, {2, -2}, {3, -2}, - {-3, -1}, {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1}, {3, -1}, - {-3, 0}, {-2, 0}, {-1, 0}, {1, 0}, {2, 0}, {3, 0}, - {-3, 1}, {-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1}, {3, 1}, - {-3, 2}, {-2, 2}, {-1, 2}, {0, 2}, {1, 2}, {2, 2}, {3, 2}, - {-2, 3}, {-1, 3}, {0, 3}, {1, 3}, {2, 3}, -} ; - -typedef struct -{ - const sCoords * Coords; - size_t Count; -} sCoordsArr; - -static const sCoordsArr BigOs[] = -{ - {BigO1, ARRAYCOUNT(BigO1)}, - {BigO2, ARRAYCOUNT(BigO2)}, - {BigO3, ARRAYCOUNT(BigO3)}, -} ; - - - - - -/// Pushes a specified layer of blocks of the same type around (x, h, z) into a_Blocks -inline void PushCoordBlocks(int a_BlockX, int a_Height, int a_BlockZ, sSetBlockVector & a_Blocks, const sCoords * a_Coords, size_t a_NumCoords, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) -{ - for (size_t i = 0; i < a_NumCoords; i++) - { - a_Blocks.push_back(sSetBlock(a_BlockX + a_Coords[i].x, a_Height, a_BlockZ + a_Coords[i].z, a_BlockType, a_Meta)); - } -} - - - - -inline void PushCornerBlocks(int a_BlockX, int a_Height, int a_BlockZ, int a_Seq, cNoise & a_Noise, int a_Chance, sSetBlockVector & a_Blocks, int a_CornersDist, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) -{ - for (size_t i = 0; i < ARRAYCOUNT(Corners); i++) - { - int x = a_BlockX + Corners[i].x; - int z = a_BlockZ + Corners[i].z; - if (a_Noise.IntNoise3DInt(x + 64 * a_Seq, a_Height, z + 64 * a_Seq) <= a_Chance) - { - a_Blocks.push_back(sSetBlock(x, a_Height, z, a_BlockType, a_Meta)); - } - } // for i - Corners[] -} - - - - - -inline void PushSomeColumns(int a_BlockX, int a_Height, int a_BlockZ, int a_ColumnHeight, int a_Seq, cNoise & a_Noise, int a_Chance, sSetBlockVector & a_Blocks, const sMetaCoords * a_Coords, size_t a_NumCoords, BLOCKTYPE a_BlockType) -{ - for (size_t i = 0; i < a_NumCoords; i++) - { - int x = a_BlockX + a_Coords[i].x; - int z = a_BlockZ + a_Coords[i].z; - if (a_Noise.IntNoise3DInt(x + 64 * a_Seq, a_Height + i, z + 64 * a_Seq) <= a_Chance) - { - for (int j = 0; j < a_ColumnHeight; j++) - { - a_Blocks.push_back(sSetBlock(x, a_Height - j, z, a_BlockType, a_Coords[i].Meta)); - } - } - } // for i - a_Coords[] -} - - - - - -void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, EMCSBiome a_Biome, sSetBlockVector & a_Blocks) -{ - switch (a_Biome) - { - case biPlains: - case biExtremeHills: - case biExtremeHillsEdge: - case biForest: - case biMushroomIsland: - case biMushroomShore: - case biForestHills: - { - // Apple or birch trees: - if (a_Noise.IntNoise3DInt(a_BlockX, a_BlockY + 16 * a_Seq, a_BlockZ + 16 * a_Seq) < 0x5fffffff) - { - GetAppleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); - } - else - { - GetBirchTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); - } - break; - } - - case biTaiga: - case biIcePlains: - case biIceMountains: - case biTaigaHills: - { - // Conifers - GetConiferTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); - break; - } - - case biSwampland: - { - // Swamp trees: - GetSwampTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); - break; - } - - case biJungle: - case biJungleHills: - { - // Apple bushes, jungle trees - if (a_Noise.IntNoise3DInt(a_BlockX, a_BlockY + 16 * a_Seq, a_BlockZ + 16 * a_Seq) < 0x5fffffff) - { - GetAppleBushImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); - } - else - { - GetJungleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); - } - } - } -} - - - - - -void GetAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) -{ - if (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY + 32 * a_Seq, a_BlockZ) < 0x60000000) - { - GetSmallAppleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); - } - else - { - GetLargeAppleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); - } -} - - - - - -void GetSmallAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) -{ - /* Small apple tree has: - - a top plus (no log) - - optional BigO1 + random corners (log) - - 2 layers of BigO2 + random corners (log) - - 1 to 3 blocks of trunk - */ - - int Random = a_Noise.IntNoise3DInt(a_BlockX + 64 * a_Seq, a_BlockY, a_BlockZ) >> 3; - - // Pre-alloc so that we don't realloc too often later: - a_Blocks.reserve(ARRAYCOUNT(BigO2) * 2 + ARRAYCOUNT(BigO1) + ARRAYCOUNT(Corners) * 3 + 3 + 5); - - int Heights[] = {1, 2, 2, 3} ; - int Height = 1 + Heights[Random & 3]; - Random >>= 2; - - // Trunk: - for (int i = 0; i < Height; i++) - { - a_Blocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); - } - int Hei = a_BlockY + Height; - - // 2 BigO2 + corners layers: - for (int i = 0; i < 2; i++) - { - PushCoordBlocks (a_BlockX, Hei, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); - PushCornerBlocks(a_BlockX, Hei, a_BlockZ, a_Seq, a_Noise, 0x5000000 - i * 0x10000000, a_Blocks, 2, E_BLOCK_LEAVES, E_META_LEAVES_APPLE); - a_Blocks.push_back(sSetBlock(a_BlockX, Hei, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); - Hei++; - } // for i - 2* - - // Optional BigO1 + corners layer: - if ((Random & 1) == 0) - { - PushCoordBlocks (a_BlockX, Hei, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); - PushCornerBlocks(a_BlockX, Hei, a_BlockZ, a_Seq, a_Noise, 0x6000000, a_Blocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_APPLE); - a_Blocks.push_back(sSetBlock(a_BlockX, Hei, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); - Hei++; - } - - // Top plus: - PushCoordBlocks(a_BlockX, Hei, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); - a_Blocks.push_back(sSetBlock(a_BlockX, Hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE)); -} - - - - - -void GetLargeAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) -{ - // TODO -} - - - - - -void GetBirchTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) -{ - int Height = 5 + (a_Noise.IntNoise3DInt(a_BlockX + 64 * a_Seq, a_BlockY, a_BlockZ) % 3); - - // Prealloc, so that we don't realloc too often later: - a_Blocks.reserve(Height + 80); - - // The entire trunk, out of logs: - for (int i = Height - 1; i >= 0; --i) - { - a_Blocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_BIRCH)); - } - int h = a_BlockY + Height; - - // Top layer - just the Plus: - PushCoordBlocks(a_BlockX, h, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); - a_Blocks.push_back(sSetBlock(a_BlockX, h, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH)); // There's no log at this layer - h--; - - // Second layer - log, Plus and maybe Corners: - PushCoordBlocks (a_BlockX, h, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); - PushCornerBlocks(a_BlockX, h, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_Blocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); - h--; - - // Third and fourth layers - BigO2 and maybe 2*Corners: - for (int Row = 0; Row < 2; Row++) - { - PushCoordBlocks (a_BlockX, h, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); - PushCornerBlocks(a_BlockX, h, a_BlockZ, a_Seq, a_Noise, 0x3fffffff + Row * 0x10000000, a_Blocks, 2, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); - h--; - } // for Row - 2* -} - - - - - -void GetConiferTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) -{ - // Half chance for a spruce, half for a pine: - if (a_Noise.IntNoise3DInt(a_BlockX + 64 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) < 0x40000000) - { - GetSpruceTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); - } - else - { - GetPineTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); - } -} - - - - - -void GetSpruceTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) -{ - // Spruces have a top section with layer sizes of (0, 1, 0) or only (1, 0), - // then 1 - 3 sections of ascending sizes (1, 2) [most often], (1, 3) or (1, 2, 3) - // and an optional bottom section of size 1, followed by 1 - 3 clear trunk blocks - - // We'll use bits from this number as partial random numbers; but the noise function has mod8 irregularities - // (each of the mod8 remainders has a very different chance of occurrence) - that's why we divide by 8 - int MyRandom = a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY + 32 * a_Seq, a_BlockZ) / 8; - - // Prealloc, so that we don't realloc too often later: - a_Blocks.reserve(180); - - // Clear trunk blocks: - static const int sHeights[] = {1, 2, 2, 3}; - int Height = sHeights[MyRandom & 3]; - MyRandom >>= 2; - for (int i = 0; i < Height; i++) - { - a_Blocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); - } - Height += a_BlockY; - - // Optional size-1 bottom leaves layer: - if ((MyRandom & 1) == 0) - { - PushCoordBlocks(a_BlockX, Height, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); - a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); - Height++; - } - MyRandom >>= 1; - - // 1 to 3 sections of leaves layers: - static const int sNumSections[] = {1, 2, 2, 3}; - int NumSections = sNumSections[MyRandom & 3]; - MyRandom >>= 2; - for (int i = 0; i < NumSections; i++) - { - switch (MyRandom & 3) // SectionType; (1, 2) twice as often as the other two - { - case 0: - case 1: - { - PushCoordBlocks(a_BlockX, Height, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); - PushCoordBlocks(a_BlockX, Height + 1, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); - a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); - a_Blocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); - Height += 2; - break; - } - case 2: - { - PushCoordBlocks(a_BlockX, Height, a_BlockZ, a_Blocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); - PushCoordBlocks(a_BlockX, Height + 1, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); - a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); - a_Blocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); - Height += 2; - break; - } - case 3: - { - PushCoordBlocks(a_BlockX, Height, a_BlockZ, a_Blocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); - PushCoordBlocks(a_BlockX, Height + 1, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); - PushCoordBlocks(a_BlockX, Height + 2, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); - a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); - a_Blocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); - a_Blocks.push_back(sSetBlock(a_BlockX, Height + 2, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); - Height += 3; - break; - } - } // switch (SectionType) - MyRandom >>= 2; - } // for i - Sections - - if ((MyRandom & 1) == 0) - { - // (0, 1, 0) top: - a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); - PushCoordBlocks (a_BlockX, Height + 1, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); - a_Blocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER)); - a_Blocks.push_back(sSetBlock(a_BlockX, Height + 2, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER)); - } - else - { - // (1, 0) top: - a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER)); - PushCoordBlocks (a_BlockX, Height + 1, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); - a_Blocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER)); - } -} - - - - - -void GetPineTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) -{ - // Tall, little leaves on top. The top leaves are arranged in a shape of two cones joined by their bases. - // There can be one or two layers representing the cone bases (SameSizeMax) - - int MyRandom = a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 8; - int TrunkHeight = 8 + (MyRandom % 3); - int SameSizeMax = ((MyRandom & 8) == 0) ? 1 : 0; - MyRandom >>= 3; - int NumLeavesLayers = 2 + (MyRandom % 3); // Number of layers that have leaves in them - if (NumLeavesLayers == 2) - { - SameSizeMax = 0; - } - - // Pre-allocate the vector: - a_Blocks.reserve(TrunkHeight + NumLeavesLayers * 25); - - // The entire trunk, out of logs: - for (int i = TrunkHeight; i >= 0; --i) - { - a_Blocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); - } - int h = a_BlockY + TrunkHeight + 2; - - // Top layer - just a single leaves block: - a_Blocks.push_back(sSetBlock(a_BlockX, h, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER)); - h--; - - // One more layer is above the trunk, push the central leaves: - a_Blocks.push_back(sSetBlock(a_BlockX, h, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER)); - - // Layers expanding in size, then collapsing again: - // LOGD("Generating %d layers of pine leaves, SameSizeMax = %d", NumLeavesLayers, SameSizeMax); - for (int i = 0; i < NumLeavesLayers; ++i) - { - int LayerSize = std::min(i, NumLeavesLayers - i + SameSizeMax - 1); - // LOGD("LayerSize %d: %d", i, LayerSize); - if (LayerSize < 0) - { - break; - } - ASSERT(LayerSize < ARRAYCOUNT(BigOs)); - PushCoordBlocks(a_BlockX, h, a_BlockZ, a_Blocks, BigOs[LayerSize].Coords, BigOs[LayerSize].Count, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); - h--; - } -} - - - - - -void GetSwampTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) -{ - // Vines are around the BigO3, but not in the corners; need proper meta for direction - static const sMetaCoords Vines[] = - { - {-2, -4, 1}, {-1, -4, 1}, {0, -4, 1}, {1, -4, 1}, {2, -4, 1}, // North face - {-2, 4, 4}, {-1, 4, 4}, {0, 4, 4}, {1, 4, 4}, {2, 4, 4}, // South face - {4, -2, 2}, {4, -1, 2}, {4, 0, 2}, {4, 1, 2}, {4, 2, 2}, // East face - {-4, -2, 8}, {-4, -1, 8}, {-4, 0, 8}, {-4, 1, 8}, {-4, 2, 8}, // West face - } ; - - int Height = 3 + (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 8) % 3; - - a_Blocks.reserve(2 * ARRAYCOUNT(BigO2) + 2 * ARRAYCOUNT(BigO3) + Height * ARRAYCOUNT(Vines) + 20); - - for (int i = 0; i < Height; i++) - { - a_Blocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); - } - int hei = a_BlockY + Height - 2; - - // Put vines around the lowermost leaves layer: - PushSomeColumns(a_BlockX, hei, a_BlockZ, Height, a_Seq, a_Noise, 0x3fffffff, a_Blocks, Vines, ARRAYCOUNT(Vines), E_BLOCK_VINES); - - // The lower two leaves layers are BigO3 with log in the middle and possibly corners: - for (int i = 0; i < 2; i++) - { - PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_Blocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); - PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_Blocks, 3, E_BLOCK_LEAVES, E_META_LEAVES_APPLE); - hei++; - } // for i - 2* - - // The upper two leaves layers are BigO2 with leaves in the middle and possibly corners: - for (int i = 0; i < 2; i++) - { - PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); - PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_Blocks, 3, E_BLOCK_LEAVES, E_META_LEAVES_APPLE); - a_Blocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE)); - hei++; - } // for i - 2* -} - - - - - -void GetAppleBushImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) -{ - a_Blocks.reserve(3 + ARRAYCOUNT(BigO2) + ARRAYCOUNT(BigO1)); - - int hei = a_BlockY; - a_Blocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LOG, E_META_LOG_JUNGLE)); - PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); - hei++; - - a_Blocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE)); - PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); - hei++; - - a_Blocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE)); -} - - - - - -void GetJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) -{ - // TODO -} - - - - + +// Trees.cpp + +// Implements helper functions used for generating trees + +#include "Globals.h" +#include "Trees.h" +#include "BlockID.h" + + + + + +typedef struct +{ + int x, z; +} sCoords; + +typedef struct +{ + int x, z; + NIBBLETYPE Meta; +} sMetaCoords; + +static const sCoords Corners[] = +{ + {-1, -1}, + {-1, 1}, + {1, -1}, + {1, 1}, +} ; + +static const sCoords BigO1[] = +{ + {0, -1}, + {-1, 0}, {1, 0}, + {0, 1}, +} ; + +static const sCoords BigO2[] = +{ + {-1, -2}, {0, -2}, {1, -2}, + {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1}, + {-2, 0}, {-1, 0}, {1, 0}, {2, 0}, + {-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1}, + {-1, 2}, {0, 2}, {1, 2}, +} ; + +static const sCoords BigO3[] = +{ + {-2, -3}, {-1, -3}, {0, -3}, {1, -3}, {2, -3}, + {-3, -2}, {-2, -2}, {-1, -2}, {0, -2}, {1, -2}, {2, -2}, {3, -2}, + {-3, -1}, {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1}, {3, -1}, + {-3, 0}, {-2, 0}, {-1, 0}, {1, 0}, {2, 0}, {3, 0}, + {-3, 1}, {-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1}, {3, 1}, + {-3, 2}, {-2, 2}, {-1, 2}, {0, 2}, {1, 2}, {2, 2}, {3, 2}, + {-2, 3}, {-1, 3}, {0, 3}, {1, 3}, {2, 3}, +} ; + +typedef struct +{ + const sCoords * Coords; + size_t Count; +} sCoordsArr; + +static const sCoordsArr BigOs[] = +{ + {BigO1, ARRAYCOUNT(BigO1)}, + {BigO2, ARRAYCOUNT(BigO2)}, + {BigO3, ARRAYCOUNT(BigO3)}, +} ; + + + + + +/// Pushes a specified layer of blocks of the same type around (x, h, z) into a_Blocks +inline void PushCoordBlocks(int a_BlockX, int a_Height, int a_BlockZ, sSetBlockVector & a_Blocks, const sCoords * a_Coords, size_t a_NumCoords, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) +{ + for (size_t i = 0; i < a_NumCoords; i++) + { + a_Blocks.push_back(sSetBlock(a_BlockX + a_Coords[i].x, a_Height, a_BlockZ + a_Coords[i].z, a_BlockType, a_Meta)); + } +} + + + + +inline void PushCornerBlocks(int a_BlockX, int a_Height, int a_BlockZ, int a_Seq, cNoise & a_Noise, int a_Chance, sSetBlockVector & a_Blocks, int a_CornersDist, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) +{ + for (size_t i = 0; i < ARRAYCOUNT(Corners); i++) + { + int x = a_BlockX + Corners[i].x; + int z = a_BlockZ + Corners[i].z; + if (a_Noise.IntNoise3DInt(x + 64 * a_Seq, a_Height, z + 64 * a_Seq) <= a_Chance) + { + a_Blocks.push_back(sSetBlock(x, a_Height, z, a_BlockType, a_Meta)); + } + } // for i - Corners[] +} + + + + + +inline void PushSomeColumns(int a_BlockX, int a_Height, int a_BlockZ, int a_ColumnHeight, int a_Seq, cNoise & a_Noise, int a_Chance, sSetBlockVector & a_Blocks, const sMetaCoords * a_Coords, size_t a_NumCoords, BLOCKTYPE a_BlockType) +{ + for (size_t i = 0; i < a_NumCoords; i++) + { + int x = a_BlockX + a_Coords[i].x; + int z = a_BlockZ + a_Coords[i].z; + if (a_Noise.IntNoise3DInt(x + 64 * a_Seq, a_Height + i, z + 64 * a_Seq) <= a_Chance) + { + for (int j = 0; j < a_ColumnHeight; j++) + { + a_Blocks.push_back(sSetBlock(x, a_Height - j, z, a_BlockType, a_Coords[i].Meta)); + } + } + } // for i - a_Coords[] +} + + + + + +void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, EMCSBiome a_Biome, sSetBlockVector & a_Blocks) +{ + switch (a_Biome) + { + case biPlains: + case biExtremeHills: + case biExtremeHillsEdge: + case biForest: + case biMushroomIsland: + case biMushroomShore: + case biForestHills: + { + // Apple or birch trees: + if (a_Noise.IntNoise3DInt(a_BlockX, a_BlockY + 16 * a_Seq, a_BlockZ + 16 * a_Seq) < 0x5fffffff) + { + GetAppleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); + } + else + { + GetBirchTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); + } + break; + } + + case biTaiga: + case biIcePlains: + case biIceMountains: + case biTaigaHills: + { + // Conifers + GetConiferTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); + break; + } + + case biSwampland: + { + // Swamp trees: + GetSwampTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); + break; + } + + case biJungle: + case biJungleHills: + { + // Apple bushes, jungle trees + if (a_Noise.IntNoise3DInt(a_BlockX, a_BlockY + 16 * a_Seq, a_BlockZ + 16 * a_Seq) < 0x5fffffff) + { + GetAppleBushImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); + } + else + { + GetJungleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); + } + } + } +} + + + + + +void GetAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) +{ + if (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY + 32 * a_Seq, a_BlockZ) < 0x60000000) + { + GetSmallAppleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); + } + else + { + GetLargeAppleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); + } +} + + + + + +void GetSmallAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) +{ + /* Small apple tree has: + - a top plus (no log) + - optional BigO1 + random corners (log) + - 2 layers of BigO2 + random corners (log) + - 1 to 3 blocks of trunk + */ + + int Random = a_Noise.IntNoise3DInt(a_BlockX + 64 * a_Seq, a_BlockY, a_BlockZ) >> 3; + + // Pre-alloc so that we don't realloc too often later: + a_Blocks.reserve(ARRAYCOUNT(BigO2) * 2 + ARRAYCOUNT(BigO1) + ARRAYCOUNT(Corners) * 3 + 3 + 5); + + int Heights[] = {1, 2, 2, 3} ; + int Height = 1 + Heights[Random & 3]; + Random >>= 2; + + // Trunk: + for (int i = 0; i < Height; i++) + { + a_Blocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); + } + int Hei = a_BlockY + Height; + + // 2 BigO2 + corners layers: + for (int i = 0; i < 2; i++) + { + PushCoordBlocks (a_BlockX, Hei, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + PushCornerBlocks(a_BlockX, Hei, a_BlockZ, a_Seq, a_Noise, 0x5000000 - i * 0x10000000, a_Blocks, 2, E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + a_Blocks.push_back(sSetBlock(a_BlockX, Hei, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); + Hei++; + } // for i - 2* + + // Optional BigO1 + corners layer: + if ((Random & 1) == 0) + { + PushCoordBlocks (a_BlockX, Hei, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + PushCornerBlocks(a_BlockX, Hei, a_BlockZ, a_Seq, a_Noise, 0x6000000, a_Blocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + a_Blocks.push_back(sSetBlock(a_BlockX, Hei, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); + Hei++; + } + + // Top plus: + PushCoordBlocks(a_BlockX, Hei, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + a_Blocks.push_back(sSetBlock(a_BlockX, Hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE)); +} + + + + + +void GetLargeAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) +{ + // TODO +} + + + + + +void GetBirchTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) +{ + int Height = 5 + (a_Noise.IntNoise3DInt(a_BlockX + 64 * a_Seq, a_BlockY, a_BlockZ) % 3); + + // Prealloc, so that we don't realloc too often later: + a_Blocks.reserve(Height + 80); + + // The entire trunk, out of logs: + for (int i = Height - 1; i >= 0; --i) + { + a_Blocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_BIRCH)); + } + int h = a_BlockY + Height; + + // Top layer - just the Plus: + PushCoordBlocks(a_BlockX, h, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); + a_Blocks.push_back(sSetBlock(a_BlockX, h, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH)); // There's no log at this layer + h--; + + // Second layer - log, Plus and maybe Corners: + PushCoordBlocks (a_BlockX, h, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); + PushCornerBlocks(a_BlockX, h, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_Blocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); + h--; + + // Third and fourth layers - BigO2 and maybe 2*Corners: + for (int Row = 0; Row < 2; Row++) + { + PushCoordBlocks (a_BlockX, h, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); + PushCornerBlocks(a_BlockX, h, a_BlockZ, a_Seq, a_Noise, 0x3fffffff + Row * 0x10000000, a_Blocks, 2, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); + h--; + } // for Row - 2* +} + + + + + +void GetConiferTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) +{ + // Half chance for a spruce, half for a pine: + if (a_Noise.IntNoise3DInt(a_BlockX + 64 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) < 0x40000000) + { + GetSpruceTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); + } + else + { + GetPineTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); + } +} + + + + + +void GetSpruceTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) +{ + // Spruces have a top section with layer sizes of (0, 1, 0) or only (1, 0), + // then 1 - 3 sections of ascending sizes (1, 2) [most often], (1, 3) or (1, 2, 3) + // and an optional bottom section of size 1, followed by 1 - 3 clear trunk blocks + + // We'll use bits from this number as partial random numbers; but the noise function has mod8 irregularities + // (each of the mod8 remainders has a very different chance of occurrence) - that's why we divide by 8 + int MyRandom = a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY + 32 * a_Seq, a_BlockZ) / 8; + + // Prealloc, so that we don't realloc too often later: + a_Blocks.reserve(180); + + // Clear trunk blocks: + static const int sHeights[] = {1, 2, 2, 3}; + int Height = sHeights[MyRandom & 3]; + MyRandom >>= 2; + for (int i = 0; i < Height; i++) + { + a_Blocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + } + Height += a_BlockY; + + // Optional size-1 bottom leaves layer: + if ((MyRandom & 1) == 0) + { + PushCoordBlocks(a_BlockX, Height, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + Height++; + } + MyRandom >>= 1; + + // 1 to 3 sections of leaves layers: + static const int sNumSections[] = {1, 2, 2, 3}; + int NumSections = sNumSections[MyRandom & 3]; + MyRandom >>= 2; + for (int i = 0; i < NumSections; i++) + { + switch (MyRandom & 3) // SectionType; (1, 2) twice as often as the other two + { + case 0: + case 1: + { + PushCoordBlocks(a_BlockX, Height, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + PushCoordBlocks(a_BlockX, Height + 1, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + a_Blocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + Height += 2; + break; + } + case 2: + { + PushCoordBlocks(a_BlockX, Height, a_BlockZ, a_Blocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + PushCoordBlocks(a_BlockX, Height + 1, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + a_Blocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + Height += 2; + break; + } + case 3: + { + PushCoordBlocks(a_BlockX, Height, a_BlockZ, a_Blocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + PushCoordBlocks(a_BlockX, Height + 1, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + PushCoordBlocks(a_BlockX, Height + 2, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + a_Blocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + a_Blocks.push_back(sSetBlock(a_BlockX, Height + 2, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + Height += 3; + break; + } + } // switch (SectionType) + MyRandom >>= 2; + } // for i - Sections + + if ((MyRandom & 1) == 0) + { + // (0, 1, 0) top: + a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + PushCoordBlocks (a_BlockX, Height + 1, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + a_Blocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER)); + a_Blocks.push_back(sSetBlock(a_BlockX, Height + 2, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER)); + } + else + { + // (1, 0) top: + a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER)); + PushCoordBlocks (a_BlockX, Height + 1, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + a_Blocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER)); + } +} + + + + + +void GetPineTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) +{ + // Tall, little leaves on top. The top leaves are arranged in a shape of two cones joined by their bases. + // There can be one or two layers representing the cone bases (SameSizeMax) + + int MyRandom = a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 8; + int TrunkHeight = 8 + (MyRandom % 3); + int SameSizeMax = ((MyRandom & 8) == 0) ? 1 : 0; + MyRandom >>= 3; + int NumLeavesLayers = 2 + (MyRandom % 3); // Number of layers that have leaves in them + if (NumLeavesLayers == 2) + { + SameSizeMax = 0; + } + + // Pre-allocate the vector: + a_Blocks.reserve(TrunkHeight + NumLeavesLayers * 25); + + // The entire trunk, out of logs: + for (int i = TrunkHeight; i >= 0; --i) + { + a_Blocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + } + int h = a_BlockY + TrunkHeight + 2; + + // Top layer - just a single leaves block: + a_Blocks.push_back(sSetBlock(a_BlockX, h, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER)); + h--; + + // One more layer is above the trunk, push the central leaves: + a_Blocks.push_back(sSetBlock(a_BlockX, h, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER)); + + // Layers expanding in size, then collapsing again: + // LOGD("Generating %d layers of pine leaves, SameSizeMax = %d", NumLeavesLayers, SameSizeMax); + for (int i = 0; i < NumLeavesLayers; ++i) + { + int LayerSize = std::min(i, NumLeavesLayers - i + SameSizeMax - 1); + // LOGD("LayerSize %d: %d", i, LayerSize); + if (LayerSize < 0) + { + break; + } + ASSERT(LayerSize < ARRAYCOUNT(BigOs)); + PushCoordBlocks(a_BlockX, h, a_BlockZ, a_Blocks, BigOs[LayerSize].Coords, BigOs[LayerSize].Count, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + h--; + } +} + + + + + +void GetSwampTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) +{ + // Vines are around the BigO3, but not in the corners; need proper meta for direction + static const sMetaCoords Vines[] = + { + {-2, -4, 1}, {-1, -4, 1}, {0, -4, 1}, {1, -4, 1}, {2, -4, 1}, // North face + {-2, 4, 4}, {-1, 4, 4}, {0, 4, 4}, {1, 4, 4}, {2, 4, 4}, // South face + {4, -2, 2}, {4, -1, 2}, {4, 0, 2}, {4, 1, 2}, {4, 2, 2}, // East face + {-4, -2, 8}, {-4, -1, 8}, {-4, 0, 8}, {-4, 1, 8}, {-4, 2, 8}, // West face + } ; + + int Height = 3 + (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 8) % 3; + + a_Blocks.reserve(2 * ARRAYCOUNT(BigO2) + 2 * ARRAYCOUNT(BigO3) + Height * ARRAYCOUNT(Vines) + 20); + + for (int i = 0; i < Height; i++) + { + a_Blocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); + } + int hei = a_BlockY + Height - 2; + + // Put vines around the lowermost leaves layer: + PushSomeColumns(a_BlockX, hei, a_BlockZ, Height, a_Seq, a_Noise, 0x3fffffff, a_Blocks, Vines, ARRAYCOUNT(Vines), E_BLOCK_VINES); + + // The lower two leaves layers are BigO3 with log in the middle and possibly corners: + for (int i = 0; i < 2; i++) + { + PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_Blocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_Blocks, 3, E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + hei++; + } // for i - 2* + + // The upper two leaves layers are BigO2 with leaves in the middle and possibly corners: + for (int i = 0; i < 2; i++) + { + PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_Blocks, 3, E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + a_Blocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE)); + hei++; + } // for i - 2* +} + + + + + +void GetAppleBushImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) +{ + a_Blocks.reserve(3 + ARRAYCOUNT(BigO2) + ARRAYCOUNT(BigO1)); + + int hei = a_BlockY; + a_Blocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LOG, E_META_LOG_JUNGLE)); + PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + hei++; + + a_Blocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE)); + PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + hei++; + + a_Blocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE)); +} + + + + + +void GetJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) +{ + // TODO +} + + + + diff --git a/source/Trees.h b/source/Trees.h index 84f1c51ea..aa8190e44 100644 --- a/source/Trees.h +++ b/source/Trees.h @@ -1,85 +1,85 @@ - -// Trees.h - -// Interfaces to helper functions used for generating trees - -/* -Note that all of these functions must generate the same tree image for the same input (x, y, z, seq) - - cStructGenTrees depends on this -To generate a random image for the (x, y, z) coords, pass an arbitrary value as (seq). -*/ - - - - - -#pragma once - -#include "ChunkDef.h" -#include "cNoise.h" - - - - - -// Blocks that don't block tree growth: -#define CASE_TREE_ALLOWED_BLOCKS \ - case E_BLOCK_AIR: \ - case E_BLOCK_LEAVES: \ - case E_BLOCK_SNOW: \ - case E_BLOCK_TALL_GRASS: \ - case E_BLOCK_DEAD_BUSH: \ - case E_BLOCK_SAPLING: \ - case E_BLOCK_VINES - -// Blocks that a tree may overwrite when growing: -#define CASE_TREE_OVERWRITTEN_BLOCKS \ - case E_BLOCK_AIR: \ - case E_BLOCK_LEAVES: \ - case E_BLOCK_SNOW: \ - case E_BLOCK_TALL_GRASS: \ - case E_BLOCK_DEAD_BUSH: \ - case E_BLOCK_SAPLING: \ - case E_BLOCK_VINES - - - - - -/// Generates an image of a tree at the specified coords (lowest trunk block) in the specified biome -void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, EMCSBiome a_Biome, sSetBlockVector & a_Blocks); - -/// Generates an image of a random apple tree -void GetAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); - -/// Generates an image of a small (nonbranching) apple tree -void GetSmallAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); - -/// Generates an image of a large (branching) apple tree -void GetLargeAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); - -/// Generates an image of a random birch tree -void GetBirchTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); - -/// Generates an image of a random conifer tree -void GetConiferTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); - -/// Generates an image of a random spruce (short conifer, two layers of leaves) -void GetSpruceTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); - -/// Generates an image of a random pine (tall conifer, little leaves at top) -void GetPineTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); - -/// Generates an image of a random swampland tree -void GetSwampTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); - -/// Generates an image of a random apple bush (for jungles) -void GetAppleBushImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); - -/// Generates an image of a random jungle tree -void GetJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); - - - - - + +// Trees.h + +// Interfaces to helper functions used for generating trees + +/* +Note that all of these functions must generate the same tree image for the same input (x, y, z, seq) + - cStructGenTrees depends on this +To generate a random image for the (x, y, z) coords, pass an arbitrary value as (seq). +*/ + + + + + +#pragma once + +#include "ChunkDef.h" +#include "cNoise.h" + + + + + +// Blocks that don't block tree growth: +#define CASE_TREE_ALLOWED_BLOCKS \ + case E_BLOCK_AIR: \ + case E_BLOCK_LEAVES: \ + case E_BLOCK_SNOW: \ + case E_BLOCK_TALL_GRASS: \ + case E_BLOCK_DEAD_BUSH: \ + case E_BLOCK_SAPLING: \ + case E_BLOCK_VINES + +// Blocks that a tree may overwrite when growing: +#define CASE_TREE_OVERWRITTEN_BLOCKS \ + case E_BLOCK_AIR: \ + case E_BLOCK_LEAVES: \ + case E_BLOCK_SNOW: \ + case E_BLOCK_TALL_GRASS: \ + case E_BLOCK_DEAD_BUSH: \ + case E_BLOCK_SAPLING: \ + case E_BLOCK_VINES + + + + + +/// Generates an image of a tree at the specified coords (lowest trunk block) in the specified biome +void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, EMCSBiome a_Biome, sSetBlockVector & a_Blocks); + +/// Generates an image of a random apple tree +void GetAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); + +/// Generates an image of a small (nonbranching) apple tree +void GetSmallAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); + +/// Generates an image of a large (branching) apple tree +void GetLargeAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); + +/// Generates an image of a random birch tree +void GetBirchTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); + +/// Generates an image of a random conifer tree +void GetConiferTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); + +/// Generates an image of a random spruce (short conifer, two layers of leaves) +void GetSpruceTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); + +/// Generates an image of a random pine (tall conifer, little leaves at top) +void GetPineTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); + +/// Generates an image of a random swampland tree +void GetSwampTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); + +/// Generates an image of a random apple bush (for jungles) +void GetAppleBushImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); + +/// Generates an image of a random jungle tree +void GetJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); + + + + + diff --git a/source/Vector3d.cpp b/source/Vector3d.cpp index 075034605..987c380dc 100644 --- a/source/Vector3d.cpp +++ b/source/Vector3d.cpp @@ -1,23 +1,23 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "Vector3d.h" -#include "Vector3f.h" - - - - - -Vector3d::Vector3d(const Vector3f & v ) - : x( v.x ) - , y( v.y ) - , z( v.z ) -{ -} - -Vector3d::Vector3d(const Vector3f * v ) - : x( v->x ) - , y( v->y ) - , z( v->z ) -{ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "Vector3d.h" +#include "Vector3f.h" + + + + + +Vector3d::Vector3d(const Vector3f & v ) + : x( v.x ) + , y( v.y ) + , z( v.z ) +{ +} + +Vector3d::Vector3d(const Vector3f * v ) + : x( v->x ) + , y( v->y ) + , z( v->z ) +{ } \ No newline at end of file diff --git a/source/Vector3d.h b/source/Vector3d.h index f93c2c763..5d3a7ad2c 100644 --- a/source/Vector3d.h +++ b/source/Vector3d.h @@ -1,42 +1,42 @@ -#pragma once - -#include - -class Vector3f; -class Vector3d //tolua_export -{ //tolua_export -public: //tolua_export - // convert from float - Vector3d(const Vector3f & v ); //tolua_export - Vector3d(const Vector3f * v ); //tolua_export - - Vector3d() : x(0), y(0), z(0) {} //tolua_export - Vector3d(double a_x, double a_y, double a_z) : x(a_x), y(a_y), z(a_z) {} //tolua_export - - inline void Set(double a_x, double a_y, double a_z) { x = a_x, y = a_y, z = a_z; } //tolua_export - inline void Normalize() { double l = 1.0f / Length(); x *= l; y *= l; z *= l; } //tolua_export - inline Vector3d NormalizeCopy() { double l = 1.0f / Length(); return Vector3d( x * l, y * l, z * l ); } //tolua_export - inline void NormalizeCopy(Vector3d & a_V) { double l = 1.0f / Length(); a_V.Set(x*l, y*l, z*l ); } //tolua_export - inline double Length() const { return (double)sqrt( x * x + y * y + z * z ); } //tolua_export - inline double SqrLength() const { return x * x + y * y + z * z; } //tolua_export - inline double Dot( const Vector3d & a_V ) const { return x * a_V.x + y * a_V.y + z * a_V.z; } //tolua_export - inline Vector3d Cross( const Vector3d & v ) const { return Vector3d( y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x ); } //tolua_export - - inline bool Equals( const Vector3d & v ) const { return (x == v.x && y == v.y && z == v.z ); } //tolua_export - - void operator += ( const Vector3d& a_V ) { x += a_V.x; y += a_V.y; z += a_V.z; } - void operator += ( Vector3d* a_V ) { x += a_V->x; y += a_V->y; z += a_V->z; } - void operator -= ( const Vector3d& a_V ) { x -= a_V.x; y -= a_V.y; z -= a_V.z; } - void operator -= ( Vector3d* a_V ) { x -= a_V->x; y -= a_V->y; z -= a_V->z; } - void operator *= ( double a_f ) { x *= a_f; y *= a_f; z *= a_f; } - - Vector3d operator + ( const Vector3d& v2 ) const { return Vector3d( x + v2.x, y + v2.y, z + v2.z ); } //tolua_export - Vector3d operator + ( const Vector3d* v2 ) const { return Vector3d( x + v2->x, y + v2->y, z + v2->z ); } //tolua_export - Vector3d operator - ( const Vector3d& v2 ) const { return Vector3d( x - v2.x, y - v2.y, z - v2.z ); } //tolua_export - Vector3d operator - ( const Vector3d* v2 ) const { return Vector3d( x - v2->x, y - v2->y, z - v2->z ); } //tolua_export - Vector3d operator * ( const double f ) const { return Vector3d( x * f, y * f, z * f ); } //tolua_export - Vector3d operator * ( const Vector3d& v2 ) const { return Vector3d( x * v2.x, y * v2.y, z * v2.z ); } //tolua_export - - double x, y, z; //tolua_export - +#pragma once + +#include + +class Vector3f; +class Vector3d //tolua_export +{ //tolua_export +public: //tolua_export + // convert from float + Vector3d(const Vector3f & v ); //tolua_export + Vector3d(const Vector3f * v ); //tolua_export + + Vector3d() : x(0), y(0), z(0) {} //tolua_export + Vector3d(double a_x, double a_y, double a_z) : x(a_x), y(a_y), z(a_z) {} //tolua_export + + inline void Set(double a_x, double a_y, double a_z) { x = a_x, y = a_y, z = a_z; } //tolua_export + inline void Normalize() { double l = 1.0f / Length(); x *= l; y *= l; z *= l; } //tolua_export + inline Vector3d NormalizeCopy() { double l = 1.0f / Length(); return Vector3d( x * l, y * l, z * l ); } //tolua_export + inline void NormalizeCopy(Vector3d & a_V) { double l = 1.0f / Length(); a_V.Set(x*l, y*l, z*l ); } //tolua_export + inline double Length() const { return (double)sqrt( x * x + y * y + z * z ); } //tolua_export + inline double SqrLength() const { return x * x + y * y + z * z; } //tolua_export + inline double Dot( const Vector3d & a_V ) const { return x * a_V.x + y * a_V.y + z * a_V.z; } //tolua_export + inline Vector3d Cross( const Vector3d & v ) const { return Vector3d( y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x ); } //tolua_export + + inline bool Equals( const Vector3d & v ) const { return (x == v.x && y == v.y && z == v.z ); } //tolua_export + + void operator += ( const Vector3d& a_V ) { x += a_V.x; y += a_V.y; z += a_V.z; } + void operator += ( Vector3d* a_V ) { x += a_V->x; y += a_V->y; z += a_V->z; } + void operator -= ( const Vector3d& a_V ) { x -= a_V.x; y -= a_V.y; z -= a_V.z; } + void operator -= ( Vector3d* a_V ) { x -= a_V->x; y -= a_V->y; z -= a_V->z; } + void operator *= ( double a_f ) { x *= a_f; y *= a_f; z *= a_f; } + + Vector3d operator + ( const Vector3d& v2 ) const { return Vector3d( x + v2.x, y + v2.y, z + v2.z ); } //tolua_export + Vector3d operator + ( const Vector3d* v2 ) const { return Vector3d( x + v2->x, y + v2->y, z + v2->z ); } //tolua_export + Vector3d operator - ( const Vector3d& v2 ) const { return Vector3d( x - v2.x, y - v2.y, z - v2.z ); } //tolua_export + Vector3d operator - ( const Vector3d* v2 ) const { return Vector3d( x - v2->x, y - v2->y, z - v2->z ); } //tolua_export + Vector3d operator * ( const double f ) const { return Vector3d( x * f, y * f, z * f ); } //tolua_export + Vector3d operator * ( const Vector3d& v2 ) const { return Vector3d( x * v2.x, y * v2.y, z * v2.z ); } //tolua_export + + double x, y, z; //tolua_export + };//tolua_export \ No newline at end of file diff --git a/source/Vector3f.cpp b/source/Vector3f.cpp index c23644065..59d71d371 100644 --- a/source/Vector3f.cpp +++ b/source/Vector3f.cpp @@ -1,34 +1,34 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "Vector3f.h" -#include "Vector3d.h" -#include "Vector3i.h" - -Vector3f::Vector3f( const Vector3d & v ) - : x( (float)v.x ) - , y( (float)v.y ) - , z( (float)v.z ) -{ -} - -Vector3f::Vector3f( const Vector3d * v ) - : x( (float)v->x ) - , y( (float)v->y ) - , z( (float)v->z ) -{ -} - -Vector3f::Vector3f( const Vector3i & v ) - : x( (float)v.x ) - , y( (float)v.y ) - , z( (float)v.z ) -{ -} - -Vector3f::Vector3f( const Vector3i * v ) - : x( (float)v->x ) - , y( (float)v->y ) - , z( (float)v->z ) -{ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "Vector3f.h" +#include "Vector3d.h" +#include "Vector3i.h" + +Vector3f::Vector3f( const Vector3d & v ) + : x( (float)v.x ) + , y( (float)v.y ) + , z( (float)v.z ) +{ +} + +Vector3f::Vector3f( const Vector3d * v ) + : x( (float)v->x ) + , y( (float)v->y ) + , z( (float)v->z ) +{ +} + +Vector3f::Vector3f( const Vector3i & v ) + : x( (float)v.x ) + , y( (float)v.y ) + , z( (float)v.z ) +{ +} + +Vector3f::Vector3f( const Vector3i * v ) + : x( (float)v->x ) + , y( (float)v->y ) + , z( (float)v->z ) +{ } \ No newline at end of file diff --git a/source/Vector3f.h b/source/Vector3f.h index ed1a6ef07..4c95e20de 100644 --- a/source/Vector3f.h +++ b/source/Vector3f.h @@ -1,47 +1,47 @@ -#pragma once - -#include - -class Vector3i; -class Vector3d; -class Vector3f //tolua_export -{ //tolua_export -public: //tolua_export - Vector3f( const Vector3d & v ); //tolua_export - Vector3f( const Vector3d * v ); //tolua_export - Vector3f( const Vector3i & v ); //tolua_export - Vector3f( const Vector3i * v ); //tolua_export - - - Vector3f() : x(0), y(0), z(0) {} //tolua_export - Vector3f(float a_x, float a_y, float a_z) : x(a_x), y(a_y), z(a_z) {} //tolua_export - - inline void Set(float a_x, float a_y, float a_z) { x = a_x, y = a_y, z = a_z; } //tolua_export - inline void Normalize() { float l = 1.0f / Length(); x *= l; y *= l; z *= l; } //tolua_export - inline Vector3f NormalizeCopy() const { float l = 1.0f / Length(); return Vector3f( x * l, y * l, z * l ); }//tolua_export - inline void NormalizeCopy(Vector3f & a_V) const { float l = 1.0f / Length(); a_V.Set(x*l, y*l, z*l ); } //tolua_export - inline float Length() const { return (float)sqrtf( x * x + y * y + z * z ); } //tolua_export - inline float SqrLength() const { return x * x + y * y + z * z; } //tolua_export - inline float Dot( const Vector3f & a_V ) const { return x * a_V.x + y * a_V.y + z * a_V.z; } //tolua_export - inline Vector3f Cross( const Vector3f & v ) const { return Vector3f( y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x ); } //tolua_export - - inline bool Equals( const Vector3f & v ) const { return (x == v.x && y == v.y && z == v.z ); } //tolua_export - - void operator += ( const Vector3f& a_V ) { x += a_V.x; y += a_V.y; z += a_V.z; } - void operator += ( Vector3f* a_V ) { x += a_V->x; y += a_V->y; z += a_V->z; } - void operator -= ( const Vector3f& a_V ) { x -= a_V.x; y -= a_V.y; z -= a_V.z; } - void operator -= ( Vector3f* a_V ) { x -= a_V->x; y -= a_V->y; z -= a_V->z; } - void operator *= ( float a_f ) { x *= a_f; y *= a_f; z *= a_f; } - void operator *= ( Vector3f* a_V ) { x *= a_V->x; y *= a_V->y; z *= a_V->z; } - void operator *= ( const Vector3f& a_V ) { x *= a_V.x; y *= a_V.y; z *= a_V.z; } - - Vector3f operator + ( const Vector3f& v2 ) const { return Vector3f( x + v2.x, y + v2.y, z + v2.z ); } //tolua_export - Vector3f operator + ( const Vector3f* v2 ) const { return Vector3f( x + v2->x, y + v2->y, z + v2->z ); } //tolua_export - Vector3f operator - ( const Vector3f& v2 ) const { return Vector3f( x - v2.x, y - v2.y, z - v2.z ); } //tolua_export - Vector3f operator - ( const Vector3f* v2 ) const { return Vector3f( x - v2->x, y - v2->y, z - v2->z ); } //tolua_export - Vector3f operator * ( const float f ) const { return Vector3f( x * f, y * f, z * f ); } //tolua_export - Vector3f operator * ( const Vector3f& v2 ) const { return Vector3f( x * v2.x, y * v2.y, z * v2.z ); } //tolua_export - - float x, y, z; //tolua_export - +#pragma once + +#include + +class Vector3i; +class Vector3d; +class Vector3f //tolua_export +{ //tolua_export +public: //tolua_export + Vector3f( const Vector3d & v ); //tolua_export + Vector3f( const Vector3d * v ); //tolua_export + Vector3f( const Vector3i & v ); //tolua_export + Vector3f( const Vector3i * v ); //tolua_export + + + Vector3f() : x(0), y(0), z(0) {} //tolua_export + Vector3f(float a_x, float a_y, float a_z) : x(a_x), y(a_y), z(a_z) {} //tolua_export + + inline void Set(float a_x, float a_y, float a_z) { x = a_x, y = a_y, z = a_z; } //tolua_export + inline void Normalize() { float l = 1.0f / Length(); x *= l; y *= l; z *= l; } //tolua_export + inline Vector3f NormalizeCopy() const { float l = 1.0f / Length(); return Vector3f( x * l, y * l, z * l ); }//tolua_export + inline void NormalizeCopy(Vector3f & a_V) const { float l = 1.0f / Length(); a_V.Set(x*l, y*l, z*l ); } //tolua_export + inline float Length() const { return (float)sqrtf( x * x + y * y + z * z ); } //tolua_export + inline float SqrLength() const { return x * x + y * y + z * z; } //tolua_export + inline float Dot( const Vector3f & a_V ) const { return x * a_V.x + y * a_V.y + z * a_V.z; } //tolua_export + inline Vector3f Cross( const Vector3f & v ) const { return Vector3f( y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x ); } //tolua_export + + inline bool Equals( const Vector3f & v ) const { return (x == v.x && y == v.y && z == v.z ); } //tolua_export + + void operator += ( const Vector3f& a_V ) { x += a_V.x; y += a_V.y; z += a_V.z; } + void operator += ( Vector3f* a_V ) { x += a_V->x; y += a_V->y; z += a_V->z; } + void operator -= ( const Vector3f& a_V ) { x -= a_V.x; y -= a_V.y; z -= a_V.z; } + void operator -= ( Vector3f* a_V ) { x -= a_V->x; y -= a_V->y; z -= a_V->z; } + void operator *= ( float a_f ) { x *= a_f; y *= a_f; z *= a_f; } + void operator *= ( Vector3f* a_V ) { x *= a_V->x; y *= a_V->y; z *= a_V->z; } + void operator *= ( const Vector3f& a_V ) { x *= a_V.x; y *= a_V.y; z *= a_V.z; } + + Vector3f operator + ( const Vector3f& v2 ) const { return Vector3f( x + v2.x, y + v2.y, z + v2.z ); } //tolua_export + Vector3f operator + ( const Vector3f* v2 ) const { return Vector3f( x + v2->x, y + v2->y, z + v2->z ); } //tolua_export + Vector3f operator - ( const Vector3f& v2 ) const { return Vector3f( x - v2.x, y - v2.y, z - v2.z ); } //tolua_export + Vector3f operator - ( const Vector3f* v2 ) const { return Vector3f( x - v2->x, y - v2->y, z - v2->z ); } //tolua_export + Vector3f operator * ( const float f ) const { return Vector3f( x * f, y * f, z * f ); } //tolua_export + Vector3f operator * ( const Vector3f& v2 ) const { return Vector3f( x * v2.x, y * v2.y, z * v2.z ); } //tolua_export + + float x, y, z; //tolua_export + };//tolua_export \ No newline at end of file diff --git a/source/Vector3i.cpp b/source/Vector3i.cpp index 3e812bf7c..4ce1e2cf3 100644 --- a/source/Vector3i.cpp +++ b/source/Vector3i.cpp @@ -1,16 +1,16 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "Vector3i.h" -#include "Vector3d.h" - - - - - -Vector3i::Vector3i( const Vector3d & v ) - : x( (int)v.x ) - , y( (int)v.y ) - , z( (int)v.z ) -{ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "Vector3i.h" +#include "Vector3d.h" + + + + + +Vector3i::Vector3i( const Vector3d & v ) + : x( (int)v.x ) + , y( (int)v.y ) + , z( (int)v.z ) +{ } \ No newline at end of file diff --git a/source/Vector3i.h b/source/Vector3i.h index 7fbd74b5a..85f2d7003 100644 --- a/source/Vector3i.h +++ b/source/Vector3i.h @@ -1,38 +1,38 @@ -#pragma once - -#include - -class Vector3d; -class Vector3i //tolua_export -{ //tolua_export -public: //tolua_export - Vector3i( const Vector3d & v ); //tolua_export - - Vector3i() : x(0), y(0), z(0) {} //tolua_export - Vector3i(int a_x, int a_y, int a_z) : x(a_x), y(a_y), z(a_z) {} //tolua_export - - inline void Set(int a_x, int a_y, int a_z) { x = a_x, y = a_y, z = a_z; } //tolua_export - inline float Length() const { return sqrtf( (float)( x * x + y * y + z * z) ); } //tolua_export - inline int SqrLength() const { return x * x + y * y + z * z; } //tolua_export - - inline bool Equals( const Vector3i & v ) const { return (x == v.x && y == v.y && z == v.z ); } //tolua_export - inline bool Equals( const Vector3i * v ) const { return (x == v->x && y == v->y && z == v->z ); } //tolua_export - - void operator += ( const Vector3i& a_V ) { x += a_V.x; y += a_V.y; z += a_V.z; } - void operator += ( Vector3i* a_V ) { x += a_V->x; y += a_V->y; z += a_V->z; } - void operator -= ( const Vector3i& a_V ) { x -= a_V.x; y -= a_V.y; z -= a_V.z; } - void operator -= ( Vector3i* a_V ) { x -= a_V->x; y -= a_V->y; z -= a_V->z; } - void operator *= ( int a_f ) { x *= a_f; y *= a_f; z *= a_f; } - - friend Vector3i operator + ( const Vector3i& v1, const Vector3i& v2 ) { return Vector3i( v1.x + v2.x, v1.y + v2.y, v1.z + v2.z ); } - friend Vector3i operator + ( const Vector3i& v1, Vector3i* v2 ) { return Vector3i( v1.x + v2->x, v1.y + v2->y, v1.z + v2->z ); } - friend Vector3i operator - ( const Vector3i& v1, const Vector3i& v2 ) { return Vector3i( v1.x - v2.x, v1.y - v2.y, v1.z - v2.z ); } - friend Vector3i operator - ( const Vector3i& v1, Vector3i* v2 ) { return Vector3i( v1.x - v2->x, v1.y - v2->y, v1.z - v2->z ); } - friend Vector3i operator - ( const Vector3i* v1, Vector3i& v2 ) { return Vector3i( v1->x - v2.x, v1->y - v2.y, v1->z - v2.z ); } - friend Vector3i operator * ( const Vector3i& v, const int f ) { return Vector3i( v.x * f, v.y * f, v.z * f ); } - friend Vector3i operator * ( const Vector3i& v1, const Vector3i& v2 ) { return Vector3i( v1.x * v2.x, v1.y * v2.y, v1.z * v2.z ); } - friend Vector3i operator * ( const int f, const Vector3i& v ) { return Vector3i( v.x * f, v.y * f, v.z * f ); } - friend bool operator < ( const Vector3i& v1, const Vector3i& v2 ) { return (v1.x + +class Vector3d; +class Vector3i //tolua_export +{ //tolua_export +public: //tolua_export + Vector3i( const Vector3d & v ); //tolua_export + + Vector3i() : x(0), y(0), z(0) {} //tolua_export + Vector3i(int a_x, int a_y, int a_z) : x(a_x), y(a_y), z(a_z) {} //tolua_export + + inline void Set(int a_x, int a_y, int a_z) { x = a_x, y = a_y, z = a_z; } //tolua_export + inline float Length() const { return sqrtf( (float)( x * x + y * y + z * z) ); } //tolua_export + inline int SqrLength() const { return x * x + y * y + z * z; } //tolua_export + + inline bool Equals( const Vector3i & v ) const { return (x == v.x && y == v.y && z == v.z ); } //tolua_export + inline bool Equals( const Vector3i * v ) const { return (x == v->x && y == v->y && z == v->z ); } //tolua_export + + void operator += ( const Vector3i& a_V ) { x += a_V.x; y += a_V.y; z += a_V.z; } + void operator += ( Vector3i* a_V ) { x += a_V->x; y += a_V->y; z += a_V->z; } + void operator -= ( const Vector3i& a_V ) { x -= a_V.x; y -= a_V.y; z -= a_V.z; } + void operator -= ( Vector3i* a_V ) { x -= a_V->x; y -= a_V->y; z -= a_V->z; } + void operator *= ( int a_f ) { x *= a_f; y *= a_f; z *= a_f; } + + friend Vector3i operator + ( const Vector3i& v1, const Vector3i& v2 ) { return Vector3i( v1.x + v2.x, v1.y + v2.y, v1.z + v2.z ); } + friend Vector3i operator + ( const Vector3i& v1, Vector3i* v2 ) { return Vector3i( v1.x + v2->x, v1.y + v2->y, v1.z + v2->z ); } + friend Vector3i operator - ( const Vector3i& v1, const Vector3i& v2 ) { return Vector3i( v1.x - v2.x, v1.y - v2.y, v1.z - v2.z ); } + friend Vector3i operator - ( const Vector3i& v1, Vector3i* v2 ) { return Vector3i( v1.x - v2->x, v1.y - v2->y, v1.z - v2->z ); } + friend Vector3i operator - ( const Vector3i* v1, Vector3i& v2 ) { return Vector3i( v1->x - v2.x, v1->y - v2.y, v1->z - v2.z ); } + friend Vector3i operator * ( const Vector3i& v, const int f ) { return Vector3i( v.x * f, v.y * f, v.z * f ); } + friend Vector3i operator * ( const Vector3i& v1, const Vector3i& v2 ) { return Vector3i( v1.x * v2.x, v1.y * v2.y, v1.z * v2.z ); } + friend Vector3i operator * ( const int f, const Vector3i& v ) { return Vector3i( v.x * f, v.y * f, v.z * f ); } + friend bool operator < ( const Vector3i& v1, const Vector3i& v2 ) { return (v1.xGetPosX()); - m_Writer.AddInt ("y", a_Entity->GetPosY()); - m_Writer.AddInt ("z", a_Entity->GetPosZ()); - m_Writer.AddString("id", a_EntityTypeID); - } - - - void AddItem(const cItem * a_Item, int a_Slot) - { - m_Writer.BeginCompound(""); - m_Writer.AddShort("id", (short)(a_Item->m_ItemID)); - m_Writer.AddShort("Damage", a_Item->m_ItemHealth); - m_Writer.AddByte ("Count", a_Item->m_ItemCount); - m_Writer.AddByte ("Slot", (unsigned char)a_Slot); - m_Writer.EndCompound(); - } - - - void AddChestEntity(cChestEntity * a_Entity) - { - m_Writer.BeginCompound(""); - AddBasicTileEntity(a_Entity, "Chest"); - m_Writer.BeginList("Items", TAG_Compound); - for (int i = 0; i < cChestEntity::c_ChestHeight * cChestEntity::c_ChestWidth; i++) - { - const cItem * Item = a_Entity->GetSlot(i); - if ((Item == NULL) || Item->IsEmpty()) - { - continue; - } - AddItem(Item, i); - } - m_Writer.EndList(); - m_Writer.EndCompound(); - } - - - void AddFurnaceEntity(cFurnaceEntity * a_Furnace) - { - m_Writer.BeginCompound(""); - AddBasicTileEntity(a_Furnace, "Furnace"); - m_Writer.BeginList("Items", TAG_Compound); - AddItem(&a_Furnace->GetSlot(0), 0); - AddItem(&a_Furnace->GetSlot(1), 1); - AddItem(&a_Furnace->GetSlot(2), 2); - m_Writer.EndList(); - m_Writer.AddShort("BurnTime", (Int16)(a_Furnace->GetTimeToBurn() / 50.0)); - m_Writer.AddShort("CookTime", (Int16)(a_Furnace->GetTimeCooked() / 50.0)); - m_Writer.EndCompound(); - } - - - virtual bool LightIsValid(bool a_IsLightValid) override - { - m_IsLightValid = a_IsLightValid; - return a_IsLightValid; // We want lighting only if it's valid, otherwise don't bother - } - - - virtual void Entity(cEntity * a_Entity) override - { - // TODO: Add entity into NBT: - } - - - virtual void BlockEntity(cBlockEntity * a_Entity) - { - if (m_IsTagOpen) - { - if (!m_HasHadBlockEntity) - { - m_Writer.EndList(); - m_Writer.BeginList("TileEntities", TAG_Compound); - } - } - else - { - m_Writer.BeginList("TileEntities", TAG_Compound); - } - m_IsTagOpen = true; - - // Add tile-entity into NBT: - switch (a_Entity->GetBlockType()) - { - case E_BLOCK_CHEST: AddChestEntity ((cChestEntity *) a_Entity); break; - case E_BLOCK_FURNACE: AddFurnaceEntity((cFurnaceEntity *)a_Entity); break; - default: - { - ASSERT(!"Unhandled block entity saved into Anvil"); - } - } - m_HasHadBlockEntity = true; - } -} ; // class cNBTChunkSerializer - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cWSSAnvil: - -cWSSAnvil::cWSSAnvil(cWorld * a_World) : - super(a_World) -{ - // Create a level.dat file for mapping tools, if it doesn't already exist: - AString fnam; - Printf(fnam, "%s/level.dat", a_World->GetName().c_str()); - if (!cFile::Exists(fnam)) - { - cFastNBTWriter Writer; - Writer.BeginCompound(""); - Writer.AddInt("SpawnX", (int)(a_World->GetSpawnX())); - Writer.AddInt("SpawnY", (int)(a_World->GetSpawnY())); - Writer.AddInt("SpawnZ", (int)(a_World->GetSpawnZ())); - Writer.EndCompound(); - Writer.Finish(); - - #ifdef _DEBUG - cParsedNBT TestParse(Writer.GetResult().data(), Writer.GetResult().size()); - ASSERT(TestParse.IsValid()); - #endif // _DEBUG - - gzFile gz = gzopen(fnam.c_str(), "wb"); - if (gz != NULL) - { - gzwrite(gz, Writer.GetResult().data(), Writer.GetResult().size()); - } - gzclose(gz); - } -} - - - - - -cWSSAnvil::~cWSSAnvil() -{ - cCSLock Lock(m_CS); - for (cMCAFiles::iterator itr = m_Files.begin(); itr != m_Files.end(); ++itr) - { - delete *itr; - } // for itr - m_Files[] -} - - - - - -bool cWSSAnvil::LoadChunk(const cChunkCoords & a_Chunk) -{ - AString ChunkData; - if (!GetChunkData(a_Chunk, ChunkData)) - { - // The reason for failure is already printed in GetChunkData() - return false; - } - - return LoadChunkFromData(a_Chunk, ChunkData); -} - - - - - -bool cWSSAnvil::SaveChunk(const cChunkCoords & a_Chunk) -{ - AString ChunkData; - if (!SaveChunkToData(a_Chunk, ChunkData)) - { - return false; - } - if (!SetChunkData(a_Chunk, ChunkData)) - { - return false; - } - - // Everything successful - return true; -} - - - - - -bool cWSSAnvil::GetChunkData(const cChunkCoords & a_Chunk, AString & a_Data) -{ - cCSLock Lock(m_CS); - cMCAFile * File = LoadMCAFile(a_Chunk); - if (File == NULL) - { - return false; - } - return File->GetChunkData(a_Chunk, a_Data); -} - - - - - -bool cWSSAnvil::SetChunkData(const cChunkCoords & a_Chunk, const AString & a_Data) -{ - cCSLock Lock(m_CS); - cMCAFile * File = LoadMCAFile(a_Chunk); - if (File == NULL) - { - return false; - } - return File->SetChunkData(a_Chunk, a_Data); -} - - - - - -cWSSAnvil::cMCAFile * cWSSAnvil::LoadMCAFile(const cChunkCoords & a_Chunk) -{ - // ASSUME m_CS is locked - - const int RegionX = (int)(floorf((float)a_Chunk.m_ChunkX / 32.0f)); - const int RegionZ = (int)(floorf((float)a_Chunk.m_ChunkZ / 32.0f)); - - // Is it already cached? - for (cMCAFiles::iterator itr = m_Files.begin(); itr != m_Files.end(); ++itr) - { - if (((*itr) != NULL) && ((*itr)->GetRegionX() == RegionX) && ((*itr)->GetRegionZ() == RegionZ)) - { - // Move the file to front and return it: - cMCAFile * f = *itr; - if (itr != m_Files.begin()) - { - m_Files.erase(itr); - m_Files.push_front(f); - } - return f; - } - } - - // Load it anew: - AString FileName; - Printf(FileName, "%s/region", m_World->GetName().c_str()); - cMakeDir::MakeDir(FileName); - AppendPrintf(FileName, "/r.%d.%d.mca", RegionX, RegionZ); - cMCAFile * f = new cMCAFile(FileName, RegionX, RegionZ); - if (f == NULL) - { - return NULL; - } - m_Files.push_front(f); - - // If there are too many MCA files cached, delete the last one used: - if (m_Files.size() > MAX_MCA_FILES) - { - delete m_Files.back(); - m_Files.pop_back(); - } - return f; -} - - - - - -bool cWSSAnvil::LoadChunkFromData(const cChunkCoords & a_Chunk, const AString & a_Data) -{ - // Decompress the data: - char Uncompressed[CHUNK_INFLATE_MAX]; - z_stream strm; - strm.zalloc = (alloc_func)NULL; - strm.zfree = (free_func)NULL; - strm.opaque = NULL; - inflateInit(&strm); - strm.next_out = (Bytef *)Uncompressed; - strm.avail_out = sizeof(Uncompressed); - strm.next_in = (Bytef *)a_Data.data(); - strm.avail_in = a_Data.size(); - int res = inflate(&strm, Z_FINISH); - inflateEnd(&strm); - if (res != Z_STREAM_END) - { - return false; - } - - // Parse the NBT data: - cParsedNBT NBT(Uncompressed, strm.total_out); - if (!NBT.IsValid()) - { - // NBT Parsing failed - return false; - } - - // Load the data from NBT: - return LoadChunkFromNBT(a_Chunk, NBT); -} - - - - - -bool cWSSAnvil::SaveChunkToData(const cChunkCoords & a_Chunk, AString & a_Data) -{ - cFastNBTWriter Writer; - if (!SaveChunkToNBT(a_Chunk, Writer)) - { - return false; - } - Writer.Finish(); - CompressString(Writer.GetResult().data(), Writer.GetResult().size(), a_Data); - return true; -} - - - - - -bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT & a_NBT) -{ - // The data arrays, in MCA-native y/z/x ordering (will be reordered for the final chunk data) - cChunkDef::BlockTypes BlockTypes; - cChunkDef::BlockNibbles MetaData; - cChunkDef::BlockNibbles BlockLight; - cChunkDef::BlockNibbles SkyLight; - - memset(BlockTypes, E_BLOCK_AIR, sizeof(BlockTypes)); - memset(MetaData, 0, sizeof(MetaData)); - memset(SkyLight, 0xff, sizeof(SkyLight)); // By default, data not present in the NBT means air, which means full skylight - memset(BlockLight, 0x00, sizeof(BlockLight)); - - // Load the blockdata, blocklight and skylight: - int Level = a_NBT.FindChildByName(0, "Level"); - if (Level < 0) - { - return false; - } - int Sections = a_NBT.FindChildByName(Level, "Sections"); - if ((Sections < 0) || (a_NBT.GetType(Sections) != TAG_List) || (a_NBT.GetChildrenType(Sections) != TAG_Compound)) - { - return false; - } - for (int Child = a_NBT.GetFirstChild(Sections); Child >= 0; Child = a_NBT.GetNextSibling(Child)) - { - int y = 0; - int SectionY = a_NBT.FindChildByName(Child, "Y"); - if ((SectionY < 0) || (a_NBT.GetType(SectionY) != TAG_Byte)) - { - continue; - } - y = a_NBT.GetByte(SectionY); - if ((y < 0) || (y > 15)) - { - continue; - } - CopyNBTData(a_NBT, Child, "Blocks", (char *)&(BlockTypes[y * 4096]), 4096); - CopyNBTData(a_NBT, Child, "Data", (char *)&(MetaData[y * 2048]), 2048); - CopyNBTData(a_NBT, Child, "SkyLight", (char *)&(SkyLight[y * 2048]), 2048); - CopyNBTData(a_NBT, Child, "BlockLight", (char *)&(BlockLight[y * 2048]), 2048); - } // for itr - LevelSections[] - - // Load the biomes from NBT, if present and valid: - cChunkDef::BiomeMap BiomeMap; - cChunkDef::BiomeMap * Biomes = LoadBiomeMapFromNBT(&BiomeMap, a_NBT, a_NBT.FindChildByName(Level, "Biomes")); - - // Load the entities from NBT: - cEntityList Entities; - cBlockEntityList BlockEntities; - LoadEntitiesFromNBT (Entities, a_NBT, a_NBT.FindChildByName(Level, "Entities")); - LoadBlockEntitiesFromNBT(BlockEntities, a_NBT, a_NBT.FindChildByName(Level, "TileEntities")); - - bool IsLightValid = (a_NBT.FindChildByName(Level, "MCSIsLightValid") > 0); - - /* - // Uncomment this block for really cool stuff :) - // DEBUG magic: Invert the underground, so that we can see the MC generator in action :) - bool ShouldInvert[cChunkDef::Width * cChunkDef::Width]; - memset(ShouldInvert, 0, sizeof(ShouldInvert)); - for (int y = cChunkDef::Height - 1; y >= 0; y--) - { - for (int x = 0; x < cChunkDef::Width; x++) for (int z = 0; z < cChunkDef::Width; z++) - { - int Index = cChunkDef::MakeIndexNoCheck(x, y, z); - if (ShouldInvert[x + cChunkDef::Width * z]) - { - ChunkData[Index] = (ChunkData[Index] == E_BLOCK_AIR) ? E_BLOCK_STONE : E_BLOCK_AIR; - } - else - { - ShouldInvert[x + cChunkDef::Width * z] = (ChunkData[Index] != E_BLOCK_AIR); - } - } - } // for y - // Set everything alight, so that we can see: - memset(ChunkData + cChunkDef::SkyLightOffset, 0xff, cChunkDef::NumBlocks / 2); - //*/ - - m_World->SetChunkData( - a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, - BlockTypes, MetaData, - IsLightValid ? BlockLight : NULL, - IsLightValid ? SkyLight : NULL, - NULL, Biomes, - Entities, BlockEntities, - false - ); - return true; -} - - - - -void cWSSAnvil::CopyNBTData(const cParsedNBT & a_NBT, int a_Tag, const AString & a_ChildName, char * a_Destination, int a_Length) -{ - int Child = a_NBT.FindChildByName(a_Tag, a_ChildName); - if ((Child >= 0) && (a_NBT.GetType(Child) == TAG_ByteArray) && (a_NBT.GetDataLength(Child) == a_Length)) - { - memcpy(a_Destination, a_NBT.GetData(Child), a_Length); - } -} - - - - - -bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_Writer) -{ - a_Writer.BeginCompound("Level"); - a_Writer.AddInt("xPos", a_Chunk.m_ChunkX); - a_Writer.AddInt("zPos", a_Chunk.m_ChunkZ); - cNBTChunkSerializer Serializer(a_Writer); - if (!m_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, Serializer)) - { - return false; - } - Serializer.Finish(); // Close NBT tags - - // TODO: Save biomes, both MCS (IntArray) and MC-vanilla (ByteArray): - // Level->Add(new cNBTByteArray(Level, "Biomes", AString(Serializer.m_Biomes, sizeof(Serializer.m_Biomes)); - // Level->Add(new cNBTByteArray(Level, "MCSBiomes", AString(Serializer.m_Biomes, sizeof(Serializer.m_Biomes)); - - // Save blockdata: - a_Writer.BeginList("Sections", TAG_Compound); - int SliceSizeBlock = cChunkDef::Width * cChunkDef::Width * 16; - int SliceSizeNibble = SliceSizeBlock / 2; - const char * BlockTypes = (const char *)(Serializer.m_BlockTypes); - const char * BlockMetas = (const char *)(Serializer.m_BlockMetas); - const char * BlockLight = (const char *)(Serializer.m_BlockLight); - const char * BlockSkyLight = (const char *)(Serializer.m_BlockSkyLight); - for (int Y = 0; Y < 16; Y++) - { - a_Writer.BeginCompound(""); - a_Writer.AddByteArray("Blocks", BlockTypes + Y * SliceSizeBlock, SliceSizeBlock); - a_Writer.AddByteArray("Data", BlockMetas + Y * SliceSizeNibble, SliceSizeNibble); - a_Writer.AddByteArray("SkyLight", BlockSkyLight + Y * SliceSizeNibble, SliceSizeNibble); - a_Writer.AddByteArray("BlockLight", BlockLight + Y * SliceSizeNibble, SliceSizeNibble); - a_Writer.AddByte("Y", (unsigned char)Y); - a_Writer.EndCompound(); - } - a_Writer.EndList(); // "Sections" - - // Store the information that the lighting is valid. - // For compatibility reason, the default is "invalid" (missing) - this means older data is re-lighted upon loading. - if (Serializer.IsLightValid()) - { - a_Writer.AddByte("MCSIsLightValid", 1); - } - - a_Writer.EndCompound(); // "Level" - return true; -} - - - - - -cChunkDef::BiomeMap * cWSSAnvil::LoadBiomeMapFromNBT(cChunkDef::BiomeMap * a_BiomeMap, const cParsedNBT & a_NBT, int a_TagIdx) -{ - if ((a_TagIdx < 0) || (a_NBT.GetType(a_TagIdx) != TAG_ByteArray)) - { - return NULL; - } - if (a_NBT.GetDataLength(a_TagIdx) != sizeof(*a_BiomeMap)) - { - // The biomes stored don't match in size - return NULL; - } - memcpy(a_BiomeMap, a_NBT.GetData(a_TagIdx), sizeof(*a_BiomeMap)); - for (int i = 0; i < ARRAYCOUNT(*a_BiomeMap); i++) - { - if ((*a_BiomeMap)[i] == 0xff) - { - // Unassigned biomes - return NULL; - } - } - return a_BiomeMap; -} - - - - - -void cWSSAnvil::LoadEntitiesFromNBT(cEntityList & a_Entitites, const cParsedNBT & a_NBT, int a_TagIdx) -{ - // TODO: Load the entities -} - - - - - -void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) -{ - if ((a_TagIdx < 0) || (a_NBT.GetType(a_TagIdx) != TAG_List)) - { - return; - } - - for (int Child = a_NBT.GetFirstChild(a_TagIdx); Child != -1; Child = a_NBT.GetNextSibling(Child)) - { - if (a_NBT.GetType(Child) != TAG_Compound) - { - continue; - } - int sID = a_NBT.FindChildByName(Child, "id"); - if (sID < 0) - { - continue; - } - if (strncmp(a_NBT.GetData(sID), "Chest", a_NBT.GetDataLength(sID)) == 0) - { - LoadChestFromNBT(a_BlockEntities, a_NBT, Child); - } - else if (strncmp(a_NBT.GetData(sID), "Furnace", a_NBT.GetDataLength(sID)) == 0) - { - LoadFurnaceFromNBT(a_BlockEntities, a_NBT, Child); - } - // TODO: Other block entities - } // for Child - tag children -} - - - - - -void cWSSAnvil::LoadChestFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) -{ - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) - { - return; - } - int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); - if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) - { - return; // Make it an empty chest - the chunk loader will provide an empty cChestEntity for this - } - std::auto_ptr Chest(new cChestEntity(x, y, z, m_World)); - for (int Child = a_NBT.GetFirstChild(Items); Child != -1; Child = a_NBT.GetNextSibling(Child)) - { - int Slot = a_NBT.FindChildByName(Child, "Slot"); - if ((Slot < 0) || (a_NBT.GetType(Slot) != TAG_Byte)) - { - continue; - } - cItem Item; - int ID = a_NBT.FindChildByName(Child, "id"); - if ((ID < 0) || (a_NBT.GetType(ID) != TAG_Short)) - { - continue; - } - Item.m_ItemID = (ENUM_ITEM_ID)(a_NBT.GetShort(ID)); - int Damage = a_NBT.FindChildByName(Child, "Damage"); - if ((Damage < 0) || (a_NBT.GetType(Damage) != TAG_Short)) - { - continue; - } - Item.m_ItemHealth = a_NBT.GetShort(Damage); - int Count = a_NBT.FindChildByName(Child, "Count"); - if ((Count < 0) || (a_NBT.GetType(Count) != TAG_Byte)) - { - continue; - } - Item.m_ItemCount = a_NBT.GetByte(Count); - Chest->SetSlot(a_NBT.GetByte(Slot), Item); - } // for itr - ItemDefs[] - a_BlockEntities.push_back(Chest.release()); -} - - - - - -void cWSSAnvil::LoadFurnaceFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) -{ - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) - { - return; - } - int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); - if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) - { - return; // Make it an empty furnace - the chunk loader will provide an empty cFurnaceEntity for this - } - std::auto_ptr Furnace(new cFurnaceEntity(x, y, z, m_World)); - for (int Child = a_NBT.GetFirstChild(Items); Child != -1; Child = a_NBT.GetNextSibling(Child)) - { - int Slot = a_NBT.FindChildByName(Child, "Slot"); - if ((Slot < 0) || (a_NBT.GetType(Slot) != TAG_Byte)) - { - continue; - } - cItem Item; - int ID = a_NBT.FindChildByName(Child, "id"); - if ((ID < 0) || (a_NBT.GetType(ID) != TAG_Short)) - { - continue; - } - Item.m_ItemID = (ENUM_ITEM_ID)(a_NBT.GetShort(ID)); - int Damage = a_NBT.FindChildByName(Child, "Damage"); - if ((Damage < 0) || (a_NBT.GetType(Damage) != TAG_Short)) - { - continue; - } - Item.m_ItemHealth = a_NBT.GetShort(Damage); - int Count = a_NBT.FindChildByName(Child, "Count"); - if ((Count < 0) || (a_NBT.GetType(Count) != TAG_Byte)) - { - continue; - } - Item.m_ItemCount = a_NBT.GetByte(Count); - Furnace->SetSlot(a_NBT.GetByte(Slot), Item); - } // for itr - ItemDefs[] - int BurnTime = a_NBT.FindChildByName(a_TagIdx, "BurnTime"); - if (BurnTime >= 0) - { - Int16 bt = a_NBT.GetShort(BurnTime); - // Anvil doesn't store the time that the fuel can burn. We simply "reset" the current value to be the 100% - Furnace->SetBurnTimes((float)(bt * 50.0), (float)(bt * 50.0)); - } - int CookTime = a_NBT.FindChildByName(a_TagIdx, "CookTime"); - if (CookTime >= 0) - { - Int16 ct = a_NBT.GetShort(CookTime); - // Anvil doesn't store the time that an item takes to cook. We simply use the default - 10 seconds - Furnace->SetCookTimes(10000.0, (float)(ct * 50.0)); - } - Furnace->ContinueCooking(); - a_BlockEntities.push_back(Furnace.release()); -} - - - - - -bool cWSSAnvil::GetBlockEntityNBTPos(const cParsedNBT & a_NBT, int a_TagIdx, int & a_X, int & a_Y, int & a_Z) -{ - int x = a_NBT.FindChildByName(a_TagIdx, "x"); - if ((x < 0) || (a_NBT.GetType(x) != TAG_Int)) - { - return false; - } - int y = a_NBT.FindChildByName(a_TagIdx, "y"); - if ((y < 0) || (a_NBT.GetType(y) != TAG_Int)) - { - return false; - } - int z = a_NBT.FindChildByName(a_TagIdx, "z"); - if ((z < 0) || (a_NBT.GetType(z) != TAG_Int)) - { - return false; - } - a_X = a_NBT.GetInt(x); - a_Y = a_NBT.GetInt(y); - a_Z = a_NBT.GetInt(z); - return true; -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cWSSAnvil::cMCAFile: - -cWSSAnvil::cMCAFile::cMCAFile(const AString & a_FileName, int a_RegionX, int a_RegionZ) : - m_RegionX(a_RegionX), - m_RegionZ(a_RegionZ), - m_FileName(a_FileName) -{ -} - - - - - -bool cWSSAnvil::cMCAFile::OpenFile(bool a_IsForReading) -{ - if (m_File.IsOpen()) - { - // Already open - return true; - } - - if (a_IsForReading) - { - if (!cFile::Exists(m_FileName)) - { - // We want to read and the file doesn't exist. Fail. - return false; - } - } - - if (!m_File.Open(m_FileName, cFile::fmReadWrite)) - { - // The file failed to open - return false; - } - - // Load the header: - if (m_File.Read(m_Header, sizeof(m_Header)) != sizeof(m_Header)) - { - // Cannot read the header - perhaps the file has just been created? - // Try writing a NULL header (both chunk offsets and timestamps): - memset(m_Header, 0, sizeof(m_Header)); - if ( - (m_File.Write(m_Header, sizeof(m_Header)) != sizeof(m_Header)) || // Real header - chunk offsets - (m_File.Write(m_Header, sizeof(m_Header)) != sizeof(m_Header)) // Bogus data for the chunk timestamps - ) - { - LOGWARNING("Cannot process MCA header in file \"%s\", chunks in that file will be lost", m_FileName.c_str()); - m_File.Close(); - return false; - } - } - return true; -} - - - - - -bool cWSSAnvil::cMCAFile::GetChunkData(const cChunkCoords & a_Chunk, AString & a_Data) -{ - if (!OpenFile(true)) - { - return false; - } - - int LocalX = a_Chunk.m_ChunkX % 32; - if (LocalX < 0) - { - LocalX = 32 + LocalX; - } - int LocalZ = a_Chunk.m_ChunkZ % 32; - if (LocalZ < 0) - { - LocalZ = 32 + LocalZ; - } - unsigned ChunkLocation = ntohl(m_Header[LocalX + 32 * LocalZ]); - unsigned ChunkOffset = ChunkLocation >> 8; - - m_File.Seek(ChunkOffset * 4096); - - int ChunkSize = 0; - if (m_File.Read(&ChunkSize, 4) != 4) - { - return false; - } - ChunkSize = ntohl(ChunkSize); - char CompressionType = 0; - if (m_File.Read(&CompressionType, 1) != 1) - { - return false; - } - if (CompressionType != 2) - { - // Chunk is in an unknown compression - return false; - } - ChunkSize--; - - // HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly - a_Data.assign(ChunkSize, '\0'); - return (m_File.Read((void *)a_Data.data(), ChunkSize) == ChunkSize); -} - - - - - -bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AString & a_Data) -{ - if (!OpenFile(false)) - { - return false; - } - - int LocalX = a_Chunk.m_ChunkX % 32; - if (LocalX < 0) - { - LocalX = 32 + LocalX; - } - int LocalZ = a_Chunk.m_ChunkZ % 32; - if (LocalZ < 0) - { - LocalZ = 32 + LocalZ; - } - - unsigned ChunkSector = FindFreeLocation(LocalX, LocalZ, a_Data); - - // Store the chunk data: - m_File.Seek(ChunkSector * 4096); - unsigned ChunkSize = htonl(a_Data.size() + 1); - if (m_File.Write(&ChunkSize, 4) != 4) - { - return false; - } - char CompressionType = 2; - if (m_File.Write(&CompressionType, 1) != 1) - { - return false; - } - if (m_File.Write(a_Data.data(), a_Data.size()) != (int)(a_Data.size())) - { - return false; - } - - // Store the header: - ChunkSize = (a_Data.size() + MCA_CHUNK_HEADER_LENGTH + 4095) / 4096; // Round data size *up* to nearest 4KB sector, make it a sector number - ASSERT(ChunkSize < 256); - m_Header[LocalX + 32 * LocalZ] = htonl((ChunkSector << 8) | ChunkSize); - m_File.Seek(0); - if (m_File.Write(m_Header, sizeof(m_Header)) != sizeof(m_Header)) - { - return false; - } - - return true; -} - - - - - -unsigned cWSSAnvil::cMCAFile::FindFreeLocation(int a_LocalX, int a_LocalZ, const AString & a_Data) -{ - // See if it fits the current location: - unsigned ChunkLocation = ntohl(m_Header[a_LocalX + 32 * a_LocalZ]); - unsigned ChunkLen = ChunkLocation & 0xff; - if (a_Data.size() + MCA_CHUNK_HEADER_LENGTH <= (ChunkLen * 4096)) - { - return ChunkLocation >> 8; - } - - // Doesn't fit, append to the end of file (we're wasting a lot of space, TODO: fix this later) - unsigned MaxLocation = 2 << 8; // Minimum sector is #2 - after the headers - for (int i = 0; i < ARRAYCOUNT(m_Header); i++) - { - ChunkLocation = ntohl(m_Header[i]); - ChunkLocation = ChunkLocation + ((ChunkLocation & 0xff) << 8); // Add the number of sectors used; don't care about the 4th byte - if (MaxLocation < ChunkLocation) - { - MaxLocation = ChunkLocation; - } - } // for i - m_Header[] - return MaxLocation >> 8; -} + +// WSSAnvil.cpp + +// Implements the cWSSAnvil class representing the Anvil world storage scheme + +#include "Globals.h" +#include "WSSAnvil.h" +#include "cWorld.h" +#include "zlib.h" +#include "BlockID.h" +#include "cChestEntity.h" +#include "cFurnaceEntity.h" +#include "cItem.h" +#include "StringCompression.h" +#include "cEntity.h" +#include "cBlockEntity.h" +#include "cMakeDir.h" +#include "FastNBT.h" + + + + + +/** Maximum number of MCA files that are cached in memory. +Since only the header is actually in the memory, this number can be high, but still, each file means an OS FS handle. +*/ +#define MAX_MCA_FILES 32 + +/// The maximum size of an inflated chunk; raw chunk data is 192 KiB, allow 64 KiB more of entities +#define CHUNK_INFLATE_MAX 256 KiB + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cNBTChunkSerializer + +class cNBTChunkSerializer : + public cChunkDataSeparateCollector +{ +public: + cNBTChunkSerializer(cFastNBTWriter & a_Writer) : + m_Writer(a_Writer), + m_IsTagOpen(false), + m_HasHadEntity(false), + m_HasHadBlockEntity(false), + m_IsLightValid(false) + { + } + + + /// Close NBT tags that we've opened + void Finish(void) + { + if (m_IsTagOpen) + { + m_Writer.EndList(); + } + } + + + bool IsLightValid(void) const {return m_IsLightValid; } + +protected: + + /* From cChunkDataSeparateCollector we inherit: + - m_BlockTypes[] + - m_BlockMetas[] + - m_BlockLight[] + - m_BlockSkyLight[] + */ + + // TODO: Biomes + + cFastNBTWriter & m_Writer; + + bool m_IsTagOpen; // True if a tag has been opened in the callbacks and not yet closed. + bool m_HasHadEntity; // True if any Entity has already been received and processed + bool m_HasHadBlockEntity; // True if any BlockEntity has already been received and processed + bool m_IsLightValid; // True if the chunk lighting is valid + + + void AddBasicTileEntity(cBlockEntity * a_Entity, const char * a_EntityTypeID) + { + m_Writer.AddInt ("x", a_Entity->GetPosX()); + m_Writer.AddInt ("y", a_Entity->GetPosY()); + m_Writer.AddInt ("z", a_Entity->GetPosZ()); + m_Writer.AddString("id", a_EntityTypeID); + } + + + void AddItem(const cItem * a_Item, int a_Slot) + { + m_Writer.BeginCompound(""); + m_Writer.AddShort("id", (short)(a_Item->m_ItemID)); + m_Writer.AddShort("Damage", a_Item->m_ItemHealth); + m_Writer.AddByte ("Count", a_Item->m_ItemCount); + m_Writer.AddByte ("Slot", (unsigned char)a_Slot); + m_Writer.EndCompound(); + } + + + void AddChestEntity(cChestEntity * a_Entity) + { + m_Writer.BeginCompound(""); + AddBasicTileEntity(a_Entity, "Chest"); + m_Writer.BeginList("Items", TAG_Compound); + for (int i = 0; i < cChestEntity::c_ChestHeight * cChestEntity::c_ChestWidth; i++) + { + const cItem * Item = a_Entity->GetSlot(i); + if ((Item == NULL) || Item->IsEmpty()) + { + continue; + } + AddItem(Item, i); + } + m_Writer.EndList(); + m_Writer.EndCompound(); + } + + + void AddFurnaceEntity(cFurnaceEntity * a_Furnace) + { + m_Writer.BeginCompound(""); + AddBasicTileEntity(a_Furnace, "Furnace"); + m_Writer.BeginList("Items", TAG_Compound); + AddItem(&a_Furnace->GetSlot(0), 0); + AddItem(&a_Furnace->GetSlot(1), 1); + AddItem(&a_Furnace->GetSlot(2), 2); + m_Writer.EndList(); + m_Writer.AddShort("BurnTime", (Int16)(a_Furnace->GetTimeToBurn() / 50.0)); + m_Writer.AddShort("CookTime", (Int16)(a_Furnace->GetTimeCooked() / 50.0)); + m_Writer.EndCompound(); + } + + + virtual bool LightIsValid(bool a_IsLightValid) override + { + m_IsLightValid = a_IsLightValid; + return a_IsLightValid; // We want lighting only if it's valid, otherwise don't bother + } + + + virtual void Entity(cEntity * a_Entity) override + { + // TODO: Add entity into NBT: + } + + + virtual void BlockEntity(cBlockEntity * a_Entity) + { + if (m_IsTagOpen) + { + if (!m_HasHadBlockEntity) + { + m_Writer.EndList(); + m_Writer.BeginList("TileEntities", TAG_Compound); + } + } + else + { + m_Writer.BeginList("TileEntities", TAG_Compound); + } + m_IsTagOpen = true; + + // Add tile-entity into NBT: + switch (a_Entity->GetBlockType()) + { + case E_BLOCK_CHEST: AddChestEntity ((cChestEntity *) a_Entity); break; + case E_BLOCK_FURNACE: AddFurnaceEntity((cFurnaceEntity *)a_Entity); break; + default: + { + ASSERT(!"Unhandled block entity saved into Anvil"); + } + } + m_HasHadBlockEntity = true; + } +} ; // class cNBTChunkSerializer + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cWSSAnvil: + +cWSSAnvil::cWSSAnvil(cWorld * a_World) : + super(a_World) +{ + // Create a level.dat file for mapping tools, if it doesn't already exist: + AString fnam; + Printf(fnam, "%s/level.dat", a_World->GetName().c_str()); + if (!cFile::Exists(fnam)) + { + cFastNBTWriter Writer; + Writer.BeginCompound(""); + Writer.AddInt("SpawnX", (int)(a_World->GetSpawnX())); + Writer.AddInt("SpawnY", (int)(a_World->GetSpawnY())); + Writer.AddInt("SpawnZ", (int)(a_World->GetSpawnZ())); + Writer.EndCompound(); + Writer.Finish(); + + #ifdef _DEBUG + cParsedNBT TestParse(Writer.GetResult().data(), Writer.GetResult().size()); + ASSERT(TestParse.IsValid()); + #endif // _DEBUG + + gzFile gz = gzopen(fnam.c_str(), "wb"); + if (gz != NULL) + { + gzwrite(gz, Writer.GetResult().data(), Writer.GetResult().size()); + } + gzclose(gz); + } +} + + + + + +cWSSAnvil::~cWSSAnvil() +{ + cCSLock Lock(m_CS); + for (cMCAFiles::iterator itr = m_Files.begin(); itr != m_Files.end(); ++itr) + { + delete *itr; + } // for itr - m_Files[] +} + + + + + +bool cWSSAnvil::LoadChunk(const cChunkCoords & a_Chunk) +{ + AString ChunkData; + if (!GetChunkData(a_Chunk, ChunkData)) + { + // The reason for failure is already printed in GetChunkData() + return false; + } + + return LoadChunkFromData(a_Chunk, ChunkData); +} + + + + + +bool cWSSAnvil::SaveChunk(const cChunkCoords & a_Chunk) +{ + AString ChunkData; + if (!SaveChunkToData(a_Chunk, ChunkData)) + { + return false; + } + if (!SetChunkData(a_Chunk, ChunkData)) + { + return false; + } + + // Everything successful + return true; +} + + + + + +bool cWSSAnvil::GetChunkData(const cChunkCoords & a_Chunk, AString & a_Data) +{ + cCSLock Lock(m_CS); + cMCAFile * File = LoadMCAFile(a_Chunk); + if (File == NULL) + { + return false; + } + return File->GetChunkData(a_Chunk, a_Data); +} + + + + + +bool cWSSAnvil::SetChunkData(const cChunkCoords & a_Chunk, const AString & a_Data) +{ + cCSLock Lock(m_CS); + cMCAFile * File = LoadMCAFile(a_Chunk); + if (File == NULL) + { + return false; + } + return File->SetChunkData(a_Chunk, a_Data); +} + + + + + +cWSSAnvil::cMCAFile * cWSSAnvil::LoadMCAFile(const cChunkCoords & a_Chunk) +{ + // ASSUME m_CS is locked + + const int RegionX = (int)(floorf((float)a_Chunk.m_ChunkX / 32.0f)); + const int RegionZ = (int)(floorf((float)a_Chunk.m_ChunkZ / 32.0f)); + + // Is it already cached? + for (cMCAFiles::iterator itr = m_Files.begin(); itr != m_Files.end(); ++itr) + { + if (((*itr) != NULL) && ((*itr)->GetRegionX() == RegionX) && ((*itr)->GetRegionZ() == RegionZ)) + { + // Move the file to front and return it: + cMCAFile * f = *itr; + if (itr != m_Files.begin()) + { + m_Files.erase(itr); + m_Files.push_front(f); + } + return f; + } + } + + // Load it anew: + AString FileName; + Printf(FileName, "%s/region", m_World->GetName().c_str()); + cMakeDir::MakeDir(FileName); + AppendPrintf(FileName, "/r.%d.%d.mca", RegionX, RegionZ); + cMCAFile * f = new cMCAFile(FileName, RegionX, RegionZ); + if (f == NULL) + { + return NULL; + } + m_Files.push_front(f); + + // If there are too many MCA files cached, delete the last one used: + if (m_Files.size() > MAX_MCA_FILES) + { + delete m_Files.back(); + m_Files.pop_back(); + } + return f; +} + + + + + +bool cWSSAnvil::LoadChunkFromData(const cChunkCoords & a_Chunk, const AString & a_Data) +{ + // Decompress the data: + char Uncompressed[CHUNK_INFLATE_MAX]; + z_stream strm; + strm.zalloc = (alloc_func)NULL; + strm.zfree = (free_func)NULL; + strm.opaque = NULL; + inflateInit(&strm); + strm.next_out = (Bytef *)Uncompressed; + strm.avail_out = sizeof(Uncompressed); + strm.next_in = (Bytef *)a_Data.data(); + strm.avail_in = a_Data.size(); + int res = inflate(&strm, Z_FINISH); + inflateEnd(&strm); + if (res != Z_STREAM_END) + { + return false; + } + + // Parse the NBT data: + cParsedNBT NBT(Uncompressed, strm.total_out); + if (!NBT.IsValid()) + { + // NBT Parsing failed + return false; + } + + // Load the data from NBT: + return LoadChunkFromNBT(a_Chunk, NBT); +} + + + + + +bool cWSSAnvil::SaveChunkToData(const cChunkCoords & a_Chunk, AString & a_Data) +{ + cFastNBTWriter Writer; + if (!SaveChunkToNBT(a_Chunk, Writer)) + { + return false; + } + Writer.Finish(); + CompressString(Writer.GetResult().data(), Writer.GetResult().size(), a_Data); + return true; +} + + + + + +bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT & a_NBT) +{ + // The data arrays, in MCA-native y/z/x ordering (will be reordered for the final chunk data) + cChunkDef::BlockTypes BlockTypes; + cChunkDef::BlockNibbles MetaData; + cChunkDef::BlockNibbles BlockLight; + cChunkDef::BlockNibbles SkyLight; + + memset(BlockTypes, E_BLOCK_AIR, sizeof(BlockTypes)); + memset(MetaData, 0, sizeof(MetaData)); + memset(SkyLight, 0xff, sizeof(SkyLight)); // By default, data not present in the NBT means air, which means full skylight + memset(BlockLight, 0x00, sizeof(BlockLight)); + + // Load the blockdata, blocklight and skylight: + int Level = a_NBT.FindChildByName(0, "Level"); + if (Level < 0) + { + return false; + } + int Sections = a_NBT.FindChildByName(Level, "Sections"); + if ((Sections < 0) || (a_NBT.GetType(Sections) != TAG_List) || (a_NBT.GetChildrenType(Sections) != TAG_Compound)) + { + return false; + } + for (int Child = a_NBT.GetFirstChild(Sections); Child >= 0; Child = a_NBT.GetNextSibling(Child)) + { + int y = 0; + int SectionY = a_NBT.FindChildByName(Child, "Y"); + if ((SectionY < 0) || (a_NBT.GetType(SectionY) != TAG_Byte)) + { + continue; + } + y = a_NBT.GetByte(SectionY); + if ((y < 0) || (y > 15)) + { + continue; + } + CopyNBTData(a_NBT, Child, "Blocks", (char *)&(BlockTypes[y * 4096]), 4096); + CopyNBTData(a_NBT, Child, "Data", (char *)&(MetaData[y * 2048]), 2048); + CopyNBTData(a_NBT, Child, "SkyLight", (char *)&(SkyLight[y * 2048]), 2048); + CopyNBTData(a_NBT, Child, "BlockLight", (char *)&(BlockLight[y * 2048]), 2048); + } // for itr - LevelSections[] + + // Load the biomes from NBT, if present and valid: + cChunkDef::BiomeMap BiomeMap; + cChunkDef::BiomeMap * Biomes = LoadBiomeMapFromNBT(&BiomeMap, a_NBT, a_NBT.FindChildByName(Level, "Biomes")); + + // Load the entities from NBT: + cEntityList Entities; + cBlockEntityList BlockEntities; + LoadEntitiesFromNBT (Entities, a_NBT, a_NBT.FindChildByName(Level, "Entities")); + LoadBlockEntitiesFromNBT(BlockEntities, a_NBT, a_NBT.FindChildByName(Level, "TileEntities")); + + bool IsLightValid = (a_NBT.FindChildByName(Level, "MCSIsLightValid") > 0); + + /* + // Uncomment this block for really cool stuff :) + // DEBUG magic: Invert the underground, so that we can see the MC generator in action :) + bool ShouldInvert[cChunkDef::Width * cChunkDef::Width]; + memset(ShouldInvert, 0, sizeof(ShouldInvert)); + for (int y = cChunkDef::Height - 1; y >= 0; y--) + { + for (int x = 0; x < cChunkDef::Width; x++) for (int z = 0; z < cChunkDef::Width; z++) + { + int Index = cChunkDef::MakeIndexNoCheck(x, y, z); + if (ShouldInvert[x + cChunkDef::Width * z]) + { + ChunkData[Index] = (ChunkData[Index] == E_BLOCK_AIR) ? E_BLOCK_STONE : E_BLOCK_AIR; + } + else + { + ShouldInvert[x + cChunkDef::Width * z] = (ChunkData[Index] != E_BLOCK_AIR); + } + } + } // for y + // Set everything alight, so that we can see: + memset(ChunkData + cChunkDef::SkyLightOffset, 0xff, cChunkDef::NumBlocks / 2); + //*/ + + m_World->SetChunkData( + a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, + BlockTypes, MetaData, + IsLightValid ? BlockLight : NULL, + IsLightValid ? SkyLight : NULL, + NULL, Biomes, + Entities, BlockEntities, + false + ); + return true; +} + + + + +void cWSSAnvil::CopyNBTData(const cParsedNBT & a_NBT, int a_Tag, const AString & a_ChildName, char * a_Destination, int a_Length) +{ + int Child = a_NBT.FindChildByName(a_Tag, a_ChildName); + if ((Child >= 0) && (a_NBT.GetType(Child) == TAG_ByteArray) && (a_NBT.GetDataLength(Child) == a_Length)) + { + memcpy(a_Destination, a_NBT.GetData(Child), a_Length); + } +} + + + + + +bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_Writer) +{ + a_Writer.BeginCompound("Level"); + a_Writer.AddInt("xPos", a_Chunk.m_ChunkX); + a_Writer.AddInt("zPos", a_Chunk.m_ChunkZ); + cNBTChunkSerializer Serializer(a_Writer); + if (!m_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, Serializer)) + { + return false; + } + Serializer.Finish(); // Close NBT tags + + // TODO: Save biomes, both MCS (IntArray) and MC-vanilla (ByteArray): + // Level->Add(new cNBTByteArray(Level, "Biomes", AString(Serializer.m_Biomes, sizeof(Serializer.m_Biomes)); + // Level->Add(new cNBTByteArray(Level, "MCSBiomes", AString(Serializer.m_Biomes, sizeof(Serializer.m_Biomes)); + + // Save blockdata: + a_Writer.BeginList("Sections", TAG_Compound); + int SliceSizeBlock = cChunkDef::Width * cChunkDef::Width * 16; + int SliceSizeNibble = SliceSizeBlock / 2; + const char * BlockTypes = (const char *)(Serializer.m_BlockTypes); + const char * BlockMetas = (const char *)(Serializer.m_BlockMetas); + const char * BlockLight = (const char *)(Serializer.m_BlockLight); + const char * BlockSkyLight = (const char *)(Serializer.m_BlockSkyLight); + for (int Y = 0; Y < 16; Y++) + { + a_Writer.BeginCompound(""); + a_Writer.AddByteArray("Blocks", BlockTypes + Y * SliceSizeBlock, SliceSizeBlock); + a_Writer.AddByteArray("Data", BlockMetas + Y * SliceSizeNibble, SliceSizeNibble); + a_Writer.AddByteArray("SkyLight", BlockSkyLight + Y * SliceSizeNibble, SliceSizeNibble); + a_Writer.AddByteArray("BlockLight", BlockLight + Y * SliceSizeNibble, SliceSizeNibble); + a_Writer.AddByte("Y", (unsigned char)Y); + a_Writer.EndCompound(); + } + a_Writer.EndList(); // "Sections" + + // Store the information that the lighting is valid. + // For compatibility reason, the default is "invalid" (missing) - this means older data is re-lighted upon loading. + if (Serializer.IsLightValid()) + { + a_Writer.AddByte("MCSIsLightValid", 1); + } + + a_Writer.EndCompound(); // "Level" + return true; +} + + + + + +cChunkDef::BiomeMap * cWSSAnvil::LoadBiomeMapFromNBT(cChunkDef::BiomeMap * a_BiomeMap, const cParsedNBT & a_NBT, int a_TagIdx) +{ + if ((a_TagIdx < 0) || (a_NBT.GetType(a_TagIdx) != TAG_ByteArray)) + { + return NULL; + } + if (a_NBT.GetDataLength(a_TagIdx) != sizeof(*a_BiomeMap)) + { + // The biomes stored don't match in size + return NULL; + } + memcpy(a_BiomeMap, a_NBT.GetData(a_TagIdx), sizeof(*a_BiomeMap)); + for (int i = 0; i < ARRAYCOUNT(*a_BiomeMap); i++) + { + if ((*a_BiomeMap)[i] == 0xff) + { + // Unassigned biomes + return NULL; + } + } + return a_BiomeMap; +} + + + + + +void cWSSAnvil::LoadEntitiesFromNBT(cEntityList & a_Entitites, const cParsedNBT & a_NBT, int a_TagIdx) +{ + // TODO: Load the entities +} + + + + + +void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + if ((a_TagIdx < 0) || (a_NBT.GetType(a_TagIdx) != TAG_List)) + { + return; + } + + for (int Child = a_NBT.GetFirstChild(a_TagIdx); Child != -1; Child = a_NBT.GetNextSibling(Child)) + { + if (a_NBT.GetType(Child) != TAG_Compound) + { + continue; + } + int sID = a_NBT.FindChildByName(Child, "id"); + if (sID < 0) + { + continue; + } + if (strncmp(a_NBT.GetData(sID), "Chest", a_NBT.GetDataLength(sID)) == 0) + { + LoadChestFromNBT(a_BlockEntities, a_NBT, Child); + } + else if (strncmp(a_NBT.GetData(sID), "Furnace", a_NBT.GetDataLength(sID)) == 0) + { + LoadFurnaceFromNBT(a_BlockEntities, a_NBT, Child); + } + // TODO: Other block entities + } // for Child - tag children +} + + + + + +void cWSSAnvil::LoadChestFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); + int x, y, z; + if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + { + return; + } + int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); + if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) + { + return; // Make it an empty chest - the chunk loader will provide an empty cChestEntity for this + } + std::auto_ptr Chest(new cChestEntity(x, y, z, m_World)); + for (int Child = a_NBT.GetFirstChild(Items); Child != -1; Child = a_NBT.GetNextSibling(Child)) + { + int Slot = a_NBT.FindChildByName(Child, "Slot"); + if ((Slot < 0) || (a_NBT.GetType(Slot) != TAG_Byte)) + { + continue; + } + cItem Item; + int ID = a_NBT.FindChildByName(Child, "id"); + if ((ID < 0) || (a_NBT.GetType(ID) != TAG_Short)) + { + continue; + } + Item.m_ItemID = (ENUM_ITEM_ID)(a_NBT.GetShort(ID)); + int Damage = a_NBT.FindChildByName(Child, "Damage"); + if ((Damage < 0) || (a_NBT.GetType(Damage) != TAG_Short)) + { + continue; + } + Item.m_ItemHealth = a_NBT.GetShort(Damage); + int Count = a_NBT.FindChildByName(Child, "Count"); + if ((Count < 0) || (a_NBT.GetType(Count) != TAG_Byte)) + { + continue; + } + Item.m_ItemCount = a_NBT.GetByte(Count); + Chest->SetSlot(a_NBT.GetByte(Slot), Item); + } // for itr - ItemDefs[] + a_BlockEntities.push_back(Chest.release()); +} + + + + + +void cWSSAnvil::LoadFurnaceFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); + int x, y, z; + if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + { + return; + } + int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); + if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) + { + return; // Make it an empty furnace - the chunk loader will provide an empty cFurnaceEntity for this + } + std::auto_ptr Furnace(new cFurnaceEntity(x, y, z, m_World)); + for (int Child = a_NBT.GetFirstChild(Items); Child != -1; Child = a_NBT.GetNextSibling(Child)) + { + int Slot = a_NBT.FindChildByName(Child, "Slot"); + if ((Slot < 0) || (a_NBT.GetType(Slot) != TAG_Byte)) + { + continue; + } + cItem Item; + int ID = a_NBT.FindChildByName(Child, "id"); + if ((ID < 0) || (a_NBT.GetType(ID) != TAG_Short)) + { + continue; + } + Item.m_ItemID = (ENUM_ITEM_ID)(a_NBT.GetShort(ID)); + int Damage = a_NBT.FindChildByName(Child, "Damage"); + if ((Damage < 0) || (a_NBT.GetType(Damage) != TAG_Short)) + { + continue; + } + Item.m_ItemHealth = a_NBT.GetShort(Damage); + int Count = a_NBT.FindChildByName(Child, "Count"); + if ((Count < 0) || (a_NBT.GetType(Count) != TAG_Byte)) + { + continue; + } + Item.m_ItemCount = a_NBT.GetByte(Count); + Furnace->SetSlot(a_NBT.GetByte(Slot), Item); + } // for itr - ItemDefs[] + int BurnTime = a_NBT.FindChildByName(a_TagIdx, "BurnTime"); + if (BurnTime >= 0) + { + Int16 bt = a_NBT.GetShort(BurnTime); + // Anvil doesn't store the time that the fuel can burn. We simply "reset" the current value to be the 100% + Furnace->SetBurnTimes((float)(bt * 50.0), (float)(bt * 50.0)); + } + int CookTime = a_NBT.FindChildByName(a_TagIdx, "CookTime"); + if (CookTime >= 0) + { + Int16 ct = a_NBT.GetShort(CookTime); + // Anvil doesn't store the time that an item takes to cook. We simply use the default - 10 seconds + Furnace->SetCookTimes(10000.0, (float)(ct * 50.0)); + } + Furnace->ContinueCooking(); + a_BlockEntities.push_back(Furnace.release()); +} + + + + + +bool cWSSAnvil::GetBlockEntityNBTPos(const cParsedNBT & a_NBT, int a_TagIdx, int & a_X, int & a_Y, int & a_Z) +{ + int x = a_NBT.FindChildByName(a_TagIdx, "x"); + if ((x < 0) || (a_NBT.GetType(x) != TAG_Int)) + { + return false; + } + int y = a_NBT.FindChildByName(a_TagIdx, "y"); + if ((y < 0) || (a_NBT.GetType(y) != TAG_Int)) + { + return false; + } + int z = a_NBT.FindChildByName(a_TagIdx, "z"); + if ((z < 0) || (a_NBT.GetType(z) != TAG_Int)) + { + return false; + } + a_X = a_NBT.GetInt(x); + a_Y = a_NBT.GetInt(y); + a_Z = a_NBT.GetInt(z); + return true; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cWSSAnvil::cMCAFile: + +cWSSAnvil::cMCAFile::cMCAFile(const AString & a_FileName, int a_RegionX, int a_RegionZ) : + m_RegionX(a_RegionX), + m_RegionZ(a_RegionZ), + m_FileName(a_FileName) +{ +} + + + + + +bool cWSSAnvil::cMCAFile::OpenFile(bool a_IsForReading) +{ + if (m_File.IsOpen()) + { + // Already open + return true; + } + + if (a_IsForReading) + { + if (!cFile::Exists(m_FileName)) + { + // We want to read and the file doesn't exist. Fail. + return false; + } + } + + if (!m_File.Open(m_FileName, cFile::fmReadWrite)) + { + // The file failed to open + return false; + } + + // Load the header: + if (m_File.Read(m_Header, sizeof(m_Header)) != sizeof(m_Header)) + { + // Cannot read the header - perhaps the file has just been created? + // Try writing a NULL header (both chunk offsets and timestamps): + memset(m_Header, 0, sizeof(m_Header)); + if ( + (m_File.Write(m_Header, sizeof(m_Header)) != sizeof(m_Header)) || // Real header - chunk offsets + (m_File.Write(m_Header, sizeof(m_Header)) != sizeof(m_Header)) // Bogus data for the chunk timestamps + ) + { + LOGWARNING("Cannot process MCA header in file \"%s\", chunks in that file will be lost", m_FileName.c_str()); + m_File.Close(); + return false; + } + } + return true; +} + + + + + +bool cWSSAnvil::cMCAFile::GetChunkData(const cChunkCoords & a_Chunk, AString & a_Data) +{ + if (!OpenFile(true)) + { + return false; + } + + int LocalX = a_Chunk.m_ChunkX % 32; + if (LocalX < 0) + { + LocalX = 32 + LocalX; + } + int LocalZ = a_Chunk.m_ChunkZ % 32; + if (LocalZ < 0) + { + LocalZ = 32 + LocalZ; + } + unsigned ChunkLocation = ntohl(m_Header[LocalX + 32 * LocalZ]); + unsigned ChunkOffset = ChunkLocation >> 8; + + m_File.Seek(ChunkOffset * 4096); + + int ChunkSize = 0; + if (m_File.Read(&ChunkSize, 4) != 4) + { + return false; + } + ChunkSize = ntohl(ChunkSize); + char CompressionType = 0; + if (m_File.Read(&CompressionType, 1) != 1) + { + return false; + } + if (CompressionType != 2) + { + // Chunk is in an unknown compression + return false; + } + ChunkSize--; + + // HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly + a_Data.assign(ChunkSize, '\0'); + return (m_File.Read((void *)a_Data.data(), ChunkSize) == ChunkSize); +} + + + + + +bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AString & a_Data) +{ + if (!OpenFile(false)) + { + return false; + } + + int LocalX = a_Chunk.m_ChunkX % 32; + if (LocalX < 0) + { + LocalX = 32 + LocalX; + } + int LocalZ = a_Chunk.m_ChunkZ % 32; + if (LocalZ < 0) + { + LocalZ = 32 + LocalZ; + } + + unsigned ChunkSector = FindFreeLocation(LocalX, LocalZ, a_Data); + + // Store the chunk data: + m_File.Seek(ChunkSector * 4096); + unsigned ChunkSize = htonl(a_Data.size() + 1); + if (m_File.Write(&ChunkSize, 4) != 4) + { + return false; + } + char CompressionType = 2; + if (m_File.Write(&CompressionType, 1) != 1) + { + return false; + } + if (m_File.Write(a_Data.data(), a_Data.size()) != (int)(a_Data.size())) + { + return false; + } + + // Store the header: + ChunkSize = (a_Data.size() + MCA_CHUNK_HEADER_LENGTH + 4095) / 4096; // Round data size *up* to nearest 4KB sector, make it a sector number + ASSERT(ChunkSize < 256); + m_Header[LocalX + 32 * LocalZ] = htonl((ChunkSector << 8) | ChunkSize); + m_File.Seek(0); + if (m_File.Write(m_Header, sizeof(m_Header)) != sizeof(m_Header)) + { + return false; + } + + return true; +} + + + + + +unsigned cWSSAnvil::cMCAFile::FindFreeLocation(int a_LocalX, int a_LocalZ, const AString & a_Data) +{ + // See if it fits the current location: + unsigned ChunkLocation = ntohl(m_Header[a_LocalX + 32 * a_LocalZ]); + unsigned ChunkLen = ChunkLocation & 0xff; + if (a_Data.size() + MCA_CHUNK_HEADER_LENGTH <= (ChunkLen * 4096)) + { + return ChunkLocation >> 8; + } + + // Doesn't fit, append to the end of file (we're wasting a lot of space, TODO: fix this later) + unsigned MaxLocation = 2 << 8; // Minimum sector is #2 - after the headers + for (int i = 0; i < ARRAYCOUNT(m_Header); i++) + { + ChunkLocation = ntohl(m_Header[i]); + ChunkLocation = ChunkLocation + ((ChunkLocation & 0xff) << 8); // Add the number of sectors used; don't care about the 4th byte + if (MaxLocation < ChunkLocation) + { + MaxLocation = ChunkLocation; + } + } // for i - m_Header[] + return MaxLocation >> 8; +} diff --git a/source/WSSAnvil.h b/source/WSSAnvil.h index f8beea524..ab03adf5e 100644 --- a/source/WSSAnvil.h +++ b/source/WSSAnvil.h @@ -1,131 +1,131 @@ - -// WSSAnvil.h - -// Interfaces to the cWSSAnvil class representing the Anvil world storage scheme - - - - -#pragma once - -#include "WorldStorage.h" -#include "FastNBT.h" - - - - - -enum -{ - /// Maximum number of chunks in an MCA file - also the count of the header items - MCA_MAX_CHUNKS = 32 * 32, - - /// The MCA header is 8 KiB - MCA_HEADER_SIZE = MCA_MAX_CHUNKS * 8, - - /// There are 5 bytes of header in front of each chunk - MCA_CHUNK_HEADER_LENGTH = 5, -} ; - - - - - -class cWSSAnvil : - public cWSSchema -{ - typedef cWSSchema super; - -public: - - cWSSAnvil(cWorld * a_World); - virtual ~cWSSAnvil(); - -protected: - - class cMCAFile - { - public: - - cMCAFile(const AString & a_FileName, int a_RegionX, int a_RegionZ); - - bool GetChunkData (const cChunkCoords & a_Chunk, AString & a_Data); - bool SetChunkData (const cChunkCoords & a_Chunk, const AString & a_Data); - bool EraseChunkData(const cChunkCoords & a_Chunk); - - int GetRegionX (void) const {return m_RegionX; } - int GetRegionZ (void) const {return m_RegionZ; } - const AString & GetFileName(void) const {return m_FileName; } - - protected: - - int m_RegionX; - int m_RegionZ; - cFile m_File; - AString m_FileName; - - // The header, copied from the file so we don't have to seek to it all the time - // First 1024 entries are chunk locations - the 3 + 1 byte sector-offset and sector-count - unsigned m_Header[MCA_MAX_CHUNKS]; - - // Chunk timestamps, following the chunk headers, are unused by MCS - - /// Finds a free location large enough to hold a_Data. Gets a hint of the chunk coords, places the data there if it fits. Returns the sector number. - unsigned FindFreeLocation(int a_LocalX, int a_LocalZ, const AString & a_Data); - - /// Opens a MCA file either for a Read operation (fails if doesn't exist) or for a Write operation (creates new if not found) - bool OpenFile(bool a_IsForReading); - } ; - typedef std::list cMCAFiles; - - cCriticalSection m_CS; - cMCAFiles m_Files; // a MRU cache of MCA files - - /// Gets chunk data from the correct file; locks file CS as needed - bool GetChunkData(const cChunkCoords & a_Chunk, AString & a_Data); - - /// Sets chunk data into the correct file; locks file CS as needed - bool SetChunkData(const cChunkCoords & a_Chunk, const AString & a_Data); - - /// Loads the chunk from the data (no locking needed) - bool LoadChunkFromData(const cChunkCoords & a_Chunk, const AString & a_Data); - - /// Saves the chunk into datastream (no locking needed) - bool SaveChunkToData(const cChunkCoords & a_Chunk, AString & a_Data); - - /// Loads the chunk from NBT data (no locking needed) - bool LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT & a_NBT); - - /// Saves the chunk into NBT data using a_Writer; returns true on success - bool SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_Writer); - - /// Loads the chunk's biome map; returns a_BiomeMap if biomes present and valid, NULL otherwise - cChunkDef::BiomeMap * LoadBiomeMapFromNBT(cChunkDef::BiomeMap * a_BiomeMap, const cParsedNBT & a_NBT, int a_TagIdx); - - /// Loads the chunk's entities from NBT data (a_Tag is the Level\\Entities list tag; may be -1) - void LoadEntitiesFromNBT(cEntityList & a_Entitites, const cParsedNBT & a_NBT, int a_Tag); - - /// Loads the chunk's BlockEntities from NBT data (a_Tag is the Level\\TileEntities list tag; may be -1) - void LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntitites, const cParsedNBT & a_NBT, int a_Tag); - - void LoadChestFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadFurnaceFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - - /// Helper function for extracting the X, Y, and Z int subtags of a NBT compound; returns true if successful - bool GetBlockEntityNBTPos(const cParsedNBT & a_NBT, int a_TagIdx, int & a_X, int & a_Y, int & a_Z); - - /// Gets the correct MCA file either from cache or from disk, manages the m_MCAFiles cache; assumes m_CS is locked - cMCAFile * LoadMCAFile(const cChunkCoords & a_Chunk); - - /// Copies a_Length bytes of data from the specified NBT Tag's Child into the a_Destination buffer - void CopyNBTData(const cParsedNBT & a_NBT, int a_Tag, const AString & a_ChildName, char * a_Destination, int a_Length); - - // cWSSchema overrides: - virtual bool LoadChunk(const cChunkCoords & a_Chunk) override; - virtual bool SaveChunk(const cChunkCoords & a_Chunk) override; - virtual const AString GetName(void) const override {return "anvil"; } -} ; - - - - + +// WSSAnvil.h + +// Interfaces to the cWSSAnvil class representing the Anvil world storage scheme + + + + +#pragma once + +#include "WorldStorage.h" +#include "FastNBT.h" + + + + + +enum +{ + /// Maximum number of chunks in an MCA file - also the count of the header items + MCA_MAX_CHUNKS = 32 * 32, + + /// The MCA header is 8 KiB + MCA_HEADER_SIZE = MCA_MAX_CHUNKS * 8, + + /// There are 5 bytes of header in front of each chunk + MCA_CHUNK_HEADER_LENGTH = 5, +} ; + + + + + +class cWSSAnvil : + public cWSSchema +{ + typedef cWSSchema super; + +public: + + cWSSAnvil(cWorld * a_World); + virtual ~cWSSAnvil(); + +protected: + + class cMCAFile + { + public: + + cMCAFile(const AString & a_FileName, int a_RegionX, int a_RegionZ); + + bool GetChunkData (const cChunkCoords & a_Chunk, AString & a_Data); + bool SetChunkData (const cChunkCoords & a_Chunk, const AString & a_Data); + bool EraseChunkData(const cChunkCoords & a_Chunk); + + int GetRegionX (void) const {return m_RegionX; } + int GetRegionZ (void) const {return m_RegionZ; } + const AString & GetFileName(void) const {return m_FileName; } + + protected: + + int m_RegionX; + int m_RegionZ; + cFile m_File; + AString m_FileName; + + // The header, copied from the file so we don't have to seek to it all the time + // First 1024 entries are chunk locations - the 3 + 1 byte sector-offset and sector-count + unsigned m_Header[MCA_MAX_CHUNKS]; + + // Chunk timestamps, following the chunk headers, are unused by MCS + + /// Finds a free location large enough to hold a_Data. Gets a hint of the chunk coords, places the data there if it fits. Returns the sector number. + unsigned FindFreeLocation(int a_LocalX, int a_LocalZ, const AString & a_Data); + + /// Opens a MCA file either for a Read operation (fails if doesn't exist) or for a Write operation (creates new if not found) + bool OpenFile(bool a_IsForReading); + } ; + typedef std::list cMCAFiles; + + cCriticalSection m_CS; + cMCAFiles m_Files; // a MRU cache of MCA files + + /// Gets chunk data from the correct file; locks file CS as needed + bool GetChunkData(const cChunkCoords & a_Chunk, AString & a_Data); + + /// Sets chunk data into the correct file; locks file CS as needed + bool SetChunkData(const cChunkCoords & a_Chunk, const AString & a_Data); + + /// Loads the chunk from the data (no locking needed) + bool LoadChunkFromData(const cChunkCoords & a_Chunk, const AString & a_Data); + + /// Saves the chunk into datastream (no locking needed) + bool SaveChunkToData(const cChunkCoords & a_Chunk, AString & a_Data); + + /// Loads the chunk from NBT data (no locking needed) + bool LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT & a_NBT); + + /// Saves the chunk into NBT data using a_Writer; returns true on success + bool SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_Writer); + + /// Loads the chunk's biome map; returns a_BiomeMap if biomes present and valid, NULL otherwise + cChunkDef::BiomeMap * LoadBiomeMapFromNBT(cChunkDef::BiomeMap * a_BiomeMap, const cParsedNBT & a_NBT, int a_TagIdx); + + /// Loads the chunk's entities from NBT data (a_Tag is the Level\\Entities list tag; may be -1) + void LoadEntitiesFromNBT(cEntityList & a_Entitites, const cParsedNBT & a_NBT, int a_Tag); + + /// Loads the chunk's BlockEntities from NBT data (a_Tag is the Level\\TileEntities list tag; may be -1) + void LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntitites, const cParsedNBT & a_NBT, int a_Tag); + + void LoadChestFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadFurnaceFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); + + /// Helper function for extracting the X, Y, and Z int subtags of a NBT compound; returns true if successful + bool GetBlockEntityNBTPos(const cParsedNBT & a_NBT, int a_TagIdx, int & a_X, int & a_Y, int & a_Z); + + /// Gets the correct MCA file either from cache or from disk, manages the m_MCAFiles cache; assumes m_CS is locked + cMCAFile * LoadMCAFile(const cChunkCoords & a_Chunk); + + /// Copies a_Length bytes of data from the specified NBT Tag's Child into the a_Destination buffer + void CopyNBTData(const cParsedNBT & a_NBT, int a_Tag, const AString & a_ChildName, char * a_Destination, int a_Length); + + // cWSSchema overrides: + virtual bool LoadChunk(const cChunkCoords & a_Chunk) override; + virtual bool SaveChunk(const cChunkCoords & a_Chunk) override; + virtual const AString GetName(void) const override {return "anvil"; } +} ; + + + + diff --git a/source/WSSCompact.cpp b/source/WSSCompact.cpp index 1064528bc..406b55d38 100644 --- a/source/WSSCompact.cpp +++ b/source/WSSCompact.cpp @@ -1,942 +1,942 @@ - -// WSSCompact.cpp - -// Interfaces to the cWSSCompact class representing the "compact" storage schema (PAK-files) - -#include "Globals.h" -#include "WSSCompact.h" -#include "cWorld.h" -#include "zlib.h" -#include -#include "StringCompression.h" -#include "cChestEntity.h" -#include "cSignEntity.h" -#include "cFurnaceEntity.h" -#include "BlockID.h" - - - - - -#pragma pack(push, 1) -/// The chunk header, as stored in the file: -struct cWSSCompact::sChunkHeader -{ - int m_ChunkX; - int m_ChunkZ; - int m_CompressedSize; - int m_UncompressedSize; -} ; -#pragma pack(pop) - - - - - -/// The maximum number of PAK files that are cached -const int MAX_PAK_FILES = 16; - -/// The maximum number of unsaved chunks before the cPAKFile saves them to disk -const int MAX_DIRTY_CHUNKS = 16; - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cJsonChunkSerializer: - -cJsonChunkSerializer::cJsonChunkSerializer(void) : - m_HasJsonData(false) -{ -} - - - - - -void cJsonChunkSerializer::Entity(cEntity * a_Entity) -{ - // TODO: a_Entity->SaveToJson(m_Root); -} - - - - - -void cJsonChunkSerializer::BlockEntity(cBlockEntity * a_BlockEntity) -{ - const char * SaveInto = NULL; - switch (a_BlockEntity->GetBlockType()) - { - case E_BLOCK_CHEST: SaveInto = "Chests"; break; - case E_BLOCK_FURNACE: SaveInto = "Furnaces"; break; - case E_BLOCK_SIGN_POST: SaveInto = "Signs"; break; - case E_BLOCK_WALLSIGN: SaveInto = "Signs"; break; - - default: - { - ASSERT(!"Unhandled blocktype in BlockEntities list while saving to JSON"); - break; - } - } // switch (BlockEntity->GetBlockType()) - if (SaveInto == NULL) - { - return; - } - - Json::Value val; - a_BlockEntity->SaveToJson(val); - m_Root[SaveInto].append(val); - m_HasJsonData = true; -} - - - - - -bool cJsonChunkSerializer::LightIsValid(bool a_IsLightValid) -{ - if (!a_IsLightValid) - { - return false; - } - m_Root["IsLightValid"] = true; - m_HasJsonData = true; - return true; -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cWSSCompact: - -cWSSCompact::~cWSSCompact() -{ - for (cPAKFiles::iterator itr = m_PAKFiles.begin(); itr != m_PAKFiles.end(); ++itr) - { - delete *itr; - } -} - - - - - -bool cWSSCompact::LoadChunk(const cChunkCoords & a_Chunk) -{ - AString ChunkData; - int UncompressedSize = 0; - if (!GetChunkData(a_Chunk, UncompressedSize, ChunkData)) - { - // The reason for failure is already printed in GetChunkData() - return false; - } - - return LoadChunkFromData(a_Chunk, UncompressedSize, ChunkData, m_World); -} - - - - - -bool cWSSCompact::SaveChunk(const cChunkCoords & a_Chunk) -{ - cCSLock Lock(m_CS); - - cPAKFile * f = LoadPAKFile(a_Chunk); - if (f == NULL) - { - // For some reason we couldn't locate the file - LOG("Cannot locate a proper PAK file for chunk [%d, %d]", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); - return false; - } - return f->SaveChunk(a_Chunk, m_World); -} - - - - - -cWSSCompact::cPAKFile * cWSSCompact::LoadPAKFile(const cChunkCoords & a_Chunk) -{ - // ASSUMES that m_CS has been locked - - // We need to retain this weird conversion code, because some edge chunks are in the wrong PAK file - const int LayerX = (int)(floorf((float)a_Chunk.m_ChunkX / 32.0f)); - const int LayerZ = (int)(floorf((float)a_Chunk.m_ChunkZ / 32.0f)); - - // Is it already cached? - for (cPAKFiles::iterator itr = m_PAKFiles.begin(); itr != m_PAKFiles.end(); ++itr) - { - if (((*itr) != NULL) && ((*itr)->GetLayerX() == LayerX) && ((*itr)->GetLayerZ() == LayerZ)) - { - // Move the file to front and return it: - cPAKFile * f = *itr; - if (itr != m_PAKFiles.begin()) - { - m_PAKFiles.erase(itr); - m_PAKFiles.push_front(f); - } - return f; - } - } - - // Load it anew: - AString FileName; - Printf(FileName, "%s/X%i_Z%i.pak", m_World->GetName().c_str(), LayerX, LayerZ ); - cPAKFile * f = new cPAKFile(FileName, LayerX, LayerZ); - if (f == NULL) - { - return NULL; - } - m_PAKFiles.push_front(f); - - // If there are too many PAK files cached, delete the last one used: - if (m_PAKFiles.size() > MAX_PAK_FILES) - { - delete m_PAKFiles.back(); - m_PAKFiles.pop_back(); - } - return f; -} - - - - - -bool cWSSCompact::GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data) -{ - cCSLock Lock(m_CS); - cPAKFile * f = LoadPAKFile(a_Chunk); - if (f == NULL) - { - return false; - } - return f->GetChunkData(a_Chunk, a_UncompressedSize, a_Data); -} - - - - - -/* -// TODO: Rewrite saving to use the same principles as loading -bool cWSSCompact::SetChunkData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data) -{ - cCSLock Lock(m_CS); - cPAKFile * f = LoadPAKFile(a_Chunk); - if (f == NULL) - { - return false; - } - return f->SetChunkData(a_Chunk, a_UncompressedSize, a_Data); -} -*/ - - - - - -bool cWSSCompact::EraseChunkData(const cChunkCoords & a_Chunk) -{ - cCSLock Lock(m_CS); - cPAKFile * f = LoadPAKFile(a_Chunk); - if (f == NULL) - { - return false; - } - return f->EraseChunkData(a_Chunk); -} - - - - - -void cWSSCompact::LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities, cWorld * a_World) -{ - // Load chests - Json::Value AllChests = a_Value.get("Chests", Json::nullValue); - if (!AllChests.empty()) - { - for (Json::Value::iterator itr = AllChests.begin(); itr != AllChests.end(); ++itr ) - { - Json::Value & Chest = *itr; - cChestEntity * ChestEntity = new cChestEntity(0,0,0, a_World); - if (!ChestEntity->LoadFromJson( Chest ) ) - { - LOGERROR("ERROR READING CHEST FROM JSON!" ); - delete ChestEntity; - } - else - { - a_BlockEntities.push_back( ChestEntity ); - } - } // for itr - AllChests[] - } - - // Load furnaces - Json::Value AllFurnaces = a_Value.get("Furnaces", Json::nullValue); - if( !AllFurnaces.empty() ) - { - for( Json::Value::iterator itr = AllFurnaces.begin(); itr != AllFurnaces.end(); ++itr ) - { - Json::Value & Furnace = *itr; - cFurnaceEntity * FurnaceEntity = new cFurnaceEntity(0,0,0, a_World); - if( !FurnaceEntity->LoadFromJson( Furnace ) ) - { - LOGERROR("ERROR READING FURNACE FROM JSON!" ); - delete FurnaceEntity; - } - else - { - a_BlockEntities.push_back( FurnaceEntity ); - } - } // for itr - AllFurnaces[] - } - - // Load signs - Json::Value AllSigns = a_Value.get("Signs", Json::nullValue); - if( !AllSigns.empty() ) - { - for( Json::Value::iterator itr = AllSigns.begin(); itr != AllSigns.end(); ++itr ) - { - Json::Value & Sign = *itr; - cSignEntity * SignEntity = new cSignEntity( E_BLOCK_SIGN_POST, 0,0,0, a_World); - if ( !SignEntity->LoadFromJson( Sign ) ) - { - LOGERROR("ERROR READING SIGN FROM JSON!" ); - delete SignEntity; - } - else - { - a_BlockEntities.push_back( SignEntity ); - } - } // for itr - AllSigns[] - } -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cWSSCompact::cPAKFile - -#define READ(Var) \ - if (f.Read(&Var, sizeof(Var)) != sizeof(Var)) \ - { \ - LOGERROR("ERROR READING %s FROM FILE %s (line %d); file offset %d", #Var, m_FileName.c_str(), __LINE__, f.Tell()); \ - return; \ - } - -cWSSCompact::cPAKFile::cPAKFile(const AString & a_FileName, int a_LayerX, int a_LayerZ) : - m_FileName(a_FileName), - m_LayerX(a_LayerX), - m_LayerZ(a_LayerZ), - m_NumDirty(0), - m_ChunkVersion( CHUNK_VERSION ), // Init with latest version - m_PakVersion( PAK_VERSION ) -{ - cFile f; - if (!f.Open(m_FileName, cFile::fmRead)) - { - return; - } - - // Read headers: - READ(m_PakVersion); - if (m_PakVersion != 1) - { - LOGERROR("File \"%s\" is in an unknown pak format (%d)", m_FileName.c_str(), m_PakVersion); - return; - } - - READ(m_ChunkVersion); - switch( m_ChunkVersion ) - { - case 1: - m_ChunkSize.Set(16, 128, 16); - break; - case 2: - case 3: - m_ChunkSize.Set(16, 256, 16); - break; - default: - LOGERROR("File \"%s\" is in an unknown chunk format (%d)", m_FileName.c_str(), m_ChunkVersion); - return; - }; - - short NumChunks = 0; - READ(NumChunks); - - // Read chunk headers: - for (int i = 0; i < NumChunks; i++) - { - sChunkHeader * Header = new sChunkHeader; - READ(*Header); - m_ChunkHeaders.push_back(Header); - } // for i - chunk headers - - // Read chunk data: - if (f.ReadRestOfFile(m_DataContents) == -1) - { - LOGERROR("Cannot read file \"%s\" contents", m_FileName.c_str()); - return; - } - - if( m_ChunkVersion == 1 ) // Convert chunks to version 2 - { - UpdateChunk1To2(); - } -#if AXIS_ORDER == AXIS_ORDER_XZY - if( m_ChunkVersion == 2 ) // Convert chunks to version 3 - { - UpdateChunk2To3(); - } -#endif -} - - - - - -cWSSCompact::cPAKFile::~cPAKFile() -{ - if (m_NumDirty > 0) - { - SynchronizeFile(); - } - for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) - { - delete *itr; - } -} - - - - - -bool cWSSCompact::cPAKFile::GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data) -{ - int ChunkX = a_Chunk.m_ChunkX; - int ChunkZ = a_Chunk.m_ChunkZ; - sChunkHeader * Header = NULL; - int Offset = 0; - for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) - { - if (((*itr)->m_ChunkX == ChunkX) && ((*itr)->m_ChunkZ == ChunkZ)) - { - Header = *itr; - break; - } - Offset += (*itr)->m_CompressedSize; - } - if ((Header == NULL) || (Offset + Header->m_CompressedSize > (int)m_DataContents.size())) - { - // Chunk not found / data invalid - return false; - } - - a_UncompressedSize = Header->m_UncompressedSize; - a_Data.assign(m_DataContents, Offset, Header->m_CompressedSize); - return true; -} - - - - - -bool cWSSCompact::cPAKFile::SaveChunk(const cChunkCoords & a_Chunk, cWorld * a_World) -{ - if (!SaveChunkToData(a_Chunk, a_World)) - { - return false; - } - if (m_NumDirty > MAX_DIRTY_CHUNKS) - { - SynchronizeFile(); - } - return true; -} - - - - - -void cWSSCompact::cPAKFile::UpdateChunk1To2() -{ - int Offset = 0; - AString NewDataContents; - int ChunksConverted = 0; - for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) - { - sChunkHeader * Header = *itr; - - if( ChunksConverted % 32 == 0 ) - { - LOGINFO("Updating \"%s\" version 1 to version 2: %d %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size() ); - } - ChunksConverted++; - - AString Data; - int UncompressedSize = Header->m_UncompressedSize; - Data.assign(m_DataContents, Offset, Header->m_CompressedSize); - Offset += Header->m_CompressedSize; - - // Crude data integrity check: - int ExpectedSize = (16*128*16)*2 + (16*128*16)/2; // For version 1 - if (UncompressedSize < ExpectedSize) - { - LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing", - Header->m_ChunkX, Header->m_ChunkZ, - UncompressedSize, ExpectedSize - ); - Offset += Header->m_CompressedSize; - continue; - } - - // Decompress the data: - AString UncompressedData; - { - int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, UncompressedSize); - if (errorcode != Z_OK) - { - LOGERROR("Error %d decompressing data for chunk [%d, %d]", - errorcode, - Header->m_ChunkX, Header->m_ChunkZ - ); - Offset += Header->m_CompressedSize; - continue; - } - } - - if (UncompressedSize != (int)UncompressedData.size()) - { - LOGWARNING("Uncompressed data size differs (exp %d bytes, got %d) for chunk [%d, %d]", - UncompressedSize, UncompressedData.size(), - Header->m_ChunkX, Header->m_ChunkZ - ); - Offset += Header->m_CompressedSize; - continue; - } - - - // Old version is 128 blocks high with YZX axis order - char ConvertedData[cChunkDef::BlockDataSize]; - int Index = 0; - unsigned int InChunkOffset = 0; - for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) - { - for( int y = 0; y < 128; ++y ) - { - ConvertedData[Index++] = UncompressedData[y + z * 128 + x * 128 * 16 + InChunkOffset]; - } - // Add 128 empty blocks after an old y column - memset(ConvertedData + Index, E_BLOCK_AIR, 128); - Index += 128; - } - InChunkOffset += (16 * 128 * 16); - for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Metadata - { - for( int y = 0; y < 64; ++y ) - { - ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset]; - } - memset(ConvertedData + Index, 0, 64); - Index += 64; - } - InChunkOffset += (16 * 128 * 16) / 2; - for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Block light - { - for( int y = 0; y < 64; ++y ) - { - ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset]; - } - memset(ConvertedData + Index, 0, 64); - Index += 64; - } - InChunkOffset += (16*128*16)/2; - for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Sky light - { - for( int y = 0; y < 64; ++y ) - { - ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset]; - } - memset(ConvertedData + Index, 0, 64); - Index += 64; - } - InChunkOffset += (16 * 128 * 16) / 2; - - AString Converted(ConvertedData, ARRAYCOUNT(ConvertedData)); - - // Add JSON data afterwards - if (UncompressedData.size() > InChunkOffset) - { - Converted.append( UncompressedData.begin() + InChunkOffset, UncompressedData.end() ); - } - - // Re-compress data - AString CompressedData; - { - int errorcode = CompressString(Converted.data(), Converted.size(), CompressedData); - if (errorcode != Z_OK) - { - LOGERROR("Error %d compressing data for chunk [%d, %d]", - errorcode, - Header->m_ChunkX, Header->m_ChunkZ - ); - continue; - } - } - - // Save into file's cache - Header->m_UncompressedSize = Converted.size(); - Header->m_CompressedSize = CompressedData.size(); - NewDataContents.append( CompressedData ); - } - - // Done converting - m_DataContents = NewDataContents; - m_ChunkVersion = 2; - SynchronizeFile(); - - LOGINFO("Updated \"%s\" version 1 to version 2", m_FileName.c_str() ); -} - - - - - -void cWSSCompact::cPAKFile::UpdateChunk2To3() -{ - int Offset = 0; - AString NewDataContents; - int ChunksConverted = 0; - for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) - { - sChunkHeader * Header = *itr; - - if( ChunksConverted % 32 == 0 ) - { - LOGINFO("Updating \"%s\" version 2 to version 3: %d %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size() ); - } - ChunksConverted++; - - AString Data; - int UncompressedSize = Header->m_UncompressedSize; - Data.assign(m_DataContents, Offset, Header->m_CompressedSize); - Offset += Header->m_CompressedSize; - - // Crude data integrity check: - const int ExpectedSize = (16*256*16)*2 + (16*256*16)/2; // For version 2 - if (UncompressedSize < ExpectedSize) - { - LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing", - Header->m_ChunkX, Header->m_ChunkZ, - UncompressedSize, ExpectedSize - ); - Offset += Header->m_CompressedSize; - continue; - } - - // Decompress the data: - AString UncompressedData; - { - int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, UncompressedSize); - if (errorcode != Z_OK) - { - LOGERROR("Error %d decompressing data for chunk [%d, %d]", - errorcode, - Header->m_ChunkX, Header->m_ChunkZ - ); - Offset += Header->m_CompressedSize; - continue; - } - } - - if (UncompressedSize != (int)UncompressedData.size()) - { - LOGWARNING("Uncompressed data size differs (exp %d bytes, got %d) for chunk [%d, %d]", - UncompressedSize, UncompressedData.size(), - Header->m_ChunkX, Header->m_ChunkZ - ); - Offset += Header->m_CompressedSize; - continue; - } - - char ConvertedData[ExpectedSize]; - memset(ConvertedData, 0, ExpectedSize); - - // Cannot use cChunk::MakeIndex because it might change again????????? - // For compatibility, use what we know is current - #define MAKE_2_INDEX( x, y, z ) ( y + (z * 256) + (x * 256 * 16) ) - #define MAKE_3_INDEX( x, y, z ) ( x + (z * 16) + (y * 16 * 16) ) - - unsigned int InChunkOffset = 0; - for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y ) // YZX Loop order is important, in 1.1 Y was first then Z then X - { - ConvertedData[ MAKE_3_INDEX(x, y, z) ] = UncompressedData[InChunkOffset]; - ++InChunkOffset; - } // for y, z, x - - - unsigned int index2 = 0; - for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y ) - { - ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4) ) & 0x0f ) << ((x&1)*4); - ++index2; - } - InChunkOffset += index2 / 2; - index2 = 0; - - for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y ) - { - ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4) ) & 0x0f ) << ((x&1)*4); - ++index2; - } - InChunkOffset += index2 / 2; - index2 = 0; - - for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y ) - { - ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4) ) & 0x0f ) << ((x&1)*4); - ++index2; - } - InChunkOffset += index2 / 2; - index2 = 0; - - AString Converted(ConvertedData, ExpectedSize); - - // Add JSON data afterwards - if (UncompressedData.size() > InChunkOffset) - { - Converted.append( UncompressedData.begin() + InChunkOffset, UncompressedData.end() ); - } - - // Re-compress data - AString CompressedData; - { - int errorcode = CompressString(Converted.data(), Converted.size(), CompressedData); - if (errorcode != Z_OK) - { - LOGERROR("Error %d compressing data for chunk [%d, %d]", - errorcode, - Header->m_ChunkX, Header->m_ChunkZ - ); - continue; - } - } - - // Save into file's cache - Header->m_UncompressedSize = Converted.size(); - Header->m_CompressedSize = CompressedData.size(); - NewDataContents.append( CompressedData ); - } - - // Done converting - m_DataContents = NewDataContents; - m_ChunkVersion = 3; - SynchronizeFile(); - - LOGINFO("Updated \"%s\" version 2 to version 3", m_FileName.c_str() ); -} - - - - - -bool cWSSCompact::LoadChunkFromData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, const AString & a_Data, cWorld * a_World) -{ - // Crude data integrity check: - if (a_UncompressedSize < cChunkDef::BlockDataSize) - { - LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing", - a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, - a_UncompressedSize, cChunkDef::BlockDataSize - ); - EraseChunkData(a_Chunk); - return false; - } - - // Decompress the data: - AString UncompressedData; - int errorcode = UncompressString(a_Data.data(), a_Data.size(), UncompressedData, a_UncompressedSize); - if (errorcode != Z_OK) - { - LOGERROR("Error %d decompressing data for chunk [%d, %d]", - errorcode, - a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ - ); - return false; - } - - if (a_UncompressedSize != (int)UncompressedData.size()) - { - LOGWARNING("Uncompressed data size differs (exp %d bytes, got %d) for chunk [%d, %d]", - a_UncompressedSize, UncompressedData.size(), - a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ - ); - return false; - } - - cEntityList Entities; - cBlockEntityList BlockEntities; - bool IsLightValid = false; - - if (a_UncompressedSize > cChunkDef::BlockDataSize) - { - Json::Value root; // will contain the root value after parsing. - Json::Reader reader; - if ( !reader.parse( UncompressedData.data() + cChunkDef::BlockDataSize, root, false ) ) - { - LOGERROR("Failed to parse trailing JSON in chunk [%d, %d]!", - a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ - ); - } - else - { - LoadEntitiesFromJson(root, Entities, BlockEntities, a_World); - IsLightValid = root.get("IsLightValid", false).asBool(); - } - } - - BLOCKTYPE * BlockData = (BLOCKTYPE *)UncompressedData.data(); - NIBBLETYPE * MetaData = (NIBBLETYPE *)(BlockData + cChunkDef::MetaOffset); - NIBBLETYPE * BlockLight = (NIBBLETYPE *)(BlockData + cChunkDef::LightOffset); - NIBBLETYPE * SkyLight = (NIBBLETYPE *)(BlockData + cChunkDef::SkyLightOffset); - - a_World->SetChunkData( - a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, - BlockData, MetaData, - IsLightValid ? BlockLight : NULL, - IsLightValid ? SkyLight : NULL, - NULL, NULL, - Entities, BlockEntities, - false - ); - - return true; -} - - - - - -bool cWSSCompact::cPAKFile::EraseChunkData(const cChunkCoords & a_Chunk) -{ - int ChunkX = a_Chunk.m_ChunkX; - int ChunkZ = a_Chunk.m_ChunkZ; - int Offset = 0; - for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) - { - if (((*itr)->m_ChunkX == ChunkX) && ((*itr)->m_ChunkZ == ChunkZ)) - { - m_DataContents.erase(Offset, (*itr)->m_CompressedSize); - delete *itr; - itr = m_ChunkHeaders.erase(itr); - return true; - } - Offset += (*itr)->m_CompressedSize; - } - - return false; -} - - - - - -bool cWSSCompact::cPAKFile::SaveChunkToData(const cChunkCoords & a_Chunk, cWorld * a_World) -{ - // Serialize the chunk: - cJsonChunkSerializer Serializer; - if (!a_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, Serializer)) - { - // Chunk not valid - LOG("cWSSCompact: Trying to save chunk [%d, %d, %d] that has no data, ignoring request.", a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ); - return false; - } - - AString Data; - Data.assign((const char *)Serializer.GetBlockData(), cChunkDef::BlockDataSize); - if (Serializer.HasJsonData()) - { - AString JsonData; - Json::StyledWriter writer; - JsonData = writer.write(Serializer.GetRoot()); - Data.append(JsonData); - } - - // Compress the data: - AString CompressedData; - int errorcode = CompressString(Data.data(), Data.size(), CompressedData); - if ( errorcode != Z_OK ) - { - LOGERROR("Error %i compressing data for chunk [%d, %d, %d]", errorcode, a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ); - return false; - } - - // Erase any existing data for the chunk: - EraseChunkData(a_Chunk); - - // Save the header: - sChunkHeader * Header = new sChunkHeader; - if (Header == NULL) - { - LOGWARNING("Cannot create a new chunk header to save chunk [%d, %d, %d]", a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ); - return false; - } - Header->m_CompressedSize = (int)CompressedData.size(); - Header->m_ChunkX = a_Chunk.m_ChunkX; - Header->m_ChunkZ = a_Chunk.m_ChunkZ; - Header->m_UncompressedSize = (int)Data.size(); - m_ChunkHeaders.push_back(Header); - - m_DataContents.append(CompressedData.data(), CompressedData.size()); - - m_NumDirty++; - return true; -} - - - - - -#define WRITE(Var) \ - if (f.Write(&Var, sizeof(Var)) != sizeof(Var)) \ - { \ - LOGERROR("cWSSCompact: ERROR writing %s to file \"%s\" (line %d); file offset %d", #Var, m_FileName.c_str(), __LINE__, f.Tell()); \ - return; \ - } - -void cWSSCompact::cPAKFile::SynchronizeFile(void) -{ - cFile f; - if (!f.Open(m_FileName, cFile::fmWrite)) - { - LOGERROR("Cannot open PAK file \"%s\" for writing", m_FileName.c_str()); - return; - } - - WRITE(m_PakVersion); - WRITE(m_ChunkVersion); - short NumChunks = (short)m_ChunkHeaders.size(); - WRITE(NumChunks); - for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) - { - WRITE(**itr); - } - if (f.Write(m_DataContents.data(), m_DataContents.size()) != (int)m_DataContents.size()) - { - LOGERROR("cWSSCompact: ERROR writing chunk contents to file \"%s\" (line %d); file offset %d", m_FileName.c_str(), __LINE__, f.Tell()); - return; - } - m_NumDirty = 0; -} - - - - + +// WSSCompact.cpp + +// Interfaces to the cWSSCompact class representing the "compact" storage schema (PAK-files) + +#include "Globals.h" +#include "WSSCompact.h" +#include "cWorld.h" +#include "zlib.h" +#include +#include "StringCompression.h" +#include "cChestEntity.h" +#include "cSignEntity.h" +#include "cFurnaceEntity.h" +#include "BlockID.h" + + + + + +#pragma pack(push, 1) +/// The chunk header, as stored in the file: +struct cWSSCompact::sChunkHeader +{ + int m_ChunkX; + int m_ChunkZ; + int m_CompressedSize; + int m_UncompressedSize; +} ; +#pragma pack(pop) + + + + + +/// The maximum number of PAK files that are cached +const int MAX_PAK_FILES = 16; + +/// The maximum number of unsaved chunks before the cPAKFile saves them to disk +const int MAX_DIRTY_CHUNKS = 16; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cJsonChunkSerializer: + +cJsonChunkSerializer::cJsonChunkSerializer(void) : + m_HasJsonData(false) +{ +} + + + + + +void cJsonChunkSerializer::Entity(cEntity * a_Entity) +{ + // TODO: a_Entity->SaveToJson(m_Root); +} + + + + + +void cJsonChunkSerializer::BlockEntity(cBlockEntity * a_BlockEntity) +{ + const char * SaveInto = NULL; + switch (a_BlockEntity->GetBlockType()) + { + case E_BLOCK_CHEST: SaveInto = "Chests"; break; + case E_BLOCK_FURNACE: SaveInto = "Furnaces"; break; + case E_BLOCK_SIGN_POST: SaveInto = "Signs"; break; + case E_BLOCK_WALLSIGN: SaveInto = "Signs"; break; + + default: + { + ASSERT(!"Unhandled blocktype in BlockEntities list while saving to JSON"); + break; + } + } // switch (BlockEntity->GetBlockType()) + if (SaveInto == NULL) + { + return; + } + + Json::Value val; + a_BlockEntity->SaveToJson(val); + m_Root[SaveInto].append(val); + m_HasJsonData = true; +} + + + + + +bool cJsonChunkSerializer::LightIsValid(bool a_IsLightValid) +{ + if (!a_IsLightValid) + { + return false; + } + m_Root["IsLightValid"] = true; + m_HasJsonData = true; + return true; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cWSSCompact: + +cWSSCompact::~cWSSCompact() +{ + for (cPAKFiles::iterator itr = m_PAKFiles.begin(); itr != m_PAKFiles.end(); ++itr) + { + delete *itr; + } +} + + + + + +bool cWSSCompact::LoadChunk(const cChunkCoords & a_Chunk) +{ + AString ChunkData; + int UncompressedSize = 0; + if (!GetChunkData(a_Chunk, UncompressedSize, ChunkData)) + { + // The reason for failure is already printed in GetChunkData() + return false; + } + + return LoadChunkFromData(a_Chunk, UncompressedSize, ChunkData, m_World); +} + + + + + +bool cWSSCompact::SaveChunk(const cChunkCoords & a_Chunk) +{ + cCSLock Lock(m_CS); + + cPAKFile * f = LoadPAKFile(a_Chunk); + if (f == NULL) + { + // For some reason we couldn't locate the file + LOG("Cannot locate a proper PAK file for chunk [%d, %d]", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); + return false; + } + return f->SaveChunk(a_Chunk, m_World); +} + + + + + +cWSSCompact::cPAKFile * cWSSCompact::LoadPAKFile(const cChunkCoords & a_Chunk) +{ + // ASSUMES that m_CS has been locked + + // We need to retain this weird conversion code, because some edge chunks are in the wrong PAK file + const int LayerX = (int)(floorf((float)a_Chunk.m_ChunkX / 32.0f)); + const int LayerZ = (int)(floorf((float)a_Chunk.m_ChunkZ / 32.0f)); + + // Is it already cached? + for (cPAKFiles::iterator itr = m_PAKFiles.begin(); itr != m_PAKFiles.end(); ++itr) + { + if (((*itr) != NULL) && ((*itr)->GetLayerX() == LayerX) && ((*itr)->GetLayerZ() == LayerZ)) + { + // Move the file to front and return it: + cPAKFile * f = *itr; + if (itr != m_PAKFiles.begin()) + { + m_PAKFiles.erase(itr); + m_PAKFiles.push_front(f); + } + return f; + } + } + + // Load it anew: + AString FileName; + Printf(FileName, "%s/X%i_Z%i.pak", m_World->GetName().c_str(), LayerX, LayerZ ); + cPAKFile * f = new cPAKFile(FileName, LayerX, LayerZ); + if (f == NULL) + { + return NULL; + } + m_PAKFiles.push_front(f); + + // If there are too many PAK files cached, delete the last one used: + if (m_PAKFiles.size() > MAX_PAK_FILES) + { + delete m_PAKFiles.back(); + m_PAKFiles.pop_back(); + } + return f; +} + + + + + +bool cWSSCompact::GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data) +{ + cCSLock Lock(m_CS); + cPAKFile * f = LoadPAKFile(a_Chunk); + if (f == NULL) + { + return false; + } + return f->GetChunkData(a_Chunk, a_UncompressedSize, a_Data); +} + + + + + +/* +// TODO: Rewrite saving to use the same principles as loading +bool cWSSCompact::SetChunkData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data) +{ + cCSLock Lock(m_CS); + cPAKFile * f = LoadPAKFile(a_Chunk); + if (f == NULL) + { + return false; + } + return f->SetChunkData(a_Chunk, a_UncompressedSize, a_Data); +} +*/ + + + + + +bool cWSSCompact::EraseChunkData(const cChunkCoords & a_Chunk) +{ + cCSLock Lock(m_CS); + cPAKFile * f = LoadPAKFile(a_Chunk); + if (f == NULL) + { + return false; + } + return f->EraseChunkData(a_Chunk); +} + + + + + +void cWSSCompact::LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities, cWorld * a_World) +{ + // Load chests + Json::Value AllChests = a_Value.get("Chests", Json::nullValue); + if (!AllChests.empty()) + { + for (Json::Value::iterator itr = AllChests.begin(); itr != AllChests.end(); ++itr ) + { + Json::Value & Chest = *itr; + cChestEntity * ChestEntity = new cChestEntity(0,0,0, a_World); + if (!ChestEntity->LoadFromJson( Chest ) ) + { + LOGERROR("ERROR READING CHEST FROM JSON!" ); + delete ChestEntity; + } + else + { + a_BlockEntities.push_back( ChestEntity ); + } + } // for itr - AllChests[] + } + + // Load furnaces + Json::Value AllFurnaces = a_Value.get("Furnaces", Json::nullValue); + if( !AllFurnaces.empty() ) + { + for( Json::Value::iterator itr = AllFurnaces.begin(); itr != AllFurnaces.end(); ++itr ) + { + Json::Value & Furnace = *itr; + cFurnaceEntity * FurnaceEntity = new cFurnaceEntity(0,0,0, a_World); + if( !FurnaceEntity->LoadFromJson( Furnace ) ) + { + LOGERROR("ERROR READING FURNACE FROM JSON!" ); + delete FurnaceEntity; + } + else + { + a_BlockEntities.push_back( FurnaceEntity ); + } + } // for itr - AllFurnaces[] + } + + // Load signs + Json::Value AllSigns = a_Value.get("Signs", Json::nullValue); + if( !AllSigns.empty() ) + { + for( Json::Value::iterator itr = AllSigns.begin(); itr != AllSigns.end(); ++itr ) + { + Json::Value & Sign = *itr; + cSignEntity * SignEntity = new cSignEntity( E_BLOCK_SIGN_POST, 0,0,0, a_World); + if ( !SignEntity->LoadFromJson( Sign ) ) + { + LOGERROR("ERROR READING SIGN FROM JSON!" ); + delete SignEntity; + } + else + { + a_BlockEntities.push_back( SignEntity ); + } + } // for itr - AllSigns[] + } +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cWSSCompact::cPAKFile + +#define READ(Var) \ + if (f.Read(&Var, sizeof(Var)) != sizeof(Var)) \ + { \ + LOGERROR("ERROR READING %s FROM FILE %s (line %d); file offset %d", #Var, m_FileName.c_str(), __LINE__, f.Tell()); \ + return; \ + } + +cWSSCompact::cPAKFile::cPAKFile(const AString & a_FileName, int a_LayerX, int a_LayerZ) : + m_FileName(a_FileName), + m_LayerX(a_LayerX), + m_LayerZ(a_LayerZ), + m_NumDirty(0), + m_ChunkVersion( CHUNK_VERSION ), // Init with latest version + m_PakVersion( PAK_VERSION ) +{ + cFile f; + if (!f.Open(m_FileName, cFile::fmRead)) + { + return; + } + + // Read headers: + READ(m_PakVersion); + if (m_PakVersion != 1) + { + LOGERROR("File \"%s\" is in an unknown pak format (%d)", m_FileName.c_str(), m_PakVersion); + return; + } + + READ(m_ChunkVersion); + switch( m_ChunkVersion ) + { + case 1: + m_ChunkSize.Set(16, 128, 16); + break; + case 2: + case 3: + m_ChunkSize.Set(16, 256, 16); + break; + default: + LOGERROR("File \"%s\" is in an unknown chunk format (%d)", m_FileName.c_str(), m_ChunkVersion); + return; + }; + + short NumChunks = 0; + READ(NumChunks); + + // Read chunk headers: + for (int i = 0; i < NumChunks; i++) + { + sChunkHeader * Header = new sChunkHeader; + READ(*Header); + m_ChunkHeaders.push_back(Header); + } // for i - chunk headers + + // Read chunk data: + if (f.ReadRestOfFile(m_DataContents) == -1) + { + LOGERROR("Cannot read file \"%s\" contents", m_FileName.c_str()); + return; + } + + if( m_ChunkVersion == 1 ) // Convert chunks to version 2 + { + UpdateChunk1To2(); + } +#if AXIS_ORDER == AXIS_ORDER_XZY + if( m_ChunkVersion == 2 ) // Convert chunks to version 3 + { + UpdateChunk2To3(); + } +#endif +} + + + + + +cWSSCompact::cPAKFile::~cPAKFile() +{ + if (m_NumDirty > 0) + { + SynchronizeFile(); + } + for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) + { + delete *itr; + } +} + + + + + +bool cWSSCompact::cPAKFile::GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data) +{ + int ChunkX = a_Chunk.m_ChunkX; + int ChunkZ = a_Chunk.m_ChunkZ; + sChunkHeader * Header = NULL; + int Offset = 0; + for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) + { + if (((*itr)->m_ChunkX == ChunkX) && ((*itr)->m_ChunkZ == ChunkZ)) + { + Header = *itr; + break; + } + Offset += (*itr)->m_CompressedSize; + } + if ((Header == NULL) || (Offset + Header->m_CompressedSize > (int)m_DataContents.size())) + { + // Chunk not found / data invalid + return false; + } + + a_UncompressedSize = Header->m_UncompressedSize; + a_Data.assign(m_DataContents, Offset, Header->m_CompressedSize); + return true; +} + + + + + +bool cWSSCompact::cPAKFile::SaveChunk(const cChunkCoords & a_Chunk, cWorld * a_World) +{ + if (!SaveChunkToData(a_Chunk, a_World)) + { + return false; + } + if (m_NumDirty > MAX_DIRTY_CHUNKS) + { + SynchronizeFile(); + } + return true; +} + + + + + +void cWSSCompact::cPAKFile::UpdateChunk1To2() +{ + int Offset = 0; + AString NewDataContents; + int ChunksConverted = 0; + for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) + { + sChunkHeader * Header = *itr; + + if( ChunksConverted % 32 == 0 ) + { + LOGINFO("Updating \"%s\" version 1 to version 2: %d %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size() ); + } + ChunksConverted++; + + AString Data; + int UncompressedSize = Header->m_UncompressedSize; + Data.assign(m_DataContents, Offset, Header->m_CompressedSize); + Offset += Header->m_CompressedSize; + + // Crude data integrity check: + int ExpectedSize = (16*128*16)*2 + (16*128*16)/2; // For version 1 + if (UncompressedSize < ExpectedSize) + { + LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing", + Header->m_ChunkX, Header->m_ChunkZ, + UncompressedSize, ExpectedSize + ); + Offset += Header->m_CompressedSize; + continue; + } + + // Decompress the data: + AString UncompressedData; + { + int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, UncompressedSize); + if (errorcode != Z_OK) + { + LOGERROR("Error %d decompressing data for chunk [%d, %d]", + errorcode, + Header->m_ChunkX, Header->m_ChunkZ + ); + Offset += Header->m_CompressedSize; + continue; + } + } + + if (UncompressedSize != (int)UncompressedData.size()) + { + LOGWARNING("Uncompressed data size differs (exp %d bytes, got %d) for chunk [%d, %d]", + UncompressedSize, UncompressedData.size(), + Header->m_ChunkX, Header->m_ChunkZ + ); + Offset += Header->m_CompressedSize; + continue; + } + + + // Old version is 128 blocks high with YZX axis order + char ConvertedData[cChunkDef::BlockDataSize]; + int Index = 0; + unsigned int InChunkOffset = 0; + for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) + { + for( int y = 0; y < 128; ++y ) + { + ConvertedData[Index++] = UncompressedData[y + z * 128 + x * 128 * 16 + InChunkOffset]; + } + // Add 128 empty blocks after an old y column + memset(ConvertedData + Index, E_BLOCK_AIR, 128); + Index += 128; + } + InChunkOffset += (16 * 128 * 16); + for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Metadata + { + for( int y = 0; y < 64; ++y ) + { + ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset]; + } + memset(ConvertedData + Index, 0, 64); + Index += 64; + } + InChunkOffset += (16 * 128 * 16) / 2; + for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Block light + { + for( int y = 0; y < 64; ++y ) + { + ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset]; + } + memset(ConvertedData + Index, 0, 64); + Index += 64; + } + InChunkOffset += (16*128*16)/2; + for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Sky light + { + for( int y = 0; y < 64; ++y ) + { + ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset]; + } + memset(ConvertedData + Index, 0, 64); + Index += 64; + } + InChunkOffset += (16 * 128 * 16) / 2; + + AString Converted(ConvertedData, ARRAYCOUNT(ConvertedData)); + + // Add JSON data afterwards + if (UncompressedData.size() > InChunkOffset) + { + Converted.append( UncompressedData.begin() + InChunkOffset, UncompressedData.end() ); + } + + // Re-compress data + AString CompressedData; + { + int errorcode = CompressString(Converted.data(), Converted.size(), CompressedData); + if (errorcode != Z_OK) + { + LOGERROR("Error %d compressing data for chunk [%d, %d]", + errorcode, + Header->m_ChunkX, Header->m_ChunkZ + ); + continue; + } + } + + // Save into file's cache + Header->m_UncompressedSize = Converted.size(); + Header->m_CompressedSize = CompressedData.size(); + NewDataContents.append( CompressedData ); + } + + // Done converting + m_DataContents = NewDataContents; + m_ChunkVersion = 2; + SynchronizeFile(); + + LOGINFO("Updated \"%s\" version 1 to version 2", m_FileName.c_str() ); +} + + + + + +void cWSSCompact::cPAKFile::UpdateChunk2To3() +{ + int Offset = 0; + AString NewDataContents; + int ChunksConverted = 0; + for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) + { + sChunkHeader * Header = *itr; + + if( ChunksConverted % 32 == 0 ) + { + LOGINFO("Updating \"%s\" version 2 to version 3: %d %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size() ); + } + ChunksConverted++; + + AString Data; + int UncompressedSize = Header->m_UncompressedSize; + Data.assign(m_DataContents, Offset, Header->m_CompressedSize); + Offset += Header->m_CompressedSize; + + // Crude data integrity check: + const int ExpectedSize = (16*256*16)*2 + (16*256*16)/2; // For version 2 + if (UncompressedSize < ExpectedSize) + { + LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing", + Header->m_ChunkX, Header->m_ChunkZ, + UncompressedSize, ExpectedSize + ); + Offset += Header->m_CompressedSize; + continue; + } + + // Decompress the data: + AString UncompressedData; + { + int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, UncompressedSize); + if (errorcode != Z_OK) + { + LOGERROR("Error %d decompressing data for chunk [%d, %d]", + errorcode, + Header->m_ChunkX, Header->m_ChunkZ + ); + Offset += Header->m_CompressedSize; + continue; + } + } + + if (UncompressedSize != (int)UncompressedData.size()) + { + LOGWARNING("Uncompressed data size differs (exp %d bytes, got %d) for chunk [%d, %d]", + UncompressedSize, UncompressedData.size(), + Header->m_ChunkX, Header->m_ChunkZ + ); + Offset += Header->m_CompressedSize; + continue; + } + + char ConvertedData[ExpectedSize]; + memset(ConvertedData, 0, ExpectedSize); + + // Cannot use cChunk::MakeIndex because it might change again????????? + // For compatibility, use what we know is current + #define MAKE_2_INDEX( x, y, z ) ( y + (z * 256) + (x * 256 * 16) ) + #define MAKE_3_INDEX( x, y, z ) ( x + (z * 16) + (y * 16 * 16) ) + + unsigned int InChunkOffset = 0; + for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y ) // YZX Loop order is important, in 1.1 Y was first then Z then X + { + ConvertedData[ MAKE_3_INDEX(x, y, z) ] = UncompressedData[InChunkOffset]; + ++InChunkOffset; + } // for y, z, x + + + unsigned int index2 = 0; + for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y ) + { + ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4) ) & 0x0f ) << ((x&1)*4); + ++index2; + } + InChunkOffset += index2 / 2; + index2 = 0; + + for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y ) + { + ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4) ) & 0x0f ) << ((x&1)*4); + ++index2; + } + InChunkOffset += index2 / 2; + index2 = 0; + + for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y ) + { + ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4) ) & 0x0f ) << ((x&1)*4); + ++index2; + } + InChunkOffset += index2 / 2; + index2 = 0; + + AString Converted(ConvertedData, ExpectedSize); + + // Add JSON data afterwards + if (UncompressedData.size() > InChunkOffset) + { + Converted.append( UncompressedData.begin() + InChunkOffset, UncompressedData.end() ); + } + + // Re-compress data + AString CompressedData; + { + int errorcode = CompressString(Converted.data(), Converted.size(), CompressedData); + if (errorcode != Z_OK) + { + LOGERROR("Error %d compressing data for chunk [%d, %d]", + errorcode, + Header->m_ChunkX, Header->m_ChunkZ + ); + continue; + } + } + + // Save into file's cache + Header->m_UncompressedSize = Converted.size(); + Header->m_CompressedSize = CompressedData.size(); + NewDataContents.append( CompressedData ); + } + + // Done converting + m_DataContents = NewDataContents; + m_ChunkVersion = 3; + SynchronizeFile(); + + LOGINFO("Updated \"%s\" version 2 to version 3", m_FileName.c_str() ); +} + + + + + +bool cWSSCompact::LoadChunkFromData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, const AString & a_Data, cWorld * a_World) +{ + // Crude data integrity check: + if (a_UncompressedSize < cChunkDef::BlockDataSize) + { + LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing", + a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, + a_UncompressedSize, cChunkDef::BlockDataSize + ); + EraseChunkData(a_Chunk); + return false; + } + + // Decompress the data: + AString UncompressedData; + int errorcode = UncompressString(a_Data.data(), a_Data.size(), UncompressedData, a_UncompressedSize); + if (errorcode != Z_OK) + { + LOGERROR("Error %d decompressing data for chunk [%d, %d]", + errorcode, + a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ + ); + return false; + } + + if (a_UncompressedSize != (int)UncompressedData.size()) + { + LOGWARNING("Uncompressed data size differs (exp %d bytes, got %d) for chunk [%d, %d]", + a_UncompressedSize, UncompressedData.size(), + a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ + ); + return false; + } + + cEntityList Entities; + cBlockEntityList BlockEntities; + bool IsLightValid = false; + + if (a_UncompressedSize > cChunkDef::BlockDataSize) + { + Json::Value root; // will contain the root value after parsing. + Json::Reader reader; + if ( !reader.parse( UncompressedData.data() + cChunkDef::BlockDataSize, root, false ) ) + { + LOGERROR("Failed to parse trailing JSON in chunk [%d, %d]!", + a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ + ); + } + else + { + LoadEntitiesFromJson(root, Entities, BlockEntities, a_World); + IsLightValid = root.get("IsLightValid", false).asBool(); + } + } + + BLOCKTYPE * BlockData = (BLOCKTYPE *)UncompressedData.data(); + NIBBLETYPE * MetaData = (NIBBLETYPE *)(BlockData + cChunkDef::MetaOffset); + NIBBLETYPE * BlockLight = (NIBBLETYPE *)(BlockData + cChunkDef::LightOffset); + NIBBLETYPE * SkyLight = (NIBBLETYPE *)(BlockData + cChunkDef::SkyLightOffset); + + a_World->SetChunkData( + a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, + BlockData, MetaData, + IsLightValid ? BlockLight : NULL, + IsLightValid ? SkyLight : NULL, + NULL, NULL, + Entities, BlockEntities, + false + ); + + return true; +} + + + + + +bool cWSSCompact::cPAKFile::EraseChunkData(const cChunkCoords & a_Chunk) +{ + int ChunkX = a_Chunk.m_ChunkX; + int ChunkZ = a_Chunk.m_ChunkZ; + int Offset = 0; + for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) + { + if (((*itr)->m_ChunkX == ChunkX) && ((*itr)->m_ChunkZ == ChunkZ)) + { + m_DataContents.erase(Offset, (*itr)->m_CompressedSize); + delete *itr; + itr = m_ChunkHeaders.erase(itr); + return true; + } + Offset += (*itr)->m_CompressedSize; + } + + return false; +} + + + + + +bool cWSSCompact::cPAKFile::SaveChunkToData(const cChunkCoords & a_Chunk, cWorld * a_World) +{ + // Serialize the chunk: + cJsonChunkSerializer Serializer; + if (!a_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, Serializer)) + { + // Chunk not valid + LOG("cWSSCompact: Trying to save chunk [%d, %d, %d] that has no data, ignoring request.", a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ); + return false; + } + + AString Data; + Data.assign((const char *)Serializer.GetBlockData(), cChunkDef::BlockDataSize); + if (Serializer.HasJsonData()) + { + AString JsonData; + Json::StyledWriter writer; + JsonData = writer.write(Serializer.GetRoot()); + Data.append(JsonData); + } + + // Compress the data: + AString CompressedData; + int errorcode = CompressString(Data.data(), Data.size(), CompressedData); + if ( errorcode != Z_OK ) + { + LOGERROR("Error %i compressing data for chunk [%d, %d, %d]", errorcode, a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ); + return false; + } + + // Erase any existing data for the chunk: + EraseChunkData(a_Chunk); + + // Save the header: + sChunkHeader * Header = new sChunkHeader; + if (Header == NULL) + { + LOGWARNING("Cannot create a new chunk header to save chunk [%d, %d, %d]", a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ); + return false; + } + Header->m_CompressedSize = (int)CompressedData.size(); + Header->m_ChunkX = a_Chunk.m_ChunkX; + Header->m_ChunkZ = a_Chunk.m_ChunkZ; + Header->m_UncompressedSize = (int)Data.size(); + m_ChunkHeaders.push_back(Header); + + m_DataContents.append(CompressedData.data(), CompressedData.size()); + + m_NumDirty++; + return true; +} + + + + + +#define WRITE(Var) \ + if (f.Write(&Var, sizeof(Var)) != sizeof(Var)) \ + { \ + LOGERROR("cWSSCompact: ERROR writing %s to file \"%s\" (line %d); file offset %d", #Var, m_FileName.c_str(), __LINE__, f.Tell()); \ + return; \ + } + +void cWSSCompact::cPAKFile::SynchronizeFile(void) +{ + cFile f; + if (!f.Open(m_FileName, cFile::fmWrite)) + { + LOGERROR("Cannot open PAK file \"%s\" for writing", m_FileName.c_str()); + return; + } + + WRITE(m_PakVersion); + WRITE(m_ChunkVersion); + short NumChunks = (short)m_ChunkHeaders.size(); + WRITE(NumChunks); + for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) + { + WRITE(**itr); + } + if (f.Write(m_DataContents.data(), m_DataContents.size()) != (int)m_DataContents.size()) + { + LOGERROR("cWSSCompact: ERROR writing chunk contents to file \"%s\" (line %d); file offset %d", m_FileName.c_str(), __LINE__, f.Tell()); + return; + } + m_NumDirty = 0; +} + + + + diff --git a/source/WSSCompact.h b/source/WSSCompact.h index 512cb7e5b..192d0f4b8 100644 --- a/source/WSSCompact.h +++ b/source/WSSCompact.h @@ -1,144 +1,144 @@ - -// WSSCompact.h - -// Interfaces to the cWSSCompact class representing the "Compact" storage schema (PAK-files) - - - - - -#pragma once -#ifndef WSSCOMPACT_H_INCLUDED -#define WSSCOMPACT_H_INCLUDED - -#include "WorldStorage.h" -#include "Vector3i.h" - - - - - -/// Helper class for serializing a chunk into Json -class cJsonChunkSerializer : - public cChunkDataCollector -{ -public: - - cJsonChunkSerializer(void); - - Json::Value & GetRoot (void) {return m_Root; } - BLOCKTYPE * GetBlockData(void) {return m_BlockData; } - bool HasJsonData (void) const {return m_HasJsonData; } - -protected: - - // NOTE: block data is serialized into inherited cChunkDataCollector's m_BlockData[] array - - // Entities and BlockEntities are serialized to Json - Json::Value m_Root; - bool m_HasJsonData; - - // cChunkDataCollector overrides: - virtual void Entity (cEntity * a_Entity) override; - virtual void BlockEntity (cBlockEntity * a_Entity) override; - virtual bool LightIsValid (bool a_IsLightValid) override; -} ; - - - - - -class cWSSCompact : - public cWSSchema -{ -public: - cWSSCompact(cWorld * a_World) : cWSSchema(a_World) {} - virtual ~cWSSCompact(); - -protected: - - struct sChunkHeader; - typedef std::vector sChunkHeaders; - - /// Implements a cache for a single PAK file; implements lazy-write in order to be able to write multiple chunks fast - class cPAKFile - { - public: - - cPAKFile(const AString & a_FileName, int a_LayerX, int a_LayerZ); - ~cPAKFile(); - - bool GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data); - bool SetChunkData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data); - bool EraseChunkData(const cChunkCoords & a_Chunk); - - bool SaveChunk(const cChunkCoords & a_Chunk, cWorld * a_World); - - int GetLayerX(void) const {return m_LayerX; } - int GetLayerZ(void) const {return m_LayerZ; } - - static const int PAK_VERSION = 1; -#if AXIS_ORDER == AXIS_ORDER_XZY - static const int CHUNK_VERSION = 3; -#elif AXIS_ORDER == AXIS_ORDER_YZX - static const int CHUNK_VERSION = 2; -#endif - protected: - - AString m_FileName; - int m_LayerX; - int m_LayerZ; - - sChunkHeaders m_ChunkHeaders; - AString m_DataContents; // Data contents of the file, cached - - int m_NumDirty; // Number of chunks that were written into m_DataContents but not into the file - - Vector3i m_ChunkSize; // Is related to m_ChunkVersion - char m_ChunkVersion; - char m_PakVersion; - - bool SaveChunkToData(const cChunkCoords & a_Chunk, cWorld * a_World); // Saves the chunk to m_DataContents, updates headers and m_NumDirty - void SynchronizeFile(void); // Writes m_DataContents along with the headers to file, resets m_NumDirty - - void UpdateChunk1To2(void); // Height from 128 to 256 - void UpdateChunk2To3(void); // Axis order from YZX to XZY - } ; - - typedef std::list cPAKFiles; - - cCriticalSection m_CS; - cPAKFiles m_PAKFiles; // A MRU cache of PAK files - - /// Loads the correct PAK file either from cache or from disk, manages the m_PAKFiles cache - cPAKFile * LoadPAKFile(const cChunkCoords & a_Chunk); - - /// Gets chunk data from the correct file; locks CS as needed - bool GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data); - - /// Sets chunk data to the correct file; locks CS as needed - bool SetChunkData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data); - - /// Erases chunk data from the correct file; locks CS as needed - bool EraseChunkData(const cChunkCoords & a_Chunk); - - /// Loads the chunk from the data (no locking needed) - bool LoadChunkFromData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, const AString & a_Data, cWorld * a_World); - - void LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities, cWorld * a_World); - - // cWSSchema overrides: - virtual bool LoadChunk(const cChunkCoords & a_Chunk) override; - virtual bool SaveChunk(const cChunkCoords & a_Chunk) override; - virtual const AString GetName(void) const override {return "compact"; } -} ; - - - - - -#endif // WSSCOMPACT_H_INCLUDED - - - - + +// WSSCompact.h + +// Interfaces to the cWSSCompact class representing the "Compact" storage schema (PAK-files) + + + + + +#pragma once +#ifndef WSSCOMPACT_H_INCLUDED +#define WSSCOMPACT_H_INCLUDED + +#include "WorldStorage.h" +#include "Vector3i.h" + + + + + +/// Helper class for serializing a chunk into Json +class cJsonChunkSerializer : + public cChunkDataCollector +{ +public: + + cJsonChunkSerializer(void); + + Json::Value & GetRoot (void) {return m_Root; } + BLOCKTYPE * GetBlockData(void) {return m_BlockData; } + bool HasJsonData (void) const {return m_HasJsonData; } + +protected: + + // NOTE: block data is serialized into inherited cChunkDataCollector's m_BlockData[] array + + // Entities and BlockEntities are serialized to Json + Json::Value m_Root; + bool m_HasJsonData; + + // cChunkDataCollector overrides: + virtual void Entity (cEntity * a_Entity) override; + virtual void BlockEntity (cBlockEntity * a_Entity) override; + virtual bool LightIsValid (bool a_IsLightValid) override; +} ; + + + + + +class cWSSCompact : + public cWSSchema +{ +public: + cWSSCompact(cWorld * a_World) : cWSSchema(a_World) {} + virtual ~cWSSCompact(); + +protected: + + struct sChunkHeader; + typedef std::vector sChunkHeaders; + + /// Implements a cache for a single PAK file; implements lazy-write in order to be able to write multiple chunks fast + class cPAKFile + { + public: + + cPAKFile(const AString & a_FileName, int a_LayerX, int a_LayerZ); + ~cPAKFile(); + + bool GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data); + bool SetChunkData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data); + bool EraseChunkData(const cChunkCoords & a_Chunk); + + bool SaveChunk(const cChunkCoords & a_Chunk, cWorld * a_World); + + int GetLayerX(void) const {return m_LayerX; } + int GetLayerZ(void) const {return m_LayerZ; } + + static const int PAK_VERSION = 1; +#if AXIS_ORDER == AXIS_ORDER_XZY + static const int CHUNK_VERSION = 3; +#elif AXIS_ORDER == AXIS_ORDER_YZX + static const int CHUNK_VERSION = 2; +#endif + protected: + + AString m_FileName; + int m_LayerX; + int m_LayerZ; + + sChunkHeaders m_ChunkHeaders; + AString m_DataContents; // Data contents of the file, cached + + int m_NumDirty; // Number of chunks that were written into m_DataContents but not into the file + + Vector3i m_ChunkSize; // Is related to m_ChunkVersion + char m_ChunkVersion; + char m_PakVersion; + + bool SaveChunkToData(const cChunkCoords & a_Chunk, cWorld * a_World); // Saves the chunk to m_DataContents, updates headers and m_NumDirty + void SynchronizeFile(void); // Writes m_DataContents along with the headers to file, resets m_NumDirty + + void UpdateChunk1To2(void); // Height from 128 to 256 + void UpdateChunk2To3(void); // Axis order from YZX to XZY + } ; + + typedef std::list cPAKFiles; + + cCriticalSection m_CS; + cPAKFiles m_PAKFiles; // A MRU cache of PAK files + + /// Loads the correct PAK file either from cache or from disk, manages the m_PAKFiles cache + cPAKFile * LoadPAKFile(const cChunkCoords & a_Chunk); + + /// Gets chunk data from the correct file; locks CS as needed + bool GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data); + + /// Sets chunk data to the correct file; locks CS as needed + bool SetChunkData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data); + + /// Erases chunk data from the correct file; locks CS as needed + bool EraseChunkData(const cChunkCoords & a_Chunk); + + /// Loads the chunk from the data (no locking needed) + bool LoadChunkFromData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, const AString & a_Data, cWorld * a_World); + + void LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities, cWorld * a_World); + + // cWSSchema overrides: + virtual bool LoadChunk(const cChunkCoords & a_Chunk) override; + virtual bool SaveChunk(const cChunkCoords & a_Chunk) override; + virtual const AString GetName(void) const override {return "compact"; } +} ; + + + + + +#endif // WSSCOMPACT_H_INCLUDED + + + + diff --git a/source/WorldStorage.cpp b/source/WorldStorage.cpp index c9ca69659..ce1c11322 100644 --- a/source/WorldStorage.cpp +++ b/source/WorldStorage.cpp @@ -1,379 +1,379 @@ - -// WorldStorage.cpp - -// Implements the cWorldStorage class representing the chunk loading / saving thread - -// To add a new storage schema, implement a cWSSchema descendant and add it to cWorldStorage::InitSchemas() - -#include "Globals.h" -#include "WorldStorage.h" -#include "WSSCompact.h" -#include "WSSAnvil.h" -#include "cWorld.h" -#include "cChunkGenerator.h" -#include "cEntity.h" -#include "cBlockEntity.h" -#include "BlockID.h" - - - - - -/// Example storage schema - forgets all chunks ;) -class cWSSForgetful : - public cWSSchema -{ -public: - cWSSForgetful(cWorld * a_World) : cWSSchema(a_World) {} - -protected: - // cWSSchema overrides: - virtual bool LoadChunk(const cChunkCoords & a_Chunk) override {return false; } - virtual bool SaveChunk(const cChunkCoords & a_Chunk) override {return true; } - virtual const AString GetName(void) const override {return "forgetful"; } -} ; - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cWorldStorage: - -cWorldStorage::cWorldStorage(void) : - super("cWorldStorage"), - m_World(NULL), - m_SaveSchema(NULL) -{ -} - - - - - -cWorldStorage::~cWorldStorage() -{ - for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr) - { - delete *itr; - } // for itr - m_Schemas[] - m_LoadQueue.clear(); - m_SaveQueue.clear(); -} - - - - - -bool cWorldStorage::Start(cWorld * a_World, const AString & a_StorageSchemaName) -{ - m_World = a_World; - m_StorageSchemaName = a_StorageSchemaName; - InitSchemas(); - - return super::Start(); -} - - - - - -void cWorldStorage::WaitForFinish(void) -{ - LOG("Waiting for the world storage to finish saving"); - - { - // Cancel all loading requests: - cCSLock Lock(m_CSQueues); - m_LoadQueue.clear(); - } - - // Wait for the saving to finish: - WaitForQueuesEmpty(); - - // Wait for the thread to finish: - m_ShouldTerminate = true; - m_Event.Set(); - m_evtRemoved.Set(); // Wake up anybody waiting in the WaitForQueuesEmpty() method - super::Wait(); - LOG("World storage thread finished"); -} - - - - - -void cWorldStorage::WaitForQueuesEmpty(void) -{ - cCSLock Lock(m_CSQueues); - while (!m_ShouldTerminate && (!m_LoadQueue.empty() || !m_SaveQueue.empty())) - { - cCSUnlock Unlock(Lock); - m_evtRemoved.Wait(); - } -} - - - - - -int cWorldStorage::GetLoadQueueLength(void) -{ - cCSLock Lock(m_CSQueues); - return (int)m_LoadQueue.size(); -} - - - - - -int cWorldStorage::GetSaveQueueLength(void) -{ - cCSLock Lock(m_CSQueues); - return (int)m_SaveQueue.size(); -} - - - - - -void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate) -{ - // Queues the chunk for loading; if not loaded, the chunk will be generated - { - cCSLock Lock(m_CSQueues); - - // Check if already in the queue: - for (sChunkLoadQueue::iterator itr = m_LoadQueue.begin(); itr != m_LoadQueue.end(); ++itr) - { - if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ) && (itr->m_Generate == a_Generate)) - { - return; - } - } - m_LoadQueue.push_back(sChunkLoad(a_ChunkX, a_ChunkY, a_ChunkZ, a_Generate)); - } - - m_Event.Set(); -} - - - - - -void cWorldStorage::QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - { - cCSLock Lock(m_CSQueues); - m_SaveQueue.remove (cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); // Don't add twice - m_SaveQueue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); - } - m_Event.Set(); -} - - - - - -void cWorldStorage::UnqueueLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - cCSLock Lock(m_CSQueues); - for (sChunkLoadQueue::iterator itr = m_LoadQueue.begin(); itr != m_LoadQueue.end(); ++itr) - { - if ((itr->m_ChunkX != a_ChunkX) || (itr->m_ChunkY != a_ChunkY) || (itr->m_ChunkZ != a_ChunkZ)) - { - continue; - } - m_LoadQueue.erase(itr); - Lock.Unlock(); - m_evtRemoved.Set(); - return; - } // for itr - m_LoadQueue[] -} - - - - - -void cWorldStorage::UnqueueSave(const cChunkCoords & a_Chunk) -{ - { - cCSLock Lock(m_CSQueues); - m_SaveQueue.remove(a_Chunk); - } - m_evtRemoved.Set(); -} - - - - - -void cWorldStorage::InitSchemas(void) -{ - // The first schema added is considered the default - m_Schemas.push_back(new cWSSCompact (m_World)); - m_Schemas.push_back(new cWSSAnvil (m_World)); - m_Schemas.push_back(new cWSSForgetful(m_World)); - // Add new schemas here - - if (NoCaseCompare(m_StorageSchemaName, "default") == 0) - { - m_SaveSchema = m_Schemas.front(); - return; - } - for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr) - { - if (NoCaseCompare((*itr)->GetName(), m_StorageSchemaName) == 0) - { - m_SaveSchema = *itr; - return; - } - } // for itr - m_Schemas[] - - // Unknown schema selected, let the admin know: - LOGWARNING("Unknown storage schema name \"%s\". Using default (\"%s\"). Available schemas:", - m_StorageSchemaName.c_str(), m_SaveSchema->GetName().c_str() - ); - for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr) - { - LOGWARNING("\t\"%s\"", (*itr)->GetName().c_str()); - } - m_SaveSchema = m_Schemas.front(); -} - - - - - -void cWorldStorage::Execute(void) -{ - while (!m_ShouldTerminate) - { - m_Event.Wait(); - - // Process both queues until they are empty again: - bool HasMore; - do - { - HasMore = false; - if (m_ShouldTerminate) - { - return; - } - - HasMore = LoadOneChunk(); - HasMore = HasMore | SaveOneChunk(); - m_evtRemoved.Set(); - } while (HasMore); - } -} - - - - - -bool cWorldStorage::LoadOneChunk(void) -{ - sChunkLoad ToLoad(0, 0, 0, false); - bool HasMore; - bool ShouldLoad = false; - { - cCSLock Lock(m_CSQueues); - if (!m_LoadQueue.empty()) - { - ToLoad = m_LoadQueue.front(); - m_LoadQueue.pop_front(); - ShouldLoad = true; - } - HasMore = !m_LoadQueue.empty(); - } - - if (ShouldLoad && !LoadChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ)) - { - if (ToLoad.m_Generate) - { - // The chunk couldn't be loaded, generate it: - m_World->GetGenerator().QueueGenerateChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ); - } - else - { - // TODO: Notify the world that the load has failed: - // m_World->ChunkLoadFailed(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ); - } - } - return HasMore; -} - - - - - -bool cWorldStorage::SaveOneChunk(void) -{ - cChunkCoords Save(0, 0, 0); - bool HasMore; - bool ShouldSave = false; - { - cCSLock Lock(m_CSQueues); - if (!m_SaveQueue.empty()) - { - Save = m_SaveQueue.front(); - m_SaveQueue.pop_front(); - ShouldSave = true; - } - HasMore = !m_SaveQueue.empty(); - } - if (ShouldSave && m_World->IsChunkValid(Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ)) - { - m_World->MarkChunkSaving(Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ); - if (m_SaveSchema->SaveChunk(Save)) - { - m_World->MarkChunkSaved(Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ); - } - else - { - LOGWARNING("Cannot save chunk [%d, %d, %d]", Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ); - } - } - return HasMore; -} - - - - - -bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - if (m_World->IsChunkValid(a_ChunkX, a_ChunkY, a_ChunkZ)) - { - // Already loaded (can happen, since the queue is async) - return true; - } - - cChunkCoords Coords(a_ChunkX, a_ChunkY, a_ChunkZ); - - // First try the schema that is used for saving - if (m_SaveSchema->LoadChunk(Coords)) - { - return true; - } - - // If it didn't have the chunk, try all the other schemas: - for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr) - { - if (((*itr) != m_SaveSchema) && (*itr)->LoadChunk(Coords)) - { - return true; - } - } - - // Notify the chunk owner that the chunk failed to load (sets cChunk::m_HasLoadFailed to true): - m_World->ChunkLoadFailed(a_ChunkX, a_ChunkY, a_ChunkZ); - - return false; -} - - - - - + +// WorldStorage.cpp + +// Implements the cWorldStorage class representing the chunk loading / saving thread + +// To add a new storage schema, implement a cWSSchema descendant and add it to cWorldStorage::InitSchemas() + +#include "Globals.h" +#include "WorldStorage.h" +#include "WSSCompact.h" +#include "WSSAnvil.h" +#include "cWorld.h" +#include "cChunkGenerator.h" +#include "cEntity.h" +#include "cBlockEntity.h" +#include "BlockID.h" + + + + + +/// Example storage schema - forgets all chunks ;) +class cWSSForgetful : + public cWSSchema +{ +public: + cWSSForgetful(cWorld * a_World) : cWSSchema(a_World) {} + +protected: + // cWSSchema overrides: + virtual bool LoadChunk(const cChunkCoords & a_Chunk) override {return false; } + virtual bool SaveChunk(const cChunkCoords & a_Chunk) override {return true; } + virtual const AString GetName(void) const override {return "forgetful"; } +} ; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cWorldStorage: + +cWorldStorage::cWorldStorage(void) : + super("cWorldStorage"), + m_World(NULL), + m_SaveSchema(NULL) +{ +} + + + + + +cWorldStorage::~cWorldStorage() +{ + for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr) + { + delete *itr; + } // for itr - m_Schemas[] + m_LoadQueue.clear(); + m_SaveQueue.clear(); +} + + + + + +bool cWorldStorage::Start(cWorld * a_World, const AString & a_StorageSchemaName) +{ + m_World = a_World; + m_StorageSchemaName = a_StorageSchemaName; + InitSchemas(); + + return super::Start(); +} + + + + + +void cWorldStorage::WaitForFinish(void) +{ + LOG("Waiting for the world storage to finish saving"); + + { + // Cancel all loading requests: + cCSLock Lock(m_CSQueues); + m_LoadQueue.clear(); + } + + // Wait for the saving to finish: + WaitForQueuesEmpty(); + + // Wait for the thread to finish: + m_ShouldTerminate = true; + m_Event.Set(); + m_evtRemoved.Set(); // Wake up anybody waiting in the WaitForQueuesEmpty() method + super::Wait(); + LOG("World storage thread finished"); +} + + + + + +void cWorldStorage::WaitForQueuesEmpty(void) +{ + cCSLock Lock(m_CSQueues); + while (!m_ShouldTerminate && (!m_LoadQueue.empty() || !m_SaveQueue.empty())) + { + cCSUnlock Unlock(Lock); + m_evtRemoved.Wait(); + } +} + + + + + +int cWorldStorage::GetLoadQueueLength(void) +{ + cCSLock Lock(m_CSQueues); + return (int)m_LoadQueue.size(); +} + + + + + +int cWorldStorage::GetSaveQueueLength(void) +{ + cCSLock Lock(m_CSQueues); + return (int)m_SaveQueue.size(); +} + + + + + +void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate) +{ + // Queues the chunk for loading; if not loaded, the chunk will be generated + { + cCSLock Lock(m_CSQueues); + + // Check if already in the queue: + for (sChunkLoadQueue::iterator itr = m_LoadQueue.begin(); itr != m_LoadQueue.end(); ++itr) + { + if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ) && (itr->m_Generate == a_Generate)) + { + return; + } + } + m_LoadQueue.push_back(sChunkLoad(a_ChunkX, a_ChunkY, a_ChunkZ, a_Generate)); + } + + m_Event.Set(); +} + + + + + +void cWorldStorage::QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + { + cCSLock Lock(m_CSQueues); + m_SaveQueue.remove (cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); // Don't add twice + m_SaveQueue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); + } + m_Event.Set(); +} + + + + + +void cWorldStorage::UnqueueLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSQueues); + for (sChunkLoadQueue::iterator itr = m_LoadQueue.begin(); itr != m_LoadQueue.end(); ++itr) + { + if ((itr->m_ChunkX != a_ChunkX) || (itr->m_ChunkY != a_ChunkY) || (itr->m_ChunkZ != a_ChunkZ)) + { + continue; + } + m_LoadQueue.erase(itr); + Lock.Unlock(); + m_evtRemoved.Set(); + return; + } // for itr - m_LoadQueue[] +} + + + + + +void cWorldStorage::UnqueueSave(const cChunkCoords & a_Chunk) +{ + { + cCSLock Lock(m_CSQueues); + m_SaveQueue.remove(a_Chunk); + } + m_evtRemoved.Set(); +} + + + + + +void cWorldStorage::InitSchemas(void) +{ + // The first schema added is considered the default + m_Schemas.push_back(new cWSSCompact (m_World)); + m_Schemas.push_back(new cWSSAnvil (m_World)); + m_Schemas.push_back(new cWSSForgetful(m_World)); + // Add new schemas here + + if (NoCaseCompare(m_StorageSchemaName, "default") == 0) + { + m_SaveSchema = m_Schemas.front(); + return; + } + for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr) + { + if (NoCaseCompare((*itr)->GetName(), m_StorageSchemaName) == 0) + { + m_SaveSchema = *itr; + return; + } + } // for itr - m_Schemas[] + + // Unknown schema selected, let the admin know: + LOGWARNING("Unknown storage schema name \"%s\". Using default (\"%s\"). Available schemas:", + m_StorageSchemaName.c_str(), m_SaveSchema->GetName().c_str() + ); + for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr) + { + LOGWARNING("\t\"%s\"", (*itr)->GetName().c_str()); + } + m_SaveSchema = m_Schemas.front(); +} + + + + + +void cWorldStorage::Execute(void) +{ + while (!m_ShouldTerminate) + { + m_Event.Wait(); + + // Process both queues until they are empty again: + bool HasMore; + do + { + HasMore = false; + if (m_ShouldTerminate) + { + return; + } + + HasMore = LoadOneChunk(); + HasMore = HasMore | SaveOneChunk(); + m_evtRemoved.Set(); + } while (HasMore); + } +} + + + + + +bool cWorldStorage::LoadOneChunk(void) +{ + sChunkLoad ToLoad(0, 0, 0, false); + bool HasMore; + bool ShouldLoad = false; + { + cCSLock Lock(m_CSQueues); + if (!m_LoadQueue.empty()) + { + ToLoad = m_LoadQueue.front(); + m_LoadQueue.pop_front(); + ShouldLoad = true; + } + HasMore = !m_LoadQueue.empty(); + } + + if (ShouldLoad && !LoadChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ)) + { + if (ToLoad.m_Generate) + { + // The chunk couldn't be loaded, generate it: + m_World->GetGenerator().QueueGenerateChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ); + } + else + { + // TODO: Notify the world that the load has failed: + // m_World->ChunkLoadFailed(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ); + } + } + return HasMore; +} + + + + + +bool cWorldStorage::SaveOneChunk(void) +{ + cChunkCoords Save(0, 0, 0); + bool HasMore; + bool ShouldSave = false; + { + cCSLock Lock(m_CSQueues); + if (!m_SaveQueue.empty()) + { + Save = m_SaveQueue.front(); + m_SaveQueue.pop_front(); + ShouldSave = true; + } + HasMore = !m_SaveQueue.empty(); + } + if (ShouldSave && m_World->IsChunkValid(Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ)) + { + m_World->MarkChunkSaving(Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ); + if (m_SaveSchema->SaveChunk(Save)) + { + m_World->MarkChunkSaved(Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ); + } + else + { + LOGWARNING("Cannot save chunk [%d, %d, %d]", Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ); + } + } + return HasMore; +} + + + + + +bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + if (m_World->IsChunkValid(a_ChunkX, a_ChunkY, a_ChunkZ)) + { + // Already loaded (can happen, since the queue is async) + return true; + } + + cChunkCoords Coords(a_ChunkX, a_ChunkY, a_ChunkZ); + + // First try the schema that is used for saving + if (m_SaveSchema->LoadChunk(Coords)) + { + return true; + } + + // If it didn't have the chunk, try all the other schemas: + for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr) + { + if (((*itr) != m_SaveSchema) && (*itr)->LoadChunk(Coords)) + { + return true; + } + } + + // Notify the chunk owner that the chunk failed to load (sets cChunk::m_HasLoadFailed to true): + m_World->ChunkLoadFailed(a_ChunkX, a_ChunkY, a_ChunkZ); + + return false; +} + + + + + diff --git a/source/WorldStorage.h b/source/WorldStorage.h index 0c725a460..b2daba059 100644 --- a/source/WorldStorage.h +++ b/source/WorldStorage.h @@ -1,131 +1,131 @@ - -// WorldStorage.h - -// Interfaces to the cWorldStorage class representing the chunk loading / saving thread -// This class decides which storage schema to use for saving; it queries all available schemas for loading -// Also declares the base class for all storage schemas, cWSSchema -// Helper serialization class cJsonChunkSerializer is declared as well - - - - - -#pragma once -#ifndef WORLDSTORAGE_H_INCLUDED -#define WORLDSTORAGE_H_INCLUDED - -#include "ChunkDef.h" -#include "cIsThread.h" -#include - - - - - -// fwd: -class cWorld; - - - - - -/// Interface that all the world storage schemas need to implement -class cWSSchema abstract -{ -public: - cWSSchema(cWorld * a_World) : m_World(a_World) {} - virtual ~cWSSchema() {} // Force the descendants' destructors to be virtual - - virtual bool LoadChunk(const cChunkCoords & a_Chunk) = 0; - virtual bool SaveChunk(const cChunkCoords & a_Chunk) = 0; - virtual const AString GetName(void) const = 0; - -protected: - - cWorld * m_World; -} ; - -typedef std::list cWSSchemaList; - - - - - -/// The actual world storage class -class cWorldStorage : - public cIsThread -{ - typedef cIsThread super; - -public: - - cWorldStorage(void); - ~cWorldStorage(); - - void QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate); // Queues the chunk for loading; if not loaded, the chunk will be generated if a_Generate is true - void QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); - - /// Loads the chunk specified; returns true on success, false on failure - bool LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); - - void UnqueueLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ); - void UnqueueSave(const cChunkCoords & a_Chunk); - - bool Start(cWorld * a_World, const AString & a_StorageSchemaName); // Hide the cIsThread's Start() method, we need to provide args - void WaitForFinish(void); - void WaitForQueuesEmpty(void); - - int GetLoadQueueLength(void); - int GetSaveQueueLength(void); - -protected: - - struct sChunkLoad - { - int m_ChunkX; - int m_ChunkY; - int m_ChunkZ; - bool m_Generate; // If true, the chunk will be generated if it cannot be loaded - - sChunkLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate) : m_ChunkX(a_ChunkX), m_ChunkY(a_ChunkY), m_ChunkZ(a_ChunkZ), m_Generate(a_Generate) {} - } ; - - typedef std::list sChunkLoadQueue; - - cWorld * m_World; - AString m_StorageSchemaName; - - // Both queues are locked by the same CS - cCriticalSection m_CSQueues; - sChunkLoadQueue m_LoadQueue; - cChunkCoordsList m_SaveQueue; - - cEvent m_Event; // Set when there's any addition to the queues - cEvent m_evtRemoved; // Set when an item has been removed from the queue, either by the worker thread or the Unqueue methods - - /// All the storage schemas (all used for loading) - cWSSchemaList m_Schemas; - - /// The one storage schema used for saving - cWSSchema * m_SaveSchema; - - void InitSchemas(void); - - virtual void Execute(void) override; - - /// Loads one chunk from the queue (if any queued); returns true if there are more chunks in the load queue - bool LoadOneChunk(void); - - /// Saves one chunk from the queue (if any queued); returns true if there are more chunks in the save queue - bool SaveOneChunk(void); -} ; - - - - - -#endif // WORLDSTORAGE_H_INCLUDED - - - - + +// WorldStorage.h + +// Interfaces to the cWorldStorage class representing the chunk loading / saving thread +// This class decides which storage schema to use for saving; it queries all available schemas for loading +// Also declares the base class for all storage schemas, cWSSchema +// Helper serialization class cJsonChunkSerializer is declared as well + + + + + +#pragma once +#ifndef WORLDSTORAGE_H_INCLUDED +#define WORLDSTORAGE_H_INCLUDED + +#include "ChunkDef.h" +#include "cIsThread.h" +#include + + + + + +// fwd: +class cWorld; + + + + + +/// Interface that all the world storage schemas need to implement +class cWSSchema abstract +{ +public: + cWSSchema(cWorld * a_World) : m_World(a_World) {} + virtual ~cWSSchema() {} // Force the descendants' destructors to be virtual + + virtual bool LoadChunk(const cChunkCoords & a_Chunk) = 0; + virtual bool SaveChunk(const cChunkCoords & a_Chunk) = 0; + virtual const AString GetName(void) const = 0; + +protected: + + cWorld * m_World; +} ; + +typedef std::list cWSSchemaList; + + + + + +/// The actual world storage class +class cWorldStorage : + public cIsThread +{ + typedef cIsThread super; + +public: + + cWorldStorage(void); + ~cWorldStorage(); + + void QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate); // Queues the chunk for loading; if not loaded, the chunk will be generated if a_Generate is true + void QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Loads the chunk specified; returns true on success, false on failure + bool LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + void UnqueueLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + void UnqueueSave(const cChunkCoords & a_Chunk); + + bool Start(cWorld * a_World, const AString & a_StorageSchemaName); // Hide the cIsThread's Start() method, we need to provide args + void WaitForFinish(void); + void WaitForQueuesEmpty(void); + + int GetLoadQueueLength(void); + int GetSaveQueueLength(void); + +protected: + + struct sChunkLoad + { + int m_ChunkX; + int m_ChunkY; + int m_ChunkZ; + bool m_Generate; // If true, the chunk will be generated if it cannot be loaded + + sChunkLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate) : m_ChunkX(a_ChunkX), m_ChunkY(a_ChunkY), m_ChunkZ(a_ChunkZ), m_Generate(a_Generate) {} + } ; + + typedef std::list sChunkLoadQueue; + + cWorld * m_World; + AString m_StorageSchemaName; + + // Both queues are locked by the same CS + cCriticalSection m_CSQueues; + sChunkLoadQueue m_LoadQueue; + cChunkCoordsList m_SaveQueue; + + cEvent m_Event; // Set when there's any addition to the queues + cEvent m_evtRemoved; // Set when an item has been removed from the queue, either by the worker thread or the Unqueue methods + + /// All the storage schemas (all used for loading) + cWSSchemaList m_Schemas; + + /// The one storage schema used for saving + cWSSchema * m_SaveSchema; + + void InitSchemas(void); + + virtual void Execute(void) override; + + /// Loads one chunk from the queue (if any queued); returns true if there are more chunks in the load queue + bool LoadOneChunk(void); + + /// Saves one chunk from the queue (if any queued); returns true if there are more chunks in the save queue + bool SaveOneChunk(void); +} ; + + + + + +#endif // WORLDSTORAGE_H_INCLUDED + + + + diff --git a/source/cAggressiveMonster.cpp b/source/cAggressiveMonster.cpp index e597bfed8..3fa61bb33 100644 --- a/source/cAggressiveMonster.cpp +++ b/source/cAggressiveMonster.cpp @@ -1,78 +1,78 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cAggressiveMonster.h" - -#include "Vector3f.h" -#include "cPlayer.h" -#include "MersenneTwister.h" - - -cAggressiveMonster::cAggressiveMonster() - : m_ChaseTime(999999) -{ - m_EMPersonality = AGGRESSIVE; -} - -cAggressiveMonster::~cAggressiveMonster() -{ -} - -//What to do if in Chasing State -void cAggressiveMonster::InStateChasing(float a_Dt) { - cMonster::InStateChasing(a_Dt); - m_ChaseTime += a_Dt; - if( m_Target ) - { - if(m_Target->GetEntityType() == cEntity::eEntityType_Player) - { - cPlayer * Player = (cPlayer *) m_Target; - if(Player->GetGameMode() == 1) - { - m_EMState = IDLE; - return; - } - } - - Vector3f Pos = Vector3f( m_Pos ); - Vector3f Their = Vector3f( m_Target->GetPosition() ); - if( (Their - Pos).Length() <= m_AttackRange) { - cMonster::Attack(a_Dt); - } - MoveToPosition( Their + Vector3f(0, 0.65f, 0) ); - } else if( m_ChaseTime > 5.f ) { - m_ChaseTime = 0; - m_EMState = IDLE; - } -} - - - -void cAggressiveMonster::EventSeePlayer(cEntity *a_Entity) -{ - cMonster::EventSeePlayer(a_Entity); - m_EMState = CHASING; -} - -void cAggressiveMonster::Tick(float a_Dt) -{ - cMonster::Tick(a_Dt); - - m_SeePlayerInterval += a_Dt; - - if(m_SeePlayerInterval > 1) - { - MTRand r1; - int rem = r1.randInt() % 3 + 1; //check most of the time but miss occasionally - - m_SeePlayerInterval = 0.0; - if(rem >= 2) - { - if(m_EMState == CHASING){ - CheckEventLostPlayer(); - } else { - CheckEventSeePlayer(); - } - } - } + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cAggressiveMonster.h" + +#include "Vector3f.h" +#include "cPlayer.h" +#include "MersenneTwister.h" + + +cAggressiveMonster::cAggressiveMonster() + : m_ChaseTime(999999) +{ + m_EMPersonality = AGGRESSIVE; +} + +cAggressiveMonster::~cAggressiveMonster() +{ +} + +//What to do if in Chasing State +void cAggressiveMonster::InStateChasing(float a_Dt) { + cMonster::InStateChasing(a_Dt); + m_ChaseTime += a_Dt; + if( m_Target ) + { + if(m_Target->GetEntityType() == cEntity::eEntityType_Player) + { + cPlayer * Player = (cPlayer *) m_Target; + if(Player->GetGameMode() == 1) + { + m_EMState = IDLE; + return; + } + } + + Vector3f Pos = Vector3f( m_Pos ); + Vector3f Their = Vector3f( m_Target->GetPosition() ); + if( (Their - Pos).Length() <= m_AttackRange) { + cMonster::Attack(a_Dt); + } + MoveToPosition( Their + Vector3f(0, 0.65f, 0) ); + } else if( m_ChaseTime > 5.f ) { + m_ChaseTime = 0; + m_EMState = IDLE; + } +} + + + +void cAggressiveMonster::EventSeePlayer(cEntity *a_Entity) +{ + cMonster::EventSeePlayer(a_Entity); + m_EMState = CHASING; +} + +void cAggressiveMonster::Tick(float a_Dt) +{ + cMonster::Tick(a_Dt); + + m_SeePlayerInterval += a_Dt; + + if(m_SeePlayerInterval > 1) + { + MTRand r1; + int rem = r1.randInt() % 3 + 1; //check most of the time but miss occasionally + + m_SeePlayerInterval = 0.0; + if(rem >= 2) + { + if(m_EMState == CHASING){ + CheckEventLostPlayer(); + } else { + CheckEventSeePlayer(); + } + } + } } \ No newline at end of file diff --git a/source/cAuthenticator.cpp b/source/cAuthenticator.cpp index d45eaa043..f248f4698 100644 --- a/source/cAuthenticator.cpp +++ b/source/cAuthenticator.cpp @@ -1,274 +1,274 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cAuthenticator.h" -#include "cBlockingTCPLink.h" -#include "cRoot.h" -#include "cServer.h" - -#include "../iniFile/iniFile.h" - -#include - - - - - -#define DEFAULT_AUTH_SERVER "session.minecraft.net" -#define DEFAULT_AUTH_ADDRESS "/game/checkserver.jsp?user=%USERNAME%&serverId=%SERVERID%" -#define MAX_REDIRECTS 10 - - - - - -cAuthenticator::cAuthenticator(void) : - super("cAuthenticator"), - m_Server(DEFAULT_AUTH_SERVER), - m_Address(DEFAULT_AUTH_ADDRESS), - m_ShouldAuthenticate(true) -{ - ReadINI(); -} - - - - - -cAuthenticator::~cAuthenticator() -{ - Stop(); -} - - - - - -/// Read custom values from INI -void cAuthenticator::ReadINI(void) -{ - cIniFile IniFile("settings.ini"); - if (!IniFile.ReadFile()) - { - return; - } - - m_Server = IniFile.GetValue("Authentication", "Server"); - m_Address = IniFile.GetValue("Authentication", "Address"); - m_ShouldAuthenticate = IniFile.GetValueB("Authentication", "Authenticate", true); - bool bSave = false; - - if (m_Server.length() == 0) - { - m_Server = DEFAULT_AUTH_SERVER; - IniFile.SetValue("Authentication", "Server", m_Server); - bSave = true; - } - if (m_Address.length() == 0) - { - m_Address = DEFAULT_AUTH_ADDRESS; - IniFile.SetValue("Authentication", "Address", m_Address); - bSave = true; - } - - if (bSave) - { - IniFile.SetValueB("Authentication", "Authenticate", m_ShouldAuthenticate); - IniFile.WriteFile(); - } -} - - - - - -/// Queues a request for authenticating a user. If the auth fails, the user is kicked -void cAuthenticator::Authenticate(int a_ClientID, const AString & a_UserName, const AString & a_ServerHash) -{ - if (!m_ShouldAuthenticate) - { - cRoot::Get()->AuthenticateUser(a_ClientID); - return; - } - - cCSLock Lock(m_CS); - m_Queue.push_back(cUser(a_ClientID, a_UserName, a_ServerHash)); - m_QueueNonempty.Set(); -} - - - - - -void cAuthenticator::Stop(void) -{ - m_ShouldTerminate = true; - m_QueueNonempty.Set(); - Wait(); -} - - - - - -void cAuthenticator::Execute(void) -{ - for (;;) - { - cCSLock Lock(m_CS); - while (!m_ShouldTerminate && (m_Queue.size() == 0)) - { - cCSUnlock Unlock(Lock); - m_QueueNonempty.Wait(); - } - if (m_ShouldTerminate) - { - return; - } - ASSERT(!m_Queue.empty()); - - int ClientID = m_Queue.front().mClientID; - AString UserName = m_Queue.front().mName; - AString ActualAddress = m_Address; - ReplaceString(ActualAddress, "%USERNAME%", UserName); - ReplaceString(ActualAddress, "%SERVERID%", cRoot::Get()->GetServer()->GetServerID()); - m_Queue.pop_front(); - Lock.Unlock(); - - if (!AuthFromAddress(m_Server, ActualAddress, UserName)) - { - cRoot::Get()->KickUser(ClientID, "Failed to authenticate account!"); - } - else - { - cRoot::Get()->AuthenticateUser(ClientID); - } - } // for (-ever) -} - - - - - -bool cAuthenticator::AuthFromAddress(const AString & a_Server, const AString & a_Address, const AString & a_UserName, int a_Level /* = 1 */) -{ - // Returns true if the user authenticated okay, false on error; iLevel is the recursion deptht (bails out if too deep) - - cBlockingTCPLink Link; - if (!Link.Connect(a_Server.c_str(), 80)) - { - LOGERROR("cAuthenticator: cannot connect to auth server \"%s\", kicking user \"%s\"", a_Server.c_str(), a_Server.c_str()); - return false; - } - - Link.SendMessage( AString( "GET " + a_Address + " HTTP/1.0\r\n\r\n" ).c_str()); - AString DataRecvd; - Link.ReceiveData(DataRecvd); - Link.CloseSocket(); - - std::stringstream ss(DataRecvd); - - // Parse the data received: - std::string temp; - ss >> temp; - bool bRedirect = false; - bool bOK = false; - if ((temp.compare("HTTP/1.1") == 0) || (temp.compare("HTTP/1.0") == 0)) - { - int code; - ss >> code; - if (code == 302) - { - // redirect blabla - LOGINFO("Need to redirect!"); - if (a_Level > MAX_REDIRECTS) - { - LOGERROR("cAuthenticator: received too many levels of redirection from auth server \"%s\" for user \"%s\", bailing out and kicking the user", a_Server.c_str(), a_UserName.c_str()); - return false; - } - bRedirect = true; - } - else if (code == 200) - { - LOGINFO("Got 200 OK :D"); - bOK = true; - } - } - else - { - LOGERROR("cAuthenticator: cannot parse auth reply from server \"%s\" for user \"%s\", kicking the user.", a_Server.c_str(), a_UserName.c_str()); - return false; - } - - if( bRedirect ) - { - AString Location; - // Search for "Location:" - bool bFoundLocation = false; - while( !bFoundLocation && ss.good() ) - { - char c = 0; - while( c != '\n' ) - { - ss.get( c ); - } - AString Name; - ss >> Name; - if (Name.compare("Location:") == 0) - { - bFoundLocation = true; - ss >> Location; - } - } - if (!bFoundLocation) - { - LOGERROR("cAuthenticator: received invalid redirection from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str()); - return false; - } - - Location = Location.substr(strlen("http://"), std::string::npos); // Strip http:// - std::string Server = Location.substr( 0, Location.find( "/" ) ); // Only leave server address - Location = Location.substr( Server.length(), std::string::npos); - return AuthFromAddress(Server, Location, a_UserName, a_Level + 1); - } - - if (!bOK) - { - LOGERROR("cAuthenticator: received an error from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str()); - return false; - } - - // Header says OK, so receive the rest. - // Go past header, double \n means end of headers - char c = 0; - while (ss.good()) - { - while (c != '\n') - { - ss.get(c); - } - ss.get(c); - if( c == '\n' || c == '\r' || ss.peek() == '\r' || ss.peek() == '\n' ) - break; - } - if (!ss.good()) - { - LOGERROR("cAuthenticator: error while parsing response body from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str()); - return false; - } - - std::string Result; - ss >> Result; - LOGINFO("Got result: %s", Result.c_str()); - if (Result.compare("YES") == 0) - { - LOGINFO("Result was \"YES\", so player is authenticated!"); - return true; - } - LOGINFO("Result was \"%s\", so player is NOT authenticated!", Result.c_str()); - return false; -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cAuthenticator.h" +#include "cBlockingTCPLink.h" +#include "cRoot.h" +#include "cServer.h" + +#include "../iniFile/iniFile.h" + +#include + + + + + +#define DEFAULT_AUTH_SERVER "session.minecraft.net" +#define DEFAULT_AUTH_ADDRESS "/game/checkserver.jsp?user=%USERNAME%&serverId=%SERVERID%" +#define MAX_REDIRECTS 10 + + + + + +cAuthenticator::cAuthenticator(void) : + super("cAuthenticator"), + m_Server(DEFAULT_AUTH_SERVER), + m_Address(DEFAULT_AUTH_ADDRESS), + m_ShouldAuthenticate(true) +{ + ReadINI(); +} + + + + + +cAuthenticator::~cAuthenticator() +{ + Stop(); +} + + + + + +/// Read custom values from INI +void cAuthenticator::ReadINI(void) +{ + cIniFile IniFile("settings.ini"); + if (!IniFile.ReadFile()) + { + return; + } + + m_Server = IniFile.GetValue("Authentication", "Server"); + m_Address = IniFile.GetValue("Authentication", "Address"); + m_ShouldAuthenticate = IniFile.GetValueB("Authentication", "Authenticate", true); + bool bSave = false; + + if (m_Server.length() == 0) + { + m_Server = DEFAULT_AUTH_SERVER; + IniFile.SetValue("Authentication", "Server", m_Server); + bSave = true; + } + if (m_Address.length() == 0) + { + m_Address = DEFAULT_AUTH_ADDRESS; + IniFile.SetValue("Authentication", "Address", m_Address); + bSave = true; + } + + if (bSave) + { + IniFile.SetValueB("Authentication", "Authenticate", m_ShouldAuthenticate); + IniFile.WriteFile(); + } +} + + + + + +/// Queues a request for authenticating a user. If the auth fails, the user is kicked +void cAuthenticator::Authenticate(int a_ClientID, const AString & a_UserName, const AString & a_ServerHash) +{ + if (!m_ShouldAuthenticate) + { + cRoot::Get()->AuthenticateUser(a_ClientID); + return; + } + + cCSLock Lock(m_CS); + m_Queue.push_back(cUser(a_ClientID, a_UserName, a_ServerHash)); + m_QueueNonempty.Set(); +} + + + + + +void cAuthenticator::Stop(void) +{ + m_ShouldTerminate = true; + m_QueueNonempty.Set(); + Wait(); +} + + + + + +void cAuthenticator::Execute(void) +{ + for (;;) + { + cCSLock Lock(m_CS); + while (!m_ShouldTerminate && (m_Queue.size() == 0)) + { + cCSUnlock Unlock(Lock); + m_QueueNonempty.Wait(); + } + if (m_ShouldTerminate) + { + return; + } + ASSERT(!m_Queue.empty()); + + int ClientID = m_Queue.front().mClientID; + AString UserName = m_Queue.front().mName; + AString ActualAddress = m_Address; + ReplaceString(ActualAddress, "%USERNAME%", UserName); + ReplaceString(ActualAddress, "%SERVERID%", cRoot::Get()->GetServer()->GetServerID()); + m_Queue.pop_front(); + Lock.Unlock(); + + if (!AuthFromAddress(m_Server, ActualAddress, UserName)) + { + cRoot::Get()->KickUser(ClientID, "Failed to authenticate account!"); + } + else + { + cRoot::Get()->AuthenticateUser(ClientID); + } + } // for (-ever) +} + + + + + +bool cAuthenticator::AuthFromAddress(const AString & a_Server, const AString & a_Address, const AString & a_UserName, int a_Level /* = 1 */) +{ + // Returns true if the user authenticated okay, false on error; iLevel is the recursion deptht (bails out if too deep) + + cBlockingTCPLink Link; + if (!Link.Connect(a_Server.c_str(), 80)) + { + LOGERROR("cAuthenticator: cannot connect to auth server \"%s\", kicking user \"%s\"", a_Server.c_str(), a_Server.c_str()); + return false; + } + + Link.SendMessage( AString( "GET " + a_Address + " HTTP/1.0\r\n\r\n" ).c_str()); + AString DataRecvd; + Link.ReceiveData(DataRecvd); + Link.CloseSocket(); + + std::stringstream ss(DataRecvd); + + // Parse the data received: + std::string temp; + ss >> temp; + bool bRedirect = false; + bool bOK = false; + if ((temp.compare("HTTP/1.1") == 0) || (temp.compare("HTTP/1.0") == 0)) + { + int code; + ss >> code; + if (code == 302) + { + // redirect blabla + LOGINFO("Need to redirect!"); + if (a_Level > MAX_REDIRECTS) + { + LOGERROR("cAuthenticator: received too many levels of redirection from auth server \"%s\" for user \"%s\", bailing out and kicking the user", a_Server.c_str(), a_UserName.c_str()); + return false; + } + bRedirect = true; + } + else if (code == 200) + { + LOGINFO("Got 200 OK :D"); + bOK = true; + } + } + else + { + LOGERROR("cAuthenticator: cannot parse auth reply from server \"%s\" for user \"%s\", kicking the user.", a_Server.c_str(), a_UserName.c_str()); + return false; + } + + if( bRedirect ) + { + AString Location; + // Search for "Location:" + bool bFoundLocation = false; + while( !bFoundLocation && ss.good() ) + { + char c = 0; + while( c != '\n' ) + { + ss.get( c ); + } + AString Name; + ss >> Name; + if (Name.compare("Location:") == 0) + { + bFoundLocation = true; + ss >> Location; + } + } + if (!bFoundLocation) + { + LOGERROR("cAuthenticator: received invalid redirection from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str()); + return false; + } + + Location = Location.substr(strlen("http://"), std::string::npos); // Strip http:// + std::string Server = Location.substr( 0, Location.find( "/" ) ); // Only leave server address + Location = Location.substr( Server.length(), std::string::npos); + return AuthFromAddress(Server, Location, a_UserName, a_Level + 1); + } + + if (!bOK) + { + LOGERROR("cAuthenticator: received an error from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str()); + return false; + } + + // Header says OK, so receive the rest. + // Go past header, double \n means end of headers + char c = 0; + while (ss.good()) + { + while (c != '\n') + { + ss.get(c); + } + ss.get(c); + if( c == '\n' || c == '\r' || ss.peek() == '\r' || ss.peek() == '\n' ) + break; + } + if (!ss.good()) + { + LOGERROR("cAuthenticator: error while parsing response body from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str()); + return false; + } + + std::string Result; + ss >> Result; + LOGINFO("Got result: %s", Result.c_str()); + if (Result.compare("YES") == 0) + { + LOGINFO("Result was \"YES\", so player is authenticated!"); + return true; + } + LOGINFO("Result was \"%s\", so player is NOT authenticated!", Result.c_str()); + return false; +} + + + + diff --git a/source/cAuthenticator.h b/source/cAuthenticator.h index ba75e8eb3..0d69e930e 100644 --- a/source/cAuthenticator.h +++ b/source/cAuthenticator.h @@ -1,85 +1,85 @@ - -// cAuthenticator.h - -// Interfaces to the cAuthenticator class representing the thread that authenticates users against the official MC server -// Authentication prevents "hackers" from joining with an arbitrary username (possibly impersonating the server admins) -// For more info, see http://wiki.vg/Session#Server_operation -// In MCS, authentication is implemented as a single thread that receives queued auth requests and dispatches them one by one. - - - - - -#pragma once -#ifndef CAUTHENTICATOR_H_INCLUDED -#define CAUTHENTICATOR_H_INCLUDED - -#include "cIsThread.h" - - - - - -// fwd: "cRoot.h" -class cRoot; - - - - - -class cAuthenticator : - public cIsThread -{ - typedef cIsThread super; - -public: - cAuthenticator(void); - ~cAuthenticator(); - - /// (Re-)read server and address from INI: - void ReadINI(void); - - /// Queues a request for authenticating a user. If the auth fails, the user is kicked - void Authenticate(int a_ClientID, const AString & a_UserName, const AString & a_ServerHash); - - // Stops the authenticator thread - void Stop(void); - -private: - - class cUser - { - public: - int mClientID; - AString mName; - AString mServerHash; - - cUser(int a_ClientID, const AString & a_Name, const AString & a_ServerHash) : mClientID(a_ClientID), mName(a_Name), mServerHash(a_ServerHash) {} - } ; - - typedef std::deque cUserList; - - cCriticalSection m_CS; - cUserList m_Queue; - cEvent m_QueueNonempty; - - AString m_Server; - AString m_Address; - bool m_ShouldAuthenticate; - - // cIsThread override: - virtual void Execute(void) override; - - // Returns true if the user authenticated okay, false on error; iLevel is the recursion deptht (bails out if too deep) - bool AuthFromAddress(const AString & a_Server, const AString & a_Address, const AString & a_UserName, int a_Level = 1); -}; - - - - - -#endif // CAUTHENTICATOR_H_INCLUDED - - - - + +// cAuthenticator.h + +// Interfaces to the cAuthenticator class representing the thread that authenticates users against the official MC server +// Authentication prevents "hackers" from joining with an arbitrary username (possibly impersonating the server admins) +// For more info, see http://wiki.vg/Session#Server_operation +// In MCS, authentication is implemented as a single thread that receives queued auth requests and dispatches them one by one. + + + + + +#pragma once +#ifndef CAUTHENTICATOR_H_INCLUDED +#define CAUTHENTICATOR_H_INCLUDED + +#include "cIsThread.h" + + + + + +// fwd: "cRoot.h" +class cRoot; + + + + + +class cAuthenticator : + public cIsThread +{ + typedef cIsThread super; + +public: + cAuthenticator(void); + ~cAuthenticator(); + + /// (Re-)read server and address from INI: + void ReadINI(void); + + /// Queues a request for authenticating a user. If the auth fails, the user is kicked + void Authenticate(int a_ClientID, const AString & a_UserName, const AString & a_ServerHash); + + // Stops the authenticator thread + void Stop(void); + +private: + + class cUser + { + public: + int mClientID; + AString mName; + AString mServerHash; + + cUser(int a_ClientID, const AString & a_Name, const AString & a_ServerHash) : mClientID(a_ClientID), mName(a_Name), mServerHash(a_ServerHash) {} + } ; + + typedef std::deque cUserList; + + cCriticalSection m_CS; + cUserList m_Queue; + cEvent m_QueueNonempty; + + AString m_Server; + AString m_Address; + bool m_ShouldAuthenticate; + + // cIsThread override: + virtual void Execute(void) override; + + // Returns true if the user authenticated okay, false on error; iLevel is the recursion deptht (bails out if too deep) + bool AuthFromAddress(const AString & a_Server, const AString & a_Address, const AString & a_UserName, int a_Level = 1); +}; + + + + + +#endif // CAUTHENTICATOR_H_INCLUDED + + + + diff --git a/source/cBlockEntity.h b/source/cBlockEntity.h index 8a9e51f56..0a6494ec6 100644 --- a/source/cBlockEntity.h +++ b/source/cBlockEntity.h @@ -1,93 +1,93 @@ - -#pragma once - -#include "cClientHandle.h" -#include "cWorld.h" - - - - - -#ifndef _WIN32 -#include "BlockID.h" -#else -enum ENUM_BLOCK_ID; -#endif - - - - - -namespace Json -{ - class Value; -}; - -class cPlayer; -class cWorld; -class cPacket; - - - - - -class cBlockEntity -{ -protected: - cBlockEntity(ENUM_BLOCK_ID a_BlockType, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) - : m_PosX( a_BlockX ) - , m_PosY( a_BlockY ) - , m_PosZ( a_BlockZ ) - , m_BlockType( a_BlockType ) - , m_World( a_World ) - {} -public: - virtual ~cBlockEntity() {}; - virtual void Destroy() {}; - - // Position, in absolute block coordinates: - int GetPosX() { return m_PosX; } - int GetPosY() { return m_PosY; } - int GetPosZ() { return m_PosZ; } - - ENUM_BLOCK_ID GetBlockType() { return m_BlockType; } - - cWorld * GetWorld(void) const {return m_World; } - - virtual void SaveToJson (Json::Value & a_Value ) = 0; - - virtual void UsedBy( cPlayer * a_Player ) = 0; - - void SendTo( cClientHandle* a_Client ) - { - std::auto_ptr Packet(GetPacket()); - if (Packet.get() == NULL) - { - return; - } - if ( a_Client != NULL ) - { - a_Client->Send(*(Packet.get())); - } - else // broadcast to all chunk clients - { - m_World->BroadcastToChunkOfBlock(m_PosX, m_PosY, m_PosZ, Packet.get()); - } - } - - /// Returns the packet to send to clients to represent this entity; NULL if no packet needed; caller is supposed to delete the packet - virtual cPacket * GetPacket(void) {return NULL; } - -protected: - int m_PosX; // Position in absolute block coordinates - int m_PosY; - int m_PosZ; - - ENUM_BLOCK_ID m_BlockType; - - cWorld * m_World; -}; - - - - + +#pragma once + +#include "cClientHandle.h" +#include "cWorld.h" + + + + + +#ifndef _WIN32 +#include "BlockID.h" +#else +enum ENUM_BLOCK_ID; +#endif + + + + + +namespace Json +{ + class Value; +}; + +class cPlayer; +class cWorld; +class cPacket; + + + + + +class cBlockEntity +{ +protected: + cBlockEntity(ENUM_BLOCK_ID a_BlockType, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) + : m_PosX( a_BlockX ) + , m_PosY( a_BlockY ) + , m_PosZ( a_BlockZ ) + , m_BlockType( a_BlockType ) + , m_World( a_World ) + {} +public: + virtual ~cBlockEntity() {}; + virtual void Destroy() {}; + + // Position, in absolute block coordinates: + int GetPosX() { return m_PosX; } + int GetPosY() { return m_PosY; } + int GetPosZ() { return m_PosZ; } + + ENUM_BLOCK_ID GetBlockType() { return m_BlockType; } + + cWorld * GetWorld(void) const {return m_World; } + + virtual void SaveToJson (Json::Value & a_Value ) = 0; + + virtual void UsedBy( cPlayer * a_Player ) = 0; + + void SendTo( cClientHandle* a_Client ) + { + std::auto_ptr Packet(GetPacket()); + if (Packet.get() == NULL) + { + return; + } + if ( a_Client != NULL ) + { + a_Client->Send(*(Packet.get())); + } + else // broadcast to all chunk clients + { + m_World->BroadcastToChunkOfBlock(m_PosX, m_PosY, m_PosZ, Packet.get()); + } + } + + /// Returns the packet to send to clients to represent this entity; NULL if no packet needed; caller is supposed to delete the packet + virtual cPacket * GetPacket(void) {return NULL; } + +protected: + int m_PosX; // Position in absolute block coordinates + int m_PosY; + int m_PosZ; + + ENUM_BLOCK_ID m_BlockType; + + cWorld * m_World; +}; + + + + diff --git a/source/cBlockToPickup.cpp b/source/cBlockToPickup.cpp index ceda2b115..8089320e7 100644 --- a/source/cBlockToPickup.cpp +++ b/source/cBlockToPickup.cpp @@ -1,323 +1,323 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cBlockToPickup.h" -#include "Defines.h" -#include "BlockID.h" -#include "MersenneTwister.h" - - - - - -static void AddRandomDrop(cItems & a_Drops, MTRand & r1, int a_OneInNChance, ENUM_ITEM_ID a_ItemID) -{ - if ((r1.randInt(16 * a_OneInNChance - 1) / 16) != 0) - { - return; - } - a_Drops.push_back(cItem(a_ItemID, 1)); -} - - - - - -void cBlockToPickup::ToPickup(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cItem & a_UsedItem, cItems & a_Drops) -{ - MTRand r1; - - switch (a_BlockType) - { - // Blocks that always drop themselves as the only item, no matter what tool; copy damage from meta: - case E_BLOCK_LOG: - case E_BLOCK_PLANKS: - case E_BLOCK_WOOL: - { - a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1, a_BlockMeta)); - return; - } - - - // Blocks that always drop themselves as the only item, no matter what tool, set damage value zero: - case E_BLOCK_DIRT: - case E_BLOCK_SAPLING: - case E_BLOCK_SAND: - case E_BLOCK_TORCH: - case E_BLOCK_YELLOW_FLOWER: - case E_BLOCK_RED_ROSE: - case E_BLOCK_BROWN_MUSHROOM: - case E_BLOCK_RED_MUSHROOM: - case E_BLOCK_TNT: - case E_BLOCK_CRAFTING_TABLE: - case E_BLOCK_FURNACE: - case E_BLOCK_CACTUS: - case E_BLOCK_REDSTONE_TORCH_OFF: - case E_BLOCK_POWERED_RAIL: - case E_BLOCK_DETECTOR_RAIL: - case E_BLOCK_RAIL: - case E_BLOCK_LADDER: - case E_BLOCK_LEVER: - case E_BLOCK_WOODEN_PRESSURE_PLATE: - case E_BLOCK_STONE_BUTTON: - case E_BLOCK_JUKEBOX: - case E_BLOCK_FENCE: - case E_BLOCK_FENCE_GATE: - case E_BLOCK_PUMPKIN: - case E_BLOCK_NETHERRACK: - case E_BLOCK_SOULSAND: - case E_BLOCK_JACK_O_LANTERN: - case E_BLOCK_TRAPDOOR: - { - a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1, 0)); - return; - } - - - // Blocks that always drop a single item, no matter what tool: - case E_BLOCK_SIGN_POST: - case E_BLOCK_WALLSIGN: a_Drops.push_back(cItem(E_ITEM_SIGN, 1)); return; - case E_BLOCK_REDSTONE_WIRE: a_Drops.push_back(cItem(E_ITEM_REDSTONE_DUST, 1)); return; - case E_BLOCK_GLOWSTONE: a_Drops.push_back(cItem(E_ITEM_GLOWSTONE_DUST, 1)); return; - case E_BLOCK_REDSTONE_REPEATER_OFF: - case E_BLOCK_REDSTONE_REPEATER_ON: a_Drops.push_back(cItem(E_ITEM_REDSTONE_REPEATER, 1)); return; - case E_BLOCK_COBWEB: a_Drops.push_back(cItem(E_ITEM_STRING, 1)); return; - case E_BLOCK_FARMLAND: - case E_BLOCK_GRASS: a_Drops.push_back(cItem(E_ITEM_DIRT, 1)); return; - case E_BLOCK_LIT_FURNACE: a_Drops.push_back(cItem(E_ITEM_FURNACE, 1)); return; - case E_BLOCK_SUGARCANE: a_Drops.push_back(cItem(E_ITEM_SUGARCANE, 1)); return; - case E_BLOCK_PUMPKIN_STEM: a_Drops.push_back(cItem(E_ITEM_PUMPKIN_SEEDS, 1)); return; - case E_BLOCK_MELON_STEM: a_Drops.push_back(cItem(E_ITEM_MELON_SEEDS, 1)); return; - - - // Doors seem to need their meta set to 1 - case E_BLOCK_WOODEN_DOOR: a_Drops.push_back(cItem(E_ITEM_WOODEN_DOOR, 1, 1)); return; - case E_BLOCK_IRON_DOOR: a_Drops.push_back(cItem(E_ITEM_IRON_DOOR, 1, 1)); return; - - - //////////////////////// - // Ores: - - // Coal ore requires a pickaxe: - case E_BLOCK_COAL_ORE: - { - if (ItemCategory::IsPickaxe(a_UsedItem.m_ItemID)) - { - a_Drops.push_back(cItem(E_ITEM_COAL, 1)); - } - return; - } - - // Iron ore requires a stone or better pickaxe: - case E_BLOCK_IRON_ORE: - { - if ( - (a_UsedItem.m_ItemID == E_ITEM_STONE_PICKAXE) || - (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) || - (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) - ) - { - a_Drops.push_back(cItem(E_ITEM_IRON_ORE, 1)); - } - return; - } - - // Gold and diamond ores require an iron or better pickaxe: - case E_BLOCK_GOLD_ORE: - case E_BLOCK_DIAMOND_ORE: - { - if ( - (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) || - (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) - ) - { - a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1)); - } - return; - } - - // Obsidian require a diamond pickaxe: - case E_BLOCK_OBSIDIAN: - { - if (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) - { - a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1)); - } - return; - } - - // Redstone requires an iron or better pickaxe: - case E_BLOCK_REDSTONE_ORE_GLOWING: - case E_BLOCK_REDSTONE_ORE: - { - if ( - (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) || - (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) - ) - { - a_Drops.push_back(cItem(E_ITEM_REDSTONE_DUST, 4 + (short)r1.randInt(1))); - } - return; - } - - // Lapis ore requires a stone or better pickaxe: - case E_BLOCK_LAPIS_ORE: - { - if ( - (a_UsedItem.m_ItemID == E_ITEM_STONE_PICKAXE) || - (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) || - (a_UsedItem.m_ItemID == E_ITEM_GOLD_PICKAXE) || - (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) - ) - { - a_Drops.push_back(cItem(E_ITEM_DYE, 4 + (short)r1.randInt(4), E_META_DYE_BLUE)); - } - return; - } - - - //////////////////////// - // Resource blocks: - - // Iron and lapis blocks require a stone or better pickaxe: - case E_BLOCK_IRON_BLOCK: - case E_BLOCK_LAPIS_BLOCK: - { - if ( - (a_UsedItem.m_ItemID == E_ITEM_STONE_PICKAXE) || - (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) || - (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) - ) - { - a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1)); - } - return; - } - - // Diamond and gold blocks require an iron or better pickaxe: - case E_BLOCK_DIAMOND_BLOCK: - { - if ( - (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) || - (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) - ) - { - a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1)); - } - } - - - // These blocks require a pickaxe to drop themselves: - case E_BLOCK_COBBLESTONE: - case E_BLOCK_BRICK: - case E_BLOCK_NETHER_BRICK: - case E_BLOCK_MOSSY_COBBLESTONE: - case E_BLOCK_STONE_SLAB: - case E_BLOCK_COBBLESTONE_STAIRS: - case E_BLOCK_STONE_BRICK_STAIRS: - case E_BLOCK_NETHER_BRICK_STAIRS: - case E_BLOCK_SANDSTONE_STAIRS: - case E_BLOCK_SANDSTONE: - case E_BLOCK_STONE_PRESSURE_PLATE: - { - if (ItemCategory::IsPickaxe(a_UsedItem.m_ItemID)) - { - a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1)); - } - return; - } - - - // Stone requires a pickaxe to drop cobblestone: - case E_BLOCK_STONE: - { - if (ItemCategory::IsPickaxe(a_UsedItem.m_ItemID)) - { - a_Drops.push_back(cItem(E_ITEM_COBBLESTONE, 1)); - } - return; - } - - - // Snow requires a shovel to harvest: - case E_BLOCK_SNOW: - { - if (ItemCategory::IsShovel(a_UsedItem.m_ItemID)) - { - a_Drops.push_back(cItem(E_ITEM_SNOWBALL, 1)); - } - return; - } - - - // Leaves require shears for harvesting and have a chance of dropping a sapling and a red apple: - case E_BLOCK_LEAVES: - { - if (a_UsedItem.m_ItemID == E_ITEM_SHEARS) - { - a_Drops.push_back(cItem(E_ITEM_LEAVES, 1)); - } - else - { - AddRandomDrop(a_Drops, r1, 5, E_ITEM_SAPLING); - AddRandomDrop(a_Drops, r1, 200, E_ITEM_APPLE); - } - return; - } - - - // Crops drop a wheat and possibly another seeds when ripe; always drop at least a single seed - case E_BLOCK_CROPS: - { - if (a_BlockMeta == 7) - { - AddRandomDrop(a_Drops, r1, 3, E_ITEM_SEEDS); - a_Drops.push_back(cItem(E_ITEM_WHEAT, 1)); - } - a_Drops.push_back(cItem(E_ITEM_SEEDS, 1)); - return; - } - - - // Vines drop only with shears, otherwise they are destroyed - case E_BLOCK_VINES: - { - if (a_UsedItem.m_ItemID == E_ITEM_SHEARS) - { - a_Drops.push_back(cItem(E_ITEM_VINES, 1)); - } - return; - } - - - // Snow drops only when using a shovel - case E_BLOCK_SNOW_BLOCK: - { - if (ItemCategory::IsShovel(a_UsedItem.m_ItemID)) - { - a_Drops.push_back(cItem(E_ITEM_SNOWBALL, 4, 0)); return; - } - return; - } - - - // Random multi-drop blocks: - case E_BLOCK_TALL_GRASS: a_Drops.push_back(cItem(E_ITEM_SEEDS, (short)r1.randInt(3) / 2, 1)); return; - case E_BLOCK_MELON: a_Drops.push_back(cItem(E_ITEM_MELON_SLICE, 3 + (short)r1.randInt(2), 1)); return; - - - // Fixed multi-drop blocks: - case E_BLOCK_DOUBLE_STONE_SLAB: a_Drops.push_back(cItem(E_ITEM_STONE_SLAB, 2, 0)); return; - case E_BLOCK_DOUBLE_WOODEN_SLAB: a_Drops.push_back(cItem(E_ITEM_STEP, 2, 0)); return; - - default: - { - return; - } - } // switch (a_BlockType) -} - - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cBlockToPickup.h" +#include "Defines.h" +#include "BlockID.h" +#include "MersenneTwister.h" + + + + + +static void AddRandomDrop(cItems & a_Drops, MTRand & r1, int a_OneInNChance, ENUM_ITEM_ID a_ItemID) +{ + if ((r1.randInt(16 * a_OneInNChance - 1) / 16) != 0) + { + return; + } + a_Drops.push_back(cItem(a_ItemID, 1)); +} + + + + + +void cBlockToPickup::ToPickup(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cItem & a_UsedItem, cItems & a_Drops) +{ + MTRand r1; + + switch (a_BlockType) + { + // Blocks that always drop themselves as the only item, no matter what tool; copy damage from meta: + case E_BLOCK_LOG: + case E_BLOCK_PLANKS: + case E_BLOCK_WOOL: + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1, a_BlockMeta)); + return; + } + + + // Blocks that always drop themselves as the only item, no matter what tool, set damage value zero: + case E_BLOCK_DIRT: + case E_BLOCK_SAPLING: + case E_BLOCK_SAND: + case E_BLOCK_TORCH: + case E_BLOCK_YELLOW_FLOWER: + case E_BLOCK_RED_ROSE: + case E_BLOCK_BROWN_MUSHROOM: + case E_BLOCK_RED_MUSHROOM: + case E_BLOCK_TNT: + case E_BLOCK_CRAFTING_TABLE: + case E_BLOCK_FURNACE: + case E_BLOCK_CACTUS: + case E_BLOCK_REDSTONE_TORCH_OFF: + case E_BLOCK_POWERED_RAIL: + case E_BLOCK_DETECTOR_RAIL: + case E_BLOCK_RAIL: + case E_BLOCK_LADDER: + case E_BLOCK_LEVER: + case E_BLOCK_WOODEN_PRESSURE_PLATE: + case E_BLOCK_STONE_BUTTON: + case E_BLOCK_JUKEBOX: + case E_BLOCK_FENCE: + case E_BLOCK_FENCE_GATE: + case E_BLOCK_PUMPKIN: + case E_BLOCK_NETHERRACK: + case E_BLOCK_SOULSAND: + case E_BLOCK_JACK_O_LANTERN: + case E_BLOCK_TRAPDOOR: + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1, 0)); + return; + } + + + // Blocks that always drop a single item, no matter what tool: + case E_BLOCK_SIGN_POST: + case E_BLOCK_WALLSIGN: a_Drops.push_back(cItem(E_ITEM_SIGN, 1)); return; + case E_BLOCK_REDSTONE_WIRE: a_Drops.push_back(cItem(E_ITEM_REDSTONE_DUST, 1)); return; + case E_BLOCK_GLOWSTONE: a_Drops.push_back(cItem(E_ITEM_GLOWSTONE_DUST, 1)); return; + case E_BLOCK_REDSTONE_REPEATER_OFF: + case E_BLOCK_REDSTONE_REPEATER_ON: a_Drops.push_back(cItem(E_ITEM_REDSTONE_REPEATER, 1)); return; + case E_BLOCK_COBWEB: a_Drops.push_back(cItem(E_ITEM_STRING, 1)); return; + case E_BLOCK_FARMLAND: + case E_BLOCK_GRASS: a_Drops.push_back(cItem(E_ITEM_DIRT, 1)); return; + case E_BLOCK_LIT_FURNACE: a_Drops.push_back(cItem(E_ITEM_FURNACE, 1)); return; + case E_BLOCK_SUGARCANE: a_Drops.push_back(cItem(E_ITEM_SUGARCANE, 1)); return; + case E_BLOCK_PUMPKIN_STEM: a_Drops.push_back(cItem(E_ITEM_PUMPKIN_SEEDS, 1)); return; + case E_BLOCK_MELON_STEM: a_Drops.push_back(cItem(E_ITEM_MELON_SEEDS, 1)); return; + + + // Doors seem to need their meta set to 1 + case E_BLOCK_WOODEN_DOOR: a_Drops.push_back(cItem(E_ITEM_WOODEN_DOOR, 1, 1)); return; + case E_BLOCK_IRON_DOOR: a_Drops.push_back(cItem(E_ITEM_IRON_DOOR, 1, 1)); return; + + + //////////////////////// + // Ores: + + // Coal ore requires a pickaxe: + case E_BLOCK_COAL_ORE: + { + if (ItemCategory::IsPickaxe(a_UsedItem.m_ItemID)) + { + a_Drops.push_back(cItem(E_ITEM_COAL, 1)); + } + return; + } + + // Iron ore requires a stone or better pickaxe: + case E_BLOCK_IRON_ORE: + { + if ( + (a_UsedItem.m_ItemID == E_ITEM_STONE_PICKAXE) || + (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) || + (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) + ) + { + a_Drops.push_back(cItem(E_ITEM_IRON_ORE, 1)); + } + return; + } + + // Gold and diamond ores require an iron or better pickaxe: + case E_BLOCK_GOLD_ORE: + case E_BLOCK_DIAMOND_ORE: + { + if ( + (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) || + (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) + ) + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1)); + } + return; + } + + // Obsidian require a diamond pickaxe: + case E_BLOCK_OBSIDIAN: + { + if (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1)); + } + return; + } + + // Redstone requires an iron or better pickaxe: + case E_BLOCK_REDSTONE_ORE_GLOWING: + case E_BLOCK_REDSTONE_ORE: + { + if ( + (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) || + (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) + ) + { + a_Drops.push_back(cItem(E_ITEM_REDSTONE_DUST, 4 + (short)r1.randInt(1))); + } + return; + } + + // Lapis ore requires a stone or better pickaxe: + case E_BLOCK_LAPIS_ORE: + { + if ( + (a_UsedItem.m_ItemID == E_ITEM_STONE_PICKAXE) || + (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) || + (a_UsedItem.m_ItemID == E_ITEM_GOLD_PICKAXE) || + (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) + ) + { + a_Drops.push_back(cItem(E_ITEM_DYE, 4 + (short)r1.randInt(4), E_META_DYE_BLUE)); + } + return; + } + + + //////////////////////// + // Resource blocks: + + // Iron and lapis blocks require a stone or better pickaxe: + case E_BLOCK_IRON_BLOCK: + case E_BLOCK_LAPIS_BLOCK: + { + if ( + (a_UsedItem.m_ItemID == E_ITEM_STONE_PICKAXE) || + (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) || + (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) + ) + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1)); + } + return; + } + + // Diamond and gold blocks require an iron or better pickaxe: + case E_BLOCK_DIAMOND_BLOCK: + { + if ( + (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) || + (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) + ) + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1)); + } + } + + + // These blocks require a pickaxe to drop themselves: + case E_BLOCK_COBBLESTONE: + case E_BLOCK_BRICK: + case E_BLOCK_NETHER_BRICK: + case E_BLOCK_MOSSY_COBBLESTONE: + case E_BLOCK_STONE_SLAB: + case E_BLOCK_COBBLESTONE_STAIRS: + case E_BLOCK_STONE_BRICK_STAIRS: + case E_BLOCK_NETHER_BRICK_STAIRS: + case E_BLOCK_SANDSTONE_STAIRS: + case E_BLOCK_SANDSTONE: + case E_BLOCK_STONE_PRESSURE_PLATE: + { + if (ItemCategory::IsPickaxe(a_UsedItem.m_ItemID)) + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1)); + } + return; + } + + + // Stone requires a pickaxe to drop cobblestone: + case E_BLOCK_STONE: + { + if (ItemCategory::IsPickaxe(a_UsedItem.m_ItemID)) + { + a_Drops.push_back(cItem(E_ITEM_COBBLESTONE, 1)); + } + return; + } + + + // Snow requires a shovel to harvest: + case E_BLOCK_SNOW: + { + if (ItemCategory::IsShovel(a_UsedItem.m_ItemID)) + { + a_Drops.push_back(cItem(E_ITEM_SNOWBALL, 1)); + } + return; + } + + + // Leaves require shears for harvesting and have a chance of dropping a sapling and a red apple: + case E_BLOCK_LEAVES: + { + if (a_UsedItem.m_ItemID == E_ITEM_SHEARS) + { + a_Drops.push_back(cItem(E_ITEM_LEAVES, 1)); + } + else + { + AddRandomDrop(a_Drops, r1, 5, E_ITEM_SAPLING); + AddRandomDrop(a_Drops, r1, 200, E_ITEM_APPLE); + } + return; + } + + + // Crops drop a wheat and possibly another seeds when ripe; always drop at least a single seed + case E_BLOCK_CROPS: + { + if (a_BlockMeta == 7) + { + AddRandomDrop(a_Drops, r1, 3, E_ITEM_SEEDS); + a_Drops.push_back(cItem(E_ITEM_WHEAT, 1)); + } + a_Drops.push_back(cItem(E_ITEM_SEEDS, 1)); + return; + } + + + // Vines drop only with shears, otherwise they are destroyed + case E_BLOCK_VINES: + { + if (a_UsedItem.m_ItemID == E_ITEM_SHEARS) + { + a_Drops.push_back(cItem(E_ITEM_VINES, 1)); + } + return; + } + + + // Snow drops only when using a shovel + case E_BLOCK_SNOW_BLOCK: + { + if (ItemCategory::IsShovel(a_UsedItem.m_ItemID)) + { + a_Drops.push_back(cItem(E_ITEM_SNOWBALL, 4, 0)); return; + } + return; + } + + + // Random multi-drop blocks: + case E_BLOCK_TALL_GRASS: a_Drops.push_back(cItem(E_ITEM_SEEDS, (short)r1.randInt(3) / 2, 1)); return; + case E_BLOCK_MELON: a_Drops.push_back(cItem(E_ITEM_MELON_SLICE, 3 + (short)r1.randInt(2), 1)); return; + + + // Fixed multi-drop blocks: + case E_BLOCK_DOUBLE_STONE_SLAB: a_Drops.push_back(cItem(E_ITEM_STONE_SLAB, 2, 0)); return; + case E_BLOCK_DOUBLE_WOODEN_SLAB: a_Drops.push_back(cItem(E_ITEM_STEP, 2, 0)); return; + + default: + { + return; + } + } // switch (a_BlockType) +} + + + + + diff --git a/source/cBlockToPickup.h b/source/cBlockToPickup.h index 195f96bf6..559e0a052 100644 --- a/source/cBlockToPickup.h +++ b/source/cBlockToPickup.h @@ -1,28 +1,28 @@ -#pragma once - -#ifndef _WIN32 - #include "BlockID.h" -#else - enum ENUM_ITEM_ID; -#endif - -#include "cItem.h" - - - - - -class cBlockToPickup // tolua_export -{ // tolua_export -public: - /// For a given block and tool, returns the list of drops generated - static void ToPickup(BLOCKTYPE a_BlockID, NIBBLETYPE a_BlockMeta, const cItem & a_UsedItem, cItems & a_Drops); // tolua_export - - /// Returns true if the tool used for the block is the right one for the job. cClientHandle uses this to determine whether to decrease tool durability twice as much - static bool IsRightTool(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, ENUM_ITEM_ID a_UsedTool); // tolua_export - -}; // tolua_export - - - - +#pragma once + +#ifndef _WIN32 + #include "BlockID.h" +#else + enum ENUM_ITEM_ID; +#endif + +#include "cItem.h" + + + + + +class cBlockToPickup // tolua_export +{ // tolua_export +public: + /// For a given block and tool, returns the list of drops generated + static void ToPickup(BLOCKTYPE a_BlockID, NIBBLETYPE a_BlockMeta, const cItem & a_UsedItem, cItems & a_Drops); // tolua_export + + /// Returns true if the tool used for the block is the right one for the job. cClientHandle uses this to determine whether to decrease tool durability twice as much + static bool IsRightTool(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, ENUM_ITEM_ID a_UsedTool); // tolua_export + +}; // tolua_export + + + + diff --git a/source/cBlockingTCPLink.cpp b/source/cBlockingTCPLink.cpp index da82f3801..741eb328c 100644 --- a/source/cBlockingTCPLink.cpp +++ b/source/cBlockingTCPLink.cpp @@ -1,150 +1,150 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cBlockingTCPLink.h" -#include "packets/cPacket.h" - - - - - -#ifdef _WIN32 - #define MSG_NOSIGNAL (0) -#endif -#ifdef __MACH__ - #define MSG_NOSIGNAL (0) -#endif - - - - - -cBlockingTCPLink::cBlockingTCPLink(void) -{ -} - - - - - -cBlockingTCPLink::~cBlockingTCPLink() -{ - CloseSocket(); -} - - - - - -void cBlockingTCPLink::CloseSocket() -{ - if (!m_Socket.IsValid()) - { - m_Socket.CloseSocket(); - } -} - - - - - -bool cBlockingTCPLink::Connect(const char * iAddress, unsigned int iPort) -{ - ASSERT(!m_Socket.IsValid()); - if (m_Socket.IsValid()) - { - LOGWARN("WARNING: cTCPLink Connect() called while still connected."); - m_Socket.CloseSocket(); - } - - struct hostent *hp; - unsigned int addr; - struct sockaddr_in server; - - m_Socket = socket(AF_INET, SOCK_STREAM, 0); - if (!m_Socket.IsValid()) - { - LOGERROR("cTCPLink: Cannot create a socket"); - return false; - } - - addr = inet_addr(iAddress); - hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET); - if (hp == NULL) - { - //LOGWARN("cTCPLink: gethostbyaddr returned NULL"); - hp = gethostbyname(iAddress); - if (hp == NULL) - { - LOGWARN("cTCPLink: Could not resolve %s", iAddress); - CloseSocket(); - return false; - } - } - - server.sin_addr.s_addr = *((unsigned long *)hp->h_addr); - server.sin_family = AF_INET; - server.sin_port = htons( (unsigned short)iPort); - if (connect(m_Socket, (struct sockaddr *)&server, sizeof(server))) - { - LOGWARN("cTCPLink: Connection to \"%s:%d\" failed (%s)", iAddress, iPort, cSocket::GetErrorString( cSocket::GetLastError() ).c_str() ); - CloseSocket(); - return false; - } - - return true; -} - - - - - -int cBlockingTCPLink::Send(char * a_Data, unsigned int a_Size, int a_Flags /* = 0 */ ) -{ - ASSERT(m_Socket.IsValid()); - if (!m_Socket.IsValid()) - { - LOGERROR("cBlockingTCPLink: Trying to send data without a valid connection!"); - return -1; - } - return m_Socket.Send(a_Data, a_Size); -} - - - - - -int cBlockingTCPLink::SendMessage( const char* a_Message, int a_Flags /* = 0 */ ) -{ - ASSERT(m_Socket.IsValid()); - if (!m_Socket.IsValid()) - { - LOGWARN("cBlockingTCPLink: Trying to send message without a valid connection!"); - return -1; - } - return m_Socket.Send(a_Message, strlen(a_Message)); -} - - - - - -void cBlockingTCPLink::ReceiveData(AString & oData) -{ - ASSERT(m_Socket.IsValid()); - if (!m_Socket.IsValid()) - { - return; - } - - int Received = 0; - char Buffer[256]; - while ((Received = recv(m_Socket, Buffer, sizeof(Buffer), 0)) > 0) - { - oData.append(Buffer, Received); - } -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cBlockingTCPLink.h" +#include "packets/cPacket.h" + + + + + +#ifdef _WIN32 + #define MSG_NOSIGNAL (0) +#endif +#ifdef __MACH__ + #define MSG_NOSIGNAL (0) +#endif + + + + + +cBlockingTCPLink::cBlockingTCPLink(void) +{ +} + + + + + +cBlockingTCPLink::~cBlockingTCPLink() +{ + CloseSocket(); +} + + + + + +void cBlockingTCPLink::CloseSocket() +{ + if (!m_Socket.IsValid()) + { + m_Socket.CloseSocket(); + } +} + + + + + +bool cBlockingTCPLink::Connect(const char * iAddress, unsigned int iPort) +{ + ASSERT(!m_Socket.IsValid()); + if (m_Socket.IsValid()) + { + LOGWARN("WARNING: cTCPLink Connect() called while still connected."); + m_Socket.CloseSocket(); + } + + struct hostent *hp; + unsigned int addr; + struct sockaddr_in server; + + m_Socket = socket(AF_INET, SOCK_STREAM, 0); + if (!m_Socket.IsValid()) + { + LOGERROR("cTCPLink: Cannot create a socket"); + return false; + } + + addr = inet_addr(iAddress); + hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET); + if (hp == NULL) + { + //LOGWARN("cTCPLink: gethostbyaddr returned NULL"); + hp = gethostbyname(iAddress); + if (hp == NULL) + { + LOGWARN("cTCPLink: Could not resolve %s", iAddress); + CloseSocket(); + return false; + } + } + + server.sin_addr.s_addr = *((unsigned long *)hp->h_addr); + server.sin_family = AF_INET; + server.sin_port = htons( (unsigned short)iPort); + if (connect(m_Socket, (struct sockaddr *)&server, sizeof(server))) + { + LOGWARN("cTCPLink: Connection to \"%s:%d\" failed (%s)", iAddress, iPort, cSocket::GetErrorString( cSocket::GetLastError() ).c_str() ); + CloseSocket(); + return false; + } + + return true; +} + + + + + +int cBlockingTCPLink::Send(char * a_Data, unsigned int a_Size, int a_Flags /* = 0 */ ) +{ + ASSERT(m_Socket.IsValid()); + if (!m_Socket.IsValid()) + { + LOGERROR("cBlockingTCPLink: Trying to send data without a valid connection!"); + return -1; + } + return m_Socket.Send(a_Data, a_Size); +} + + + + + +int cBlockingTCPLink::SendMessage( const char* a_Message, int a_Flags /* = 0 */ ) +{ + ASSERT(m_Socket.IsValid()); + if (!m_Socket.IsValid()) + { + LOGWARN("cBlockingTCPLink: Trying to send message without a valid connection!"); + return -1; + } + return m_Socket.Send(a_Message, strlen(a_Message)); +} + + + + + +void cBlockingTCPLink::ReceiveData(AString & oData) +{ + ASSERT(m_Socket.IsValid()); + if (!m_Socket.IsValid()) + { + return; + } + + int Received = 0; + char Buffer[256]; + while ((Received = recv(m_Socket, Buffer, sizeof(Buffer), 0)) > 0) + { + oData.append(Buffer, Received); + } +} + + + + diff --git a/source/cBlockingTCPLink.h b/source/cBlockingTCPLink.h index ff89f7db3..feba52970 100644 --- a/source/cBlockingTCPLink.h +++ b/source/cBlockingTCPLink.h @@ -1,28 +1,28 @@ - -#pragma once - -#include "cSocket.h" - - - - - -class cBlockingTCPLink //tolua_export -{ //tolua_export -public: //tolua_export - cBlockingTCPLink(void); //tolua_export - ~cBlockingTCPLink(); //tolua_export - - bool Connect( const char* a_Address, unsigned int a_Port ); //tolua_export - int Send( char* a_Data, unsigned int a_Size, int a_Flags = 0 ); //tolua_export - int SendMessage( const char* a_Message, int a_Flags = 0 ); //tolua_export - void CloseSocket(); //tolua_export - void ReceiveData(AString & oData); //tolua_export -protected: - - cSocket m_Socket; -}; //tolua_export - - - - + +#pragma once + +#include "cSocket.h" + + + + + +class cBlockingTCPLink //tolua_export +{ //tolua_export +public: //tolua_export + cBlockingTCPLink(void); //tolua_export + ~cBlockingTCPLink(); //tolua_export + + bool Connect( const char* a_Address, unsigned int a_Port ); //tolua_export + int Send( char* a_Data, unsigned int a_Size, int a_Flags = 0 ); //tolua_export + int SendMessage( const char* a_Message, int a_Flags = 0 ); //tolua_export + void CloseSocket(); //tolua_export + void ReceiveData(AString & oData); //tolua_export +protected: + + cSocket m_Socket; +}; //tolua_export + + + + diff --git a/source/cCavespider.cpp b/source/cCavespider.cpp index 8c2a1ca2c..8d0285674 100644 --- a/source/cCavespider.cpp +++ b/source/cCavespider.cpp @@ -1,59 +1,59 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cCavespider.h" - - - - - -cCavespider::cCavespider() -{ - m_MobType = 59; - GetMonsterConfig("Cavespider"); -} - - - - - -cCavespider::~cCavespider() -{ -} - - - - - -bool cCavespider::IsA( const char* a_EntityType ) -{ - if( strcmp( a_EntityType, "cCavespider" ) == 0 ) return true; - return cMonster::IsA( a_EntityType ); -} - - - - - -void cCavespider::Tick(float a_Dt) -{ - cMonster::Tick(a_Dt); - m_EMPersonality = (GetWorld()->GetWorldTime() < (12000 + 1000) ) ? PASSIVE : AGGRESSIVE; -} - - - - - -void cCavespider::KilledBy( cEntity* a_Killer ) -{ - cItems Drops; - AddRandomDropItem(Drops, 0, 2, E_ITEM_STRING); - AddRandomDropItem(Drops, 0, 1, E_ITEM_SPIDER_EYE); - - cMonster::KilledBy( a_Killer ); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cCavespider.h" + + + + + +cCavespider::cCavespider() +{ + m_MobType = 59; + GetMonsterConfig("Cavespider"); +} + + + + + +cCavespider::~cCavespider() +{ +} + + + + + +bool cCavespider::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cCavespider" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cCavespider::Tick(float a_Dt) +{ + cMonster::Tick(a_Dt); + m_EMPersonality = (GetWorld()->GetWorldTime() < (12000 + 1000) ) ? PASSIVE : AGGRESSIVE; +} + + + + + +void cCavespider::KilledBy( cEntity* a_Killer ) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_STRING); + AddRandomDropItem(Drops, 0, 1, E_ITEM_SPIDER_EYE); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cChatColor.cpp b/source/cChatColor.cpp index 50d9bbc63..228dc7a38 100644 --- a/source/cChatColor.cpp +++ b/source/cChatColor.cpp @@ -1,39 +1,39 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cChatColor.h" - -const std::string cChatColor::Color = "\xa7"; // Old color was "\xc2\xa7" or in other words: "§" -const std::string cChatColor::Delimiter = "\xa7"; -const std::string cChatColor::Black = cChatColor::Color + "0"; -const std::string cChatColor::Navy = cChatColor::Color + "1"; -const std::string cChatColor::Green = cChatColor::Color + "2"; -const std::string cChatColor::Blue = cChatColor::Color + "3"; -const std::string cChatColor::Red = cChatColor::Color + "4"; -const std::string cChatColor::Purple = cChatColor::Color + "5"; -const std::string cChatColor::Gold = cChatColor::Color + "6"; -const std::string cChatColor::LightGray = cChatColor::Color + "7"; -const std::string cChatColor::Gray = cChatColor::Color + "8"; -const std::string cChatColor::DarkPurple = cChatColor::Color + "9"; -const std::string cChatColor::LightGreen = cChatColor::Color + "a"; -const std::string cChatColor::LightBlue = cChatColor::Color + "b"; -const std::string cChatColor::Rose = cChatColor::Color + "c"; -const std::string cChatColor::LightPurple = cChatColor::Color + "d"; -const std::string cChatColor::Yellow = cChatColor::Color + "e"; -const std::string cChatColor::White = cChatColor::Color + "f"; - -const std::string cChatColor::Random = cChatColor::Color + "k"; -const std::string cChatColor::Bold = cChatColor::Color + "l"; -const std::string cChatColor::Strikethrough = cChatColor::Color + "m"; -const std::string cChatColor::Underlined = cChatColor::Color + "n"; -const std::string cChatColor::Italic = cChatColor::Color + "o"; -const std::string cChatColor::Plain = cChatColor::Color + "r"; - -const std::string cChatColor::MakeColor( char a_Color ) -{ - return cChatColor::Color + a_Color; -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cChatColor.h" + +const std::string cChatColor::Color = "\xa7"; // Old color was "\xc2\xa7" or in other words: "§" +const std::string cChatColor::Delimiter = "\xa7"; +const std::string cChatColor::Black = cChatColor::Color + "0"; +const std::string cChatColor::Navy = cChatColor::Color + "1"; +const std::string cChatColor::Green = cChatColor::Color + "2"; +const std::string cChatColor::Blue = cChatColor::Color + "3"; +const std::string cChatColor::Red = cChatColor::Color + "4"; +const std::string cChatColor::Purple = cChatColor::Color + "5"; +const std::string cChatColor::Gold = cChatColor::Color + "6"; +const std::string cChatColor::LightGray = cChatColor::Color + "7"; +const std::string cChatColor::Gray = cChatColor::Color + "8"; +const std::string cChatColor::DarkPurple = cChatColor::Color + "9"; +const std::string cChatColor::LightGreen = cChatColor::Color + "a"; +const std::string cChatColor::LightBlue = cChatColor::Color + "b"; +const std::string cChatColor::Rose = cChatColor::Color + "c"; +const std::string cChatColor::LightPurple = cChatColor::Color + "d"; +const std::string cChatColor::Yellow = cChatColor::Color + "e"; +const std::string cChatColor::White = cChatColor::Color + "f"; + +const std::string cChatColor::Random = cChatColor::Color + "k"; +const std::string cChatColor::Bold = cChatColor::Color + "l"; +const std::string cChatColor::Strikethrough = cChatColor::Color + "m"; +const std::string cChatColor::Underlined = cChatColor::Color + "n"; +const std::string cChatColor::Italic = cChatColor::Color + "o"; +const std::string cChatColor::Plain = cChatColor::Color + "r"; + +const std::string cChatColor::MakeColor( char a_Color ) +{ + return cChatColor::Color + a_Color; +} + + + + diff --git a/source/cChatColor.h b/source/cChatColor.h index 8c12c7e29..85b10f400 100644 --- a/source/cChatColor.h +++ b/source/cChatColor.h @@ -1,43 +1,43 @@ - -#pragma once - - - - - -// tolua_begin -class cChatColor -{ -public: - static const std::string Color; - static const std::string Delimiter; - - static const std::string Black; - static const std::string Navy; - static const std::string Green; - static const std::string Blue; - static const std::string Red; - static const std::string Purple; - static const std::string Gold; - static const std::string LightGray; - static const std::string Gray; - static const std::string DarkPurple; - static const std::string LightGreen; - static const std::string LightBlue; - static const std::string Rose; - static const std::string LightPurple; - static const std::string Yellow; - static const std::string White; - - // Styles ( source: http://wiki.vg/Chat ) - static const std::string Random; - static const std::string Bold; - static const std::string Strikethrough; - static const std::string Underlined; - static const std::string Italic; - static const std::string Plain; - - static const std::string MakeColor( char a_Color ); -}; - -// tolua_end + +#pragma once + + + + + +// tolua_begin +class cChatColor +{ +public: + static const std::string Color; + static const std::string Delimiter; + + static const std::string Black; + static const std::string Navy; + static const std::string Green; + static const std::string Blue; + static const std::string Red; + static const std::string Purple; + static const std::string Gold; + static const std::string LightGray; + static const std::string Gray; + static const std::string DarkPurple; + static const std::string LightGreen; + static const std::string LightBlue; + static const std::string Rose; + static const std::string LightPurple; + static const std::string Yellow; + static const std::string White; + + // Styles ( source: http://wiki.vg/Chat ) + static const std::string Random; + static const std::string Bold; + static const std::string Strikethrough; + static const std::string Underlined; + static const std::string Italic; + static const std::string Plain; + + static const std::string MakeColor( char a_Color ); +}; + +// tolua_end diff --git a/source/cChestEntity.cpp b/source/cChestEntity.cpp index 35fb2894e..d2cc168b0 100644 --- a/source/cChestEntity.cpp +++ b/source/cChestEntity.cpp @@ -1,234 +1,234 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cChestEntity.h" -#include "cItem.h" -#include "cClientHandle.h" -#include "cPlayer.h" -#include "cWindow.h" -#include "cWorld.h" -#include "cRoot.h" -#include "cPickup.h" -#include - - - - - -class cWorld; -class cRoot; - - - - - -cChestEntity::cChestEntity(int a_X, int a_Y, int a_Z, cWorld * a_World) - : cBlockEntity( E_BLOCK_CHEST, a_X, a_Y, a_Z, a_World) - , m_TopChest( false ) - , m_JoinedChest( NULL ) -{ - m_Content = new cItem[ c_ChestHeight * c_ChestWidth ]; -} - - - - - -cChestEntity::~cChestEntity() -{ - if( GetWindow() ) - { - GetWindow()->OwnerDestroyed(); - } - - if( m_Content ) - { - delete [] m_Content; - } -} - - - - - -void cChestEntity::Destroy() -{ - // Drop items - cItems Pickups; - for( int i = 0; i < c_ChestHeight * c_ChestWidth; ++i ) - { - if( !m_Content[i].IsEmpty() ) - { - Pickups.push_back(m_Content[i]); - m_Content[i].Empty(); - } - } - m_World->SpawnItemPickups(Pickups, m_PosX, m_PosY, m_PosZ); - if (m_JoinedChest) - { - m_JoinedChest->RemoveJoinedChest(this); - } -} - - - - - -const cItem * cChestEntity::GetSlot( int a_Slot ) const -{ - if( a_Slot > -1 && a_Slot < c_ChestHeight*c_ChestWidth ) - { - return &m_Content[ a_Slot ]; - } - return 0; -} - - - - - -void cChestEntity::SetSlot( int a_Slot, cItem & a_Item ) -{ - if( a_Slot > -1 && a_Slot < c_ChestHeight*c_ChestWidth ) - { - m_Content[a_Slot] = a_Item; - } -} - - - - - -#define READ(File, Var) \ - if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \ - { \ - LOGERROR("ERROR READING cChestEntity %s FROM FILE (line %d)", #Var, __LINE__); \ - return false; \ - } - - - - - - -bool cChestEntity::LoadFromJson( const Json::Value& a_Value ) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - Json::Value AllSlots = a_Value.get("Slots", 0); - int SlotIdx = 0; - for( Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr ) - { - cItem Item; - Item.FromJson( *itr ); - SetSlot( SlotIdx, Item ); - SlotIdx++; - } - return true; -} - - - - - -void cChestEntity::SaveToJson( Json::Value& a_Value ) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - unsigned int NumSlots = c_ChestHeight*c_ChestWidth; - Json::Value AllSlots; - for(unsigned int i = 0; i < NumSlots; i++) - { - Json::Value Slot; - const cItem * Item = GetSlot( i ); - if( Item ) Item->GetJson( Slot ); - AllSlots.append( Slot ); - } - a_Value["Slots"] = AllSlots; -} - - - - - -void cChestEntity::SendTo( cClientHandle* a_Client, cServer* a_Server ) -{ - (void)a_Client; - (void)a_Server; - return; -} - - - - - -void cChestEntity::UsedBy( cPlayer * a_Player ) -{ - if( !GetWindow() ) - { - cWindow* Window = new cWindow( this, true ); - Window->SetSlots( GetContents(), GetChestHeight()*c_ChestWidth ); - Window->SetWindowID( 1 ); - Window->SetWindowType( cWindow::Chest ); - Window->SetWindowTitle("UberChest"); - Window->GetOwner()->SetEntity(this); - OpenWindow( Window ); - } - if ( GetWindow() ) - { - if( a_Player->GetWindow() != GetWindow() ) - { - a_Player->OpenWindow( GetWindow() ); - GetWindow()->SendWholeWindow( a_Player->GetClientHandle() ); - } - } - cPacket_BlockAction ChestOpen; - ChestOpen.m_PosX = GetPosX(); - ChestOpen.m_PosY = (short)GetPosY(); - ChestOpen.m_PosZ = GetPosZ(); - ChestOpen.m_Byte1 = (char)1; - ChestOpen.m_Byte2 = (char)1; - m_World->BroadcastToChunkOfBlock(m_PosX, m_PosY, m_PosZ, &ChestOpen); - - // This is rather a hack - // Instead of marking the chunk as dirty upon chest contents change, we mark it dirty now - // We cannot properly detect contents change, but such a change doesn't happen without a player opening the chest first. - // The few false positives aren't much to worry about - int ChunkX, ChunkY = 0, ChunkZ; - cChunkDef::BlockToChunk(m_PosX, m_PosY, m_PosZ, ChunkX, ChunkZ); - m_World->MarkChunkDirty(ChunkX, ChunkY, ChunkZ); -} - - - - - -cItem *cChestEntity::GetContents(bool a_OnlyThis) -{ - if (m_JoinedChest && !a_OnlyThis) - { - cItem *Combined = new cItem[GetChestHeight()*c_ChestWidth]; - int i; - cItem *first = (m_TopChest) ? GetContents(true) : m_JoinedChest->GetContents(true); - cItem *second = (!m_TopChest) ? GetContents(true) : m_JoinedChest->GetContents(true); - for (i=0; i < GetChestHeight()*c_ChestWidth; i++) - { - int index = i % c_ChestHeight*c_ChestWidth; - if (i < c_ChestHeight*c_ChestWidth) - Combined[index] = first[index]; - else - Combined[index] = second[index]; - } - return Combined; - } - else - return m_Content; -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cChestEntity.h" +#include "cItem.h" +#include "cClientHandle.h" +#include "cPlayer.h" +#include "cWindow.h" +#include "cWorld.h" +#include "cRoot.h" +#include "cPickup.h" +#include + + + + + +class cWorld; +class cRoot; + + + + + +cChestEntity::cChestEntity(int a_X, int a_Y, int a_Z, cWorld * a_World) + : cBlockEntity( E_BLOCK_CHEST, a_X, a_Y, a_Z, a_World) + , m_TopChest( false ) + , m_JoinedChest( NULL ) +{ + m_Content = new cItem[ c_ChestHeight * c_ChestWidth ]; +} + + + + + +cChestEntity::~cChestEntity() +{ + if( GetWindow() ) + { + GetWindow()->OwnerDestroyed(); + } + + if( m_Content ) + { + delete [] m_Content; + } +} + + + + + +void cChestEntity::Destroy() +{ + // Drop items + cItems Pickups; + for( int i = 0; i < c_ChestHeight * c_ChestWidth; ++i ) + { + if( !m_Content[i].IsEmpty() ) + { + Pickups.push_back(m_Content[i]); + m_Content[i].Empty(); + } + } + m_World->SpawnItemPickups(Pickups, m_PosX, m_PosY, m_PosZ); + if (m_JoinedChest) + { + m_JoinedChest->RemoveJoinedChest(this); + } +} + + + + + +const cItem * cChestEntity::GetSlot( int a_Slot ) const +{ + if( a_Slot > -1 && a_Slot < c_ChestHeight*c_ChestWidth ) + { + return &m_Content[ a_Slot ]; + } + return 0; +} + + + + + +void cChestEntity::SetSlot( int a_Slot, cItem & a_Item ) +{ + if( a_Slot > -1 && a_Slot < c_ChestHeight*c_ChestWidth ) + { + m_Content[a_Slot] = a_Item; + } +} + + + + + +#define READ(File, Var) \ + if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \ + { \ + LOGERROR("ERROR READING cChestEntity %s FROM FILE (line %d)", #Var, __LINE__); \ + return false; \ + } + + + + + + +bool cChestEntity::LoadFromJson( const Json::Value& a_Value ) +{ + m_PosX = a_Value.get("x", 0).asInt(); + m_PosY = a_Value.get("y", 0).asInt(); + m_PosZ = a_Value.get("z", 0).asInt(); + + Json::Value AllSlots = a_Value.get("Slots", 0); + int SlotIdx = 0; + for( Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr ) + { + cItem Item; + Item.FromJson( *itr ); + SetSlot( SlotIdx, Item ); + SlotIdx++; + } + return true; +} + + + + + +void cChestEntity::SaveToJson( Json::Value& a_Value ) +{ + a_Value["x"] = m_PosX; + a_Value["y"] = m_PosY; + a_Value["z"] = m_PosZ; + + unsigned int NumSlots = c_ChestHeight*c_ChestWidth; + Json::Value AllSlots; + for(unsigned int i = 0; i < NumSlots; i++) + { + Json::Value Slot; + const cItem * Item = GetSlot( i ); + if( Item ) Item->GetJson( Slot ); + AllSlots.append( Slot ); + } + a_Value["Slots"] = AllSlots; +} + + + + + +void cChestEntity::SendTo( cClientHandle* a_Client, cServer* a_Server ) +{ + (void)a_Client; + (void)a_Server; + return; +} + + + + + +void cChestEntity::UsedBy( cPlayer * a_Player ) +{ + if( !GetWindow() ) + { + cWindow* Window = new cWindow( this, true ); + Window->SetSlots( GetContents(), GetChestHeight()*c_ChestWidth ); + Window->SetWindowID( 1 ); + Window->SetWindowType( cWindow::Chest ); + Window->SetWindowTitle("UberChest"); + Window->GetOwner()->SetEntity(this); + OpenWindow( Window ); + } + if ( GetWindow() ) + { + if( a_Player->GetWindow() != GetWindow() ) + { + a_Player->OpenWindow( GetWindow() ); + GetWindow()->SendWholeWindow( a_Player->GetClientHandle() ); + } + } + cPacket_BlockAction ChestOpen; + ChestOpen.m_PosX = GetPosX(); + ChestOpen.m_PosY = (short)GetPosY(); + ChestOpen.m_PosZ = GetPosZ(); + ChestOpen.m_Byte1 = (char)1; + ChestOpen.m_Byte2 = (char)1; + m_World->BroadcastToChunkOfBlock(m_PosX, m_PosY, m_PosZ, &ChestOpen); + + // This is rather a hack + // Instead of marking the chunk as dirty upon chest contents change, we mark it dirty now + // We cannot properly detect contents change, but such a change doesn't happen without a player opening the chest first. + // The few false positives aren't much to worry about + int ChunkX, ChunkY = 0, ChunkZ; + cChunkDef::BlockToChunk(m_PosX, m_PosY, m_PosZ, ChunkX, ChunkZ); + m_World->MarkChunkDirty(ChunkX, ChunkY, ChunkZ); +} + + + + + +cItem *cChestEntity::GetContents(bool a_OnlyThis) +{ + if (m_JoinedChest && !a_OnlyThis) + { + cItem *Combined = new cItem[GetChestHeight()*c_ChestWidth]; + int i; + cItem *first = (m_TopChest) ? GetContents(true) : m_JoinedChest->GetContents(true); + cItem *second = (!m_TopChest) ? GetContents(true) : m_JoinedChest->GetContents(true); + for (i=0; i < GetChestHeight()*c_ChestWidth; i++) + { + int index = i % c_ChestHeight*c_ChestWidth; + if (i < c_ChestHeight*c_ChestWidth) + Combined[index] = first[index]; + else + Combined[index] = second[index]; + } + return Combined; + } + else + return m_Content; +} + + + + diff --git a/source/cChestEntity.h b/source/cChestEntity.h index 6e625f8f5..b24533d76 100644 --- a/source/cChestEntity.h +++ b/source/cChestEntity.h @@ -1,66 +1,66 @@ - -#pragma once - -#include "cBlockEntity.h" -#include "cWindowOwner.h" -#include "packets/cPacket_BlockAction.h" - - - - - -namespace Json -{ - class Value; -}; - -class cClientHandle; -class cServer; -class cItem; -class cNBTData; - - - - - -class cChestEntity : - public cBlockEntity, - public cWindowOwner -{ -public: - cChestEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); - virtual ~cChestEntity(); - virtual void Destroy(); - - void HandleData( cNBTData* a_NBTData ); - - const cItem * GetSlot( int a_Slot ) const; - void SetSlot( int a_Slot, cItem & a_Item ); - - bool LoadFromJson( const Json::Value& a_Value ); - virtual void SaveToJson(Json::Value& a_Value ) override; - - void SendTo( cClientHandle* a_Client, cServer* a_Server ); - - virtual void UsedBy( cPlayer * a_Player ) override; - - cChestEntity *GetJoinedChest() { return m_JoinedChest; } - void SetJoinedChest(cChestEntity *a_Chest) { m_JoinedChest = a_Chest; } - void RemoveJoinedChest(cChestEntity *a_Chest) { if (m_JoinedChest && m_JoinedChest == a_Chest) { m_JoinedChest = NULL; m_TopChest = false; } } - - int GetChestHeight() { return ((m_JoinedChest) ? c_ChestHeight * 2 : c_ChestHeight); } - cItem * GetContents(bool a_OnlyThis = false); - - static const int c_ChestWidth = 9; - static const int c_ChestHeight = 3; - -private: - - cItem * m_Content; - bool m_TopChest; - cChestEntity * m_JoinedChest; -}; - - - - + +#pragma once + +#include "cBlockEntity.h" +#include "cWindowOwner.h" +#include "packets/cPacket_BlockAction.h" + + + + + +namespace Json +{ + class Value; +}; + +class cClientHandle; +class cServer; +class cItem; +class cNBTData; + + + + + +class cChestEntity : + public cBlockEntity, + public cWindowOwner +{ +public: + cChestEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); + virtual ~cChestEntity(); + virtual void Destroy(); + + void HandleData( cNBTData* a_NBTData ); + + const cItem * GetSlot( int a_Slot ) const; + void SetSlot( int a_Slot, cItem & a_Item ); + + bool LoadFromJson( const Json::Value& a_Value ); + virtual void SaveToJson(Json::Value& a_Value ) override; + + void SendTo( cClientHandle* a_Client, cServer* a_Server ); + + virtual void UsedBy( cPlayer * a_Player ) override; + + cChestEntity *GetJoinedChest() { return m_JoinedChest; } + void SetJoinedChest(cChestEntity *a_Chest) { m_JoinedChest = a_Chest; } + void RemoveJoinedChest(cChestEntity *a_Chest) { if (m_JoinedChest && m_JoinedChest == a_Chest) { m_JoinedChest = NULL; m_TopChest = false; } } + + int GetChestHeight() { return ((m_JoinedChest) ? c_ChestHeight * 2 : c_ChestHeight); } + cItem * GetContents(bool a_OnlyThis = false); + + static const int c_ChestWidth = 9; + static const int c_ChestHeight = 3; + +private: + + cItem * m_Content; + bool m_TopChest; + cChestEntity * m_JoinedChest; +}; + + + + diff --git a/source/cChicken.cpp b/source/cChicken.cpp index 2073393d6..ddc6400e4 100644 --- a/source/cChicken.cpp +++ b/source/cChicken.cpp @@ -1,56 +1,56 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cChicken.h" - - - - - -// TODO Drop egg every 5-10 minutes - - - - - -cChicken::cChicken() -{ - m_MobType = 93; - GetMonsterConfig("Chicken"); -} - - - - - -cChicken::~cChicken() -{ -} - - - - - -bool cChicken::IsA( const char* a_EntityType ) -{ - if( strcmp( a_EntityType, "cChicken" ) == 0 ) return true; - return cMonster::IsA( a_EntityType ); -} - - - - - -void cChicken::KilledBy( cEntity* a_Killer ) -{ - cItems Drops; - AddRandomDropItem(Drops, 0, 2, E_ITEM_FEATHER); - Drops.push_back(cItem((GetMetaData() == BURNING) ? E_ITEM_COOKED_CHICKEN : E_ITEM_RAW_CHICKEN, 1)); - m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); - - cMonster::KilledBy( a_Killer ); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cChicken.h" + + + + + +// TODO Drop egg every 5-10 minutes + + + + + +cChicken::cChicken() +{ + m_MobType = 93; + GetMonsterConfig("Chicken"); +} + + + + + +cChicken::~cChicken() +{ +} + + + + + +bool cChicken::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cChicken" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cChicken::KilledBy( cEntity* a_Killer ) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_FEATHER); + Drops.push_back(cItem((GetMetaData() == BURNING) ? E_ITEM_COOKED_CHICKEN : E_ITEM_RAW_CHICKEN, 1)); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cChicken.h b/source/cChicken.h index 1ad545828..b04197414 100644 --- a/source/cChicken.h +++ b/source/cChicken.h @@ -1,14 +1,14 @@ -#pragma once - -#include "cPassiveMonster.h" - -class cChicken : public cPassiveMonster -{ -public: - cChicken(); - ~cChicken(); - - virtual bool IsA( const char* a_EntityType ); - - virtual void KilledBy( cEntity* a_Killer ); -}; +#pragma once + +#include "cPassiveMonster.h" + +class cChicken : public cPassiveMonster +{ +public: + cChicken(); + ~cChicken(); + + virtual bool IsA( const char* a_EntityType ); + + virtual void KilledBy( cEntity* a_Killer ); +}; diff --git a/source/cChunk.cpp b/source/cChunk.cpp index 5d5a1d972..98415b572 100644 --- a/source/cChunk.cpp +++ b/source/cChunk.cpp @@ -1,1643 +1,1643 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#ifndef _WIN32 - #include -#endif - - -#include "cChunk.h" -#include "cWorld.h" -#include "cWaterSimulator.h" -#include "cLavaSimulator.h" -#include "cClientHandle.h" -#include "cServer.h" -#include "zlib.h" -#include "Defines.h" -#include "cChestEntity.h" -#include "cFurnaceEntity.h" -#include "cSignEntity.h" -#include "cTorch.h" -#include "cLadder.h" -#include "cPickup.h" -#include "cRedstone.h" -#include "cItem.h" -#include "cNoise.h" -#include "cRoot.h" -#include "cBlockToPickup.h" -#include "MersenneTwister.h" -#include "cPlayer.h" - -#include "packets/cPacket_DestroyEntity.h" -#include "packets/cPacket_PreChunk.h" -#include "packets/cPacket_BlockChange.h" -#include "packets/cPacket_MultiBlock.h" - -#include - - - - - -extern bool g_bWaterPhysics; - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// sSetBlock: - -sSetBlock::sSetBlock( int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) // absolute block position - : x( a_BlockX ) - , y( a_BlockY ) - , z( a_BlockZ ) - , BlockType( a_BlockType ) - , BlockMeta( a_BlockMeta ) -{ - cChunkDef::AbsoluteToRelative(x, y, z, ChunkX, ChunkZ); -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cChunk: - -cChunk::cChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkMap * a_ChunkMap, cWorld * a_World) - : m_PosX( a_ChunkX ) - , m_PosY( a_ChunkY ) - , m_PosZ( a_ChunkZ ) - , m_BlockTickX( 0 ) - , m_BlockTickY( 0 ) - , m_BlockTickZ( 0 ) - , m_World( a_World ) - , m_ChunkMap(a_ChunkMap) - , m_IsValid(false) - , m_IsLightValid(false) - , m_IsDirty(false) - , m_IsSaving(false) - , m_StayCount(0) -{ - // LOGINFO("### new cChunk (%i, %i) at %p, thread 0x%x ###", a_X, a_Z, this, GetCurrentThreadId()); -} - - - - - -cChunk::~cChunk() -{ - // LOGINFO("### delete cChunk() (%i, %i) from %p, thread 0x%x ###", m_PosX, m_PosZ, this, GetCurrentThreadId() ); - - for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) - { - delete *itr; - } - m_BlockEntities.clear(); - - // Remove and destroy all entities that are not players: - cEntityList Entities; - for (cEntityList::const_iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) - { - if ((*itr)->GetEntityType() != cEntity::eEntityType_Player) - { - Entities.push_back(*itr); - } - } - for (cEntityList::iterator itr = Entities.begin(); itr != Entities.end(); ++itr) - { - (*itr)->RemoveFromChunk(); - (*itr)->Destroy(); - } - m_Entities.clear(); -} - - - - - -void cChunk::SetValid(void) -{ - m_IsValid = true; - - m_World->GetChunkMap()->ChunkValidated(); -} - - - - - -void cChunk::MarkRegenerating(void) -{ - // Tell all clients attached to this chunk that they want this chunk: - for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) - { - (*itr)->AddWantedChunk(m_PosX, m_PosZ); - } // for itr - m_LoadedByClient[] -} - - - - - -bool cChunk::CanUnload(void) -{ - return m_LoadedByClient.empty() && !m_IsDirty && (m_StayCount == 0); -} - - - - - -void cChunk::MarkSaving(void) -{ - m_IsSaving = true; -} - - - - - -void cChunk::MarkSaved(void) -{ - if (!m_IsSaving) - { - return; - } - m_IsDirty = false; -} - - - - - -void cChunk::MarkLoaded(void) -{ - m_IsDirty = false; - SetValid(); -} - - - - - -void cChunk::MarkLoadFailed(void) -{ - if (m_IsValid) - { - return; - } - - m_HasLoadFailed = true; -} - - - - - -void cChunk::GetAllData(cChunkDataCallback & a_Callback) -{ - a_Callback.HeightMap (&m_HeightMap); - a_Callback.BiomeData (&m_BiomeMap); - a_Callback.BlockTypes (m_BlockTypes); - a_Callback.BlockMeta (m_BlockMeta); - a_Callback.LightIsValid (m_IsLightValid); - a_Callback.BlockLight (m_BlockLight); - a_Callback.BlockSkyLight(m_BlockSkyLight); - - for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) - { - a_Callback.Entity(*itr); - } - - for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) - { - a_Callback.BlockEntity(*itr); - } -} - - - - - -void cChunk::SetAllData( - const BLOCKTYPE * a_BlockTypes, - const NIBBLETYPE * a_BlockMeta, - const NIBBLETYPE * a_BlockLight, - const NIBBLETYPE * a_BlockSkyLight, - const HeightMap * a_HeightMap, - const BiomeMap & a_BiomeMap, - cEntityList & a_Entities, - cBlockEntityList & a_BlockEntities -) -{ - memcpy(m_BiomeMap, a_BiomeMap, sizeof(m_BiomeMap)); - - if (a_HeightMap != NULL) - { - memcpy(m_HeightMap, a_HeightMap, sizeof(m_HeightMap)); - } - - memcpy(m_BlockTypes, a_BlockTypes, sizeof(m_BlockTypes)); - memcpy(m_BlockMeta, a_BlockMeta, sizeof(m_BlockMeta)); - if (a_BlockLight != NULL) - { - memcpy(m_BlockLight, a_BlockLight, sizeof(m_BlockLight)); - } - if (a_BlockSkyLight != NULL) - { - memcpy(m_BlockSkyLight, a_BlockSkyLight, sizeof(m_BlockSkyLight)); - } - - m_IsLightValid = (a_BlockLight != NULL) && (a_BlockSkyLight != NULL); - - if (a_HeightMap == NULL) - { - CalculateHeightmap(); - } - - // Append entities to current entity list: - m_Entities.splice(m_Entities.end(), a_Entities); - - // Clear the block entities present - either the loader / saver has better, or we'll create empty ones: - for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) - { - delete *itr; - } - std::swap(a_BlockEntities, m_BlockEntities); - - // Create block entities that the loader didn't load; fill them with defaults - CreateBlockEntities(); - - m_HasLoadFailed = false; -} - - - - - -void cChunk::SetLight( - const cChunkDef::BlockNibbles & a_BlockLight, - const cChunkDef::BlockNibbles & a_SkyLight -) -{ - // TODO: We might get cases of wrong lighting when a chunk changes in the middle of a lighting calculation. - // Postponing until we see how bad it is :) - memcpy(m_BlockLight, a_BlockLight, sizeof(m_BlockLight)); - memcpy(m_BlockSkyLight, a_SkyLight, sizeof(m_BlockSkyLight)); - m_IsLightValid = true; -} - - - - - -void cChunk::GetBlockTypes(BLOCKTYPE * a_BlockTypes) -{ - memcpy(a_BlockTypes, m_BlockTypes, NumBlocks); -} - - - - - -void cChunk::GetBlockData(BLOCKTYPE * a_BlockData) -{ - memcpy(a_BlockData, m_BlockTypes, NumBlocks); - memcpy(a_BlockData + MetaOffset, m_BlockMeta, NumBlocks / 2); - memcpy(a_BlockData + LightOffset, m_BlockLight, NumBlocks / 2); - memcpy(a_BlockData + SkyLightOffset, m_BlockSkyLight, NumBlocks / 2); -} - - - - - -/// Returns true if there is a block entity at the coords specified -bool cChunk::HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ) -{ - for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) - { - if ( - ((*itr)->GetPosX() == a_BlockX) && - ((*itr)->GetPosY() == a_BlockY) && - ((*itr)->GetPosZ() == a_BlockZ) - ) - { - return true; - } - } // for itr - m_BlockEntities[] - return false; -} - - - - - -/// Sets or resets the internal flag that prevents chunk from being unloaded -void cChunk::Stay(bool a_Stay) -{ - m_StayCount += (a_Stay ? 1 : -1); - ASSERT(m_StayCount >= 0); -} - - - - - -void cChunk::Tick(float a_Dt, MTRand & a_TickRandom) -{ - cCSLock Lock(m_CSBlockLists); - unsigned int PendingSendBlocks = m_PendingSendBlocks.size(); - if( PendingSendBlocks > 1 ) - { - cPacket_MultiBlock MultiBlock; - MultiBlock.m_ChunkX = m_PosX; - MultiBlock.m_ChunkZ = m_PosZ; - MultiBlock.m_NumBlocks = (short)PendingSendBlocks; - MultiBlock.m_Data = new cPacket_MultiBlock::sBlockChange[ PendingSendBlocks ]; - MultiBlock.m_DataSize = PendingSendBlocks * sizeof( cPacket_MultiBlock::sBlockChange ); - //LOG("Sending multiblock packet for %i blocks", PendingSendBlocks ); - for( unsigned int i = 0; i < PendingSendBlocks; i++) - { - unsigned int index = m_PendingSendBlocks[i]; - Vector3i BlockPos = IndexToCoordinate( index ); - - unsigned int Coords = BlockPos.y | (BlockPos.z << 8) | (BlockPos.x << 12); - unsigned int Blocks = GetNibble( m_BlockMeta, index ) | (m_BlockTypes[index] << 4); - MultiBlock.m_Data[i].Data = Coords << 16 | Blocks; - } - m_PendingSendBlocks.clear(); - PendingSendBlocks = m_PendingSendBlocks.size(); - Broadcast( MultiBlock ); - } - if( PendingSendBlocks > 0 ) - { - for( unsigned int i = 0; i < PendingSendBlocks; i++) - { - unsigned int index = m_PendingSendBlocks[i]; - Vector3i WorldPos = PositionToWorldPosition( IndexToCoordinate( index ) ); - - cPacket_BlockChange BlockChange; - BlockChange.m_PosX = WorldPos.x; - BlockChange.m_PosY = (unsigned char)WorldPos.y; - BlockChange.m_PosZ = WorldPos.z; - BlockChange.m_BlockType = m_BlockTypes[index]; - BlockChange.m_BlockMeta = GetNibble( m_BlockMeta, index ); - Broadcast( BlockChange ); - } - m_PendingSendBlocks.clear(); - } - Lock.Unlock(); - - while ( !m_UnloadQuery.empty() ) - { - cPacket_PreChunk UnloadPacket; - UnloadPacket.m_PosX = GetPosX(); - UnloadPacket.m_PosZ = GetPosZ(); - UnloadPacket.m_bLoad = false; // Unload - (*m_UnloadQuery.begin())->Send( UnloadPacket ); - m_UnloadQuery.remove( *m_UnloadQuery.begin() ); - } - - CheckBlocks(); - - TickBlocks(a_TickRandom); - - // Tick block entities (furnaces) - for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) - { - if ((*itr)->GetBlockType() == E_BLOCK_FURNACE) - { - m_IsDirty = ((cFurnaceEntity *)(*itr))->Tick( a_Dt ) | m_IsDirty; - } - } -} - - - - - -void cChunk::CheckBlocks(void) -{ - cCSLock Lock2(m_CSBlockLists); - unsigned int NumTickBlocks = m_ToTickBlocks.size(); - Lock2.Unlock(); - - if (NumTickBlocks == 0) - { - return; - } - - Lock2.Lock(); - std::deque< unsigned int > ToTickBlocks = m_ToTickBlocks; - m_ToTickBlocks.clear(); - Lock2.Unlock(); - - for (std::deque< unsigned int >::const_iterator itr = ToTickBlocks.begin(); itr != ToTickBlocks.end(); ++itr) - { - unsigned int index = (*itr); - Vector3i BlockPos = IndexToCoordinate(index); - - BLOCKTYPE BlockType = GetBlock(index); - NIBBLETYPE BlockMeta = GetMeta (index); - switch (BlockType) - { - // Stuff that drops when block below is destroyed: - case E_BLOCK_REDSTONE_REPEATER_OFF: - case E_BLOCK_REDSTONE_REPEATER_ON: - case E_BLOCK_REDSTONE_WIRE: - case E_BLOCK_CACTUS: - case E_BLOCK_REEDS: - case E_BLOCK_WOODEN_PRESSURE_PLATE: - case E_BLOCK_STONE_PRESSURE_PLATE: - case E_BLOCK_MINECART_TRACKS: - case E_BLOCK_SIGN_POST: - case E_BLOCK_CROPS: - case E_BLOCK_SAPLING: - case E_BLOCK_YELLOW_FLOWER: - case E_BLOCK_RED_ROSE: - case E_BLOCK_RED_MUSHROOM: - case E_BLOCK_BROWN_MUSHROOM: - case E_BLOCK_SNOW: - { - if (GetBlock(BlockPos.x, BlockPos.y - 1, BlockPos.z) == E_BLOCK_AIR) - { - SetBlock( BlockPos, E_BLOCK_AIR, 0 ); - - Vector3i WorldPos = PositionToWorldPosition( BlockPos ); - - m_World->GetSimulatorManager()->WakeUp(WorldPos.x, WorldPos.y, WorldPos.z); - - cItems Pickups; - cBlockToPickup::ToPickup(BlockType, BlockMeta, E_ITEM_EMPTY, Pickups); - m_World->SpawnItemPickups(Pickups, WorldPos.x, WorldPos.y, WorldPos.z); - } - break; - } - - case E_BLOCK_REDSTONE_TORCH_OFF: - case E_BLOCK_REDSTONE_TORCH_ON: - case E_BLOCK_TORCH: - { - char Dir = cTorch::MetaDataToDirection( GetNibble( m_BlockMeta, BlockPos ) ); - Vector3i WorldPos = PositionToWorldPosition( BlockPos ); - - Vector3i AttachedTo = WorldPos; - AddDirection( AttachedTo.x, AttachedTo.y, AttachedTo.z, Dir, true ); - if( m_World->GetBlock( AttachedTo ) == E_BLOCK_AIR ) - { - SetBlock( BlockPos, E_BLOCK_AIR, 0 ); - - m_World->GetSimulatorManager()->WakeUp(WorldPos.x, WorldPos.y, WorldPos.z); - - cItems Pickups; - cBlockToPickup::ToPickup(BlockType, BlockMeta, E_ITEM_EMPTY, Pickups); - m_World->SpawnItemPickups(Pickups, WorldPos.x, WorldPos.y, WorldPos.z); - } - break; - } - - case E_BLOCK_LADDER: - { - char Dir = cLadder::MetaDataToDirection( GetNibble( m_BlockMeta, BlockPos ) ); - Vector3i WorldPos = PositionToWorldPosition( BlockPos ); - Vector3i AttachedTo = WorldPos; - AddDirection( AttachedTo.x, AttachedTo.y, AttachedTo.z, Dir, true ); - if( m_World->GetBlock( AttachedTo ) == E_BLOCK_AIR ) - { - SetBlock( BlockPos, E_BLOCK_AIR, 0 ); - cItems Pickups; - cBlockToPickup::ToPickup(BlockType, BlockMeta, E_ITEM_EMPTY, Pickups); - m_World->SpawnItemPickups(Pickups, WorldPos.x, WorldPos.y, WorldPos.z); - } - break; - } - } // switch (BlockType) - } // for itr - ToTickBlocks[] -} - - - - - -void cChunk::TickBlocks(MTRand & a_TickRandom) -{ - // Tick dem blocks - // _X: We must limit the random number or else we get a nasty int overflow bug ( http://forum.mc-server.org/showthread.php?tid=457 ) - int RandomX = a_TickRandom.randInt(0x00ffffff); - int RandomY = a_TickRandom.randInt(0x00ffffff); - int RandomZ = a_TickRandom.randInt(0x00ffffff); - int TickX = m_BlockTickX; - int TickY = m_BlockTickY; - int TickZ = m_BlockTickZ; - - // This for loop looks disgusting, but it actually does a simple thing - first processes m_BlockTick, then adds random to it - // This is so that SetNextBlockTick() works - for (int i = 0; i < 50; i++, - - // This weird construct (*2, then /2) is needed, - // otherwise the blocktick distribution is too biased towards even coords! - - TickX = (TickX + RandomX) % (Width * 2), - TickY = (TickY + RandomY) % (Height * 2), - TickZ = (TickZ + RandomZ) % (Width * 2), - m_BlockTickX = TickX / 2, - m_BlockTickY = TickY / 2, - m_BlockTickZ = TickZ / 2 - ) - { - - if (m_BlockTickY > cChunkDef::GetHeight(m_HeightMap, m_BlockTickX, m_BlockTickZ)) - { - continue; // It's all air up here - } - - unsigned int Index = MakeIndexNoCheck( m_BlockTickX, m_BlockTickY, m_BlockTickZ ); - BLOCKTYPE ID = m_BlockTypes[Index]; - switch( ID ) - { - case E_BLOCK_CROPS: - { - NIBBLETYPE Meta = GetMeta(Index); - if (Meta < 7) - { - FastSetBlock(m_BlockTickX, m_BlockTickY, m_BlockTickZ, E_BLOCK_CROPS, ++Meta); - } - break; - } - - case E_BLOCK_GRASS: TickGrass (m_BlockTickX, m_BlockTickY, m_BlockTickZ, a_TickRandom); break; - case E_BLOCK_PUMPKIN_STEM: - case E_BLOCK_MELON_STEM: TickMelonPumpkin(m_BlockTickX, m_BlockTickY, m_BlockTickZ, Index, ID, a_TickRandom); break; - case E_BLOCK_FARMLAND: TickFarmland (m_BlockTickX, m_BlockTickY, m_BlockTickZ); break; - case E_BLOCK_SUGARCANE: GrowSugarcane (m_BlockTickX, m_BlockTickY, m_BlockTickZ, 1); break; - case E_BLOCK_CACTUS: GrowCactus (m_BlockTickX, m_BlockTickY, m_BlockTickZ, 1); break; - - case E_BLOCK_SAPLING: - { - // Check the highest bit, if set, grow the tree, if not, set it (1-bit delay): - NIBBLETYPE Meta = GetMeta(m_BlockTickX, m_BlockTickY, m_BlockTickZ); - if ((Meta & 0x08) != 0) - { - m_World->GrowTree( m_BlockTickX + m_PosX*Width, m_BlockTickY, m_BlockTickZ + m_PosZ*Width ); - } - else - { - SetMeta(m_BlockTickX, m_BlockTickY, m_BlockTickZ, Meta | 0x08); - } - break; - } - - case E_BLOCK_LEAVES: //todo, http://www.minecraftwiki.net/wiki/Data_values#Leaves - { - break; - } - - default: - { - break; - } - } - } -} - - - - - -void cChunk::TickGrass(int a_RelX, int a_RelY, int a_RelZ, MTRand & a_TickRandom) -{ - // Grass turns into dirt if there's another block on top of it: - { - BLOCKTYPE AboveBlock = cChunkDef::GetBlock(m_BlockTypes, a_RelX, a_RelY + 1, a_RelZ); - if (!((g_BlockOneHitDig[AboveBlock]) || (g_BlockTransparent[AboveBlock]))) - { - FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, 0); - return; - } - } - - // Grass spreads to nearby blocks if there's enough light (TODO) and free space above that block - // Ref.: http://www.minecraftwiki.net/wiki/Grass_Block#Growth - for (int i = 0; i < 2; i++) // Pick two blocks to grow to - { - int OfsX = a_TickRandom.randInt(2) - 1; // [-1 .. 1] - int OfsY = a_TickRandom.randInt(4) - 3; // [-3 .. 1] - int OfsZ = a_TickRandom.randInt(2) - 1; // [-1 .. 1] - - BLOCKTYPE DestBlock; - NIBBLETYPE DestMeta; - if ( - !UnboundedRelGetBlock(a_RelX + OfsX, a_RelY + OfsY, a_RelZ + OfsZ, DestBlock, DestMeta) || - (DestBlock != E_BLOCK_DIRT) - ) - { - continue; - } - - BLOCKTYPE AboveDest; - NIBBLETYPE AboveMeta; - if ( - UnboundedRelGetBlock(a_RelX + OfsX, a_RelY + OfsY + 1, a_RelZ + OfsZ, AboveDest, AboveMeta) && - ((g_BlockOneHitDig[AboveDest]) || (g_BlockTransparent[AboveDest])) - // TODO: Query dest light, if it's enough - ) - { - UnboundedRelFastSetBlock(a_RelX + OfsX, a_RelY + OfsY, a_RelZ + OfsZ, E_BLOCK_GRASS, 0); - } - } // for i - repeat twice -} - - - - - -void cChunk::TickMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, int a_BlockIdx, BLOCKTYPE a_BlockType, MTRand & a_TickRandom) -{ - NIBBLETYPE Meta = GetMeta(a_BlockIdx); - if (Meta < 7) - { - FastSetBlock(m_BlockTickX, m_BlockTickY, m_BlockTickZ, a_BlockType, ++Meta); - return; - } - GrowMelonPumpkin(a_RelX, a_RelY, a_RelZ, a_BlockType, a_TickRandom); -} - - - - - -void cChunk::TickFarmland(int a_RelX, int a_RelY, int a_RelZ) -{ - // TODO: Rain hydrates blocks, too. Check world weather, don't search for water if raining. - - // Search for water in a close proximity: - // Ref.: http://www.minecraftwiki.net/wiki/Farmland#Hydrated_Farmland_Tiles - bool Found = false; - for (int y = a_RelY; y <= a_RelY + 1; y++) - { - for (int z = a_RelZ - 4; z <= a_RelZ + 4; z++) - { - for (int x = a_RelX - 4; x <= a_RelX + 4; x++) - { - BLOCKTYPE BlockType; - NIBBLETYPE Meta; // unused - - if (!UnboundedRelGetBlock(x, y, z, BlockType, Meta)) - { - // Too close to an unloaded chunk, we might miss a water block there, so don't tick at all - return; - } - if ( - (BlockType == E_BLOCK_WATER) || - (BlockType == E_BLOCK_STATIONARY_WATER) - ) - { - Found = true; - break; - } - } // for x - if (Found) - { - break; - } - } // for z - if (Found) - { - break; - } - } // for y - - NIBBLETYPE BlockMeta = GetMeta(a_RelX, a_RelY, a_RelZ); - - if (Found) - { - // Water was found, hydrate the block until hydration reaches 7: - if (BlockMeta < 7) - { - FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_FARMLAND, ++BlockMeta); - } - return; - } - - // Water wasn't found, de-hydrate block: - if (BlockMeta > 0) - { - FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_FARMLAND, --BlockMeta); - return; - } - - // Farmland too dry. Turn back to dirt: - FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, 0); - - // TODO: Uproot whatever was growing on top: -} - - - - - -void cChunk::GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, MTRand & a_TickRandom) -{ - // Convert the stem BlockType into produce BlockType - BLOCKTYPE ProduceType; - switch (a_BlockType) - { - case E_BLOCK_MELON_STEM: ProduceType = E_BLOCK_MELON; break; - case E_BLOCK_PUMPKIN_STEM: ProduceType = E_BLOCK_PUMPKIN; break; - default: - { - ASSERT(!"Unhandled blocktype in TickMelonPumpkin()"); - return; - } - } - - // Check if there's another melon / pumpkin around that stem, if so, abort: - bool IsValid; - BLOCKTYPE BlockType[4]; - NIBBLETYPE BlockMeta; // unused - IsValid = UnboundedRelGetBlock(a_RelX + 1, a_RelY, a_RelZ, BlockType[0], BlockMeta); - IsValid = IsValid && UnboundedRelGetBlock(a_RelX - 1, a_RelY, a_RelZ, BlockType[1], BlockMeta); - IsValid = IsValid && UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ + 1, BlockType[2], BlockMeta); - IsValid = IsValid && UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ - 1, BlockType[3], BlockMeta); - if ( - !IsValid || - (BlockType[0] == ProduceType) || - (BlockType[1] == ProduceType) || - (BlockType[2] == ProduceType) || - (BlockType[3] == ProduceType) - ) - { - // Neighbors not valid or already taken by the same produce - return; - } - - // Pick a direction in which to place the produce: - int x = 0, z = 0; - int CheckType = a_TickRandom.randInt(3); // The index to the neighbors array which should be checked for emptiness - switch (CheckType) - { - case 0: x = 1; break; - case 1: x = -1; break; - case 2: z = 1; break; - case 3: z = -1; break; - } - - // Check that the block in that direction is empty: - switch (BlockType[CheckType]) - { - case E_BLOCK_AIR: - case E_BLOCK_SNOW: - case E_BLOCK_TALL_GRASS: - case E_BLOCK_DEAD_BUSH: - { - break; - } - default: return; - } - - // Check if there's soil under the neighbor. We already know the neighbors are valid. Place produce if ok - BLOCKTYPE Soil; - UnboundedRelGetBlock(a_RelX + x, a_RelY - 1, a_RelZ + z, Soil, BlockMeta); - switch (Soil) - { - case E_BLOCK_DIRT: - case E_BLOCK_GRASS: - case E_BLOCK_FARMLAND: - { - // Place a randomly-facing produce: - UnboundedRelFastSetBlock(a_RelX + x, a_RelY, a_RelZ + z, ProduceType, (NIBBLETYPE)(a_TickRandom.randInt(4) % 4)); - break; - } - } -} - - - - - -void cChunk::GrowSugarcane(int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks) -{ - // Check the total height of the sugarcane blocks here: - int Top = a_RelY + 1; - while ( - (Top < cChunkDef::Height) && - (GetBlock(a_RelX, Top, a_RelZ) == E_BLOCK_SUGARCANE) - ) - { - ++Top; - } - int Bottom = a_RelY - 1; - while ( - (Bottom > 0) && - (GetBlock(a_RelX, Bottom, a_RelZ) == E_BLOCK_SUGARCANE) - ) - { - --Bottom; - } - - // Grow by at most a_NumBlocks, but no more than max height: - int ToGrow = std::min(a_NumBlocks, m_World->GetMaxSugarcaneHeight() + 1 - (Top - Bottom)); - for (int i = 0; i < ToGrow; i++) - { - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - if (UnboundedRelGetBlock(a_RelX, Top + i, a_RelZ, BlockType, BlockMeta) && (BlockType == E_BLOCK_AIR)) - { - UnboundedRelFastSetBlock(a_RelX, Top + i, a_RelZ, E_BLOCK_SUGARCANE, 0); - } - else - { - break; - } - } // for i -} - - - - - -void cChunk::GrowCactus(int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks) -{ - // Check the total height of the sugarcane blocks here: - int Top = a_RelY + 1; - while ( - (Top < cChunkDef::Height) && - (GetBlock(a_RelX, Top, a_RelZ) == E_BLOCK_CACTUS) - ) - { - ++Top; - } - int Bottom = a_RelY - 1; - while ( - (Bottom > 0) && - (GetBlock(a_RelX, Bottom, a_RelZ) == E_BLOCK_CACTUS) - ) - { - --Bottom; - } - - // Grow by at most a_NumBlocks, but no more than max height: - int ToGrow = std::min(a_NumBlocks, m_World->GetMaxCactusHeight() + 1 - (Top - Bottom)); - for (int i = 0; i < ToGrow; i++) - { - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - if (UnboundedRelGetBlock(a_RelX, Top + i, a_RelZ, BlockType, BlockMeta) && (BlockType == E_BLOCK_AIR)) - { - // TODO: Check the surrounding blocks, if they aren't air, break the cactus block into pickups (and continue breaking blocks above in the next loop iterations) - UnboundedRelFastSetBlock(a_RelX, Top + i, a_RelZ, E_BLOCK_CACTUS, 0); - } - else - { - break; - } - } // for i -} - - - - - -bool cChunk::UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) -{ - if ((a_RelY < 0) || (a_RelY > cChunkDef::Height)) - { - return false; - } - - if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width)) - { - int BlockIdx = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ); - a_BlockType = GetBlock(BlockIdx); - a_BlockMeta = GetMeta(BlockIdx); - return true; - } - return m_ChunkMap->LockedGetBlock( - m_PosX * cChunkDef::Width + a_RelX, - ZERO_CHUNK_Y * cChunkDef::Height + a_RelY, - m_PosZ * cChunkDef::Width + a_RelZ, - a_BlockType, a_BlockMeta - ); -} - - - - - -bool cChunk::UnboundedRelSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) -{ - if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width)) - { - SetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); - return true; - } - return m_ChunkMap->LockedSetBlock( - m_PosX * cChunkDef::Width + a_RelX, - ZERO_CHUNK_Y * cChunkDef::Height + a_RelY, - m_PosZ * cChunkDef::Width + a_RelZ, - a_BlockType, a_BlockMeta - ); -} - - - - - -bool cChunk::UnboundedRelFastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) -{ - if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width)) - { - FastSetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); - return true; - } - return m_ChunkMap->LockedFastSetBlock( - m_PosX * cChunkDef::Width + a_RelX, - ZERO_CHUNK_Y * cChunkDef::Height + a_RelY, - m_PosZ * cChunkDef::Width + a_RelZ, - a_BlockType, a_BlockMeta - ); -} - - - - - -int cChunk::GetHeight( int a_X, int a_Z ) -{ - ASSERT((a_X >= 0) && (a_X < Width) && (a_Z >= 0) && (a_Z < Width)); - - if ((a_X >= 0) && (a_X < Width) && (a_Z >= 0) && (a_Z < Width)) - { - return m_HeightMap[a_X + a_Z * Width]; - } - return 0; -} - - - - - -void cChunk::CreateBlockEntities(void) -{ - for (int x = 0; x < Width; x++) - { - for (int z = 0; z < Width; z++) - { - for (int y = 0; y < Height; y++) - { - ENUM_BLOCK_ID BlockType = (ENUM_BLOCK_ID)m_BlockTypes[ MakeIndex( x, y, z ) ]; - switch ( BlockType ) - { - case E_BLOCK_CHEST: - { - if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width)) - { - m_BlockEntities.push_back( new cChestEntity( x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) ); - } - break; - } - - case E_BLOCK_FURNACE: - { - if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width)) - { - m_BlockEntities.push_back( new cFurnaceEntity( x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) ); - } - break; - } - - case E_BLOCK_SIGN_POST: - case E_BLOCK_WALLSIGN: - { - if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width)) - { - m_BlockEntities.push_back( new cSignEntity( BlockType, x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) ); - } - break; - } - } // switch (BlockType) - } // for y - } // for z - } // for x -} - - - - - -void cChunk::CalculateHeightmap() -{ - for (int x = 0; x < Width; x++) - { - for (int z = 0; z < Width; z++) - { - for (int y = Height - 1; y > -1; y--) - { - int index = MakeIndex( x, y, z ); - if (m_BlockTypes[index] != E_BLOCK_AIR) - { - m_HeightMap[x + z * Width] = (unsigned char)y; - break; - } - } // for y - } // for z - } // for x -} - - - - - -void cChunk::SetBlock( int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) -{ - if (a_RelX < 0 || a_RelX >= Width || a_RelY < 0 || a_RelY >= Height || a_RelZ < 0 || a_RelZ >= Width) - { - return; // Clip - } - - ASSERT(IsValid()); // Is this chunk loaded / generated? - - int index = MakeIndexNoCheck( a_RelX, a_RelY, a_RelZ ); - BLOCKTYPE OldBlockMeta = GetNibble( m_BlockMeta, index ); - BLOCKTYPE OldBlockType = m_BlockTypes[index]; - m_BlockTypes[index] = a_BlockType; - - SetNibble( m_BlockMeta, index, a_BlockMeta ); - - if ((OldBlockType == a_BlockType) && (OldBlockMeta == a_BlockMeta)) - { - return; - } - - MarkDirty(); - - { - cCSLock Lock(m_CSBlockLists); - m_PendingSendBlocks.push_back( index ); - } - - // ONLY recalculate lighting if it's necessary! - if( - (g_BlockLightValue[ OldBlockType ] != g_BlockLightValue[ a_BlockType ]) || - (g_BlockSpreadLightFalloff[ OldBlockType ] != g_BlockSpreadLightFalloff[ a_BlockType ]) || - (g_BlockTransparent[ OldBlockType ] != g_BlockTransparent[ a_BlockType ] ) - ) - { - m_IsLightValid = false; - } - - // Update heightmap, if needed: - if (a_RelY >= m_HeightMap[a_RelX + a_RelZ * Width]) - { - if (a_BlockType != E_BLOCK_AIR) - { - SetHeight(m_HeightMap, a_RelX, a_RelZ, a_RelY); - } - else - { - for (int y = a_RelY - 1; y > 0; --y) - { - if (cChunkDef::GetBlock(m_BlockTypes, a_RelX, y, a_RelZ) != E_BLOCK_AIR) - { - SetHeight(m_HeightMap, a_RelX, a_RelZ, y); - break; - } - } // for y - column in m_BlockData - } - } - - m_ToTickBlocks.push_back( MakeIndex( a_RelX, a_RelY, a_RelZ ) ); - m_ToTickBlocks.push_back( MakeIndex( a_RelX + 1, a_RelY, a_RelZ ) ); - m_ToTickBlocks.push_back( MakeIndex( a_RelX - 1, a_RelY, a_RelZ ) ); - m_ToTickBlocks.push_back( MakeIndex( a_RelX, a_RelY + 1, a_RelZ ) ); - m_ToTickBlocks.push_back( MakeIndex( a_RelX, a_RelY - 1, a_RelZ ) ); - m_ToTickBlocks.push_back( MakeIndex( a_RelX, a_RelY, a_RelZ + 1 ) ); - m_ToTickBlocks.push_back( MakeIndex( a_RelX, a_RelY, a_RelZ - 1 ) ); - - Vector3i WorldPos = PositionToWorldPosition( a_RelX, a_RelY, a_RelZ ); - cBlockEntity* BlockEntity = GetBlockEntity( WorldPos ); - if( BlockEntity ) - { - BlockEntity->Destroy(); - RemoveBlockEntity( BlockEntity ); - delete BlockEntity; - } - switch( a_BlockType ) - { - case E_BLOCK_CHEST: - { - AddBlockEntity( new cChestEntity( WorldPos.x, WorldPos.y, WorldPos.z, m_World) ); - break; - } - case E_BLOCK_FURNACE: - { - AddBlockEntity( new cFurnaceEntity( WorldPos.x, WorldPos.y, WorldPos.z, m_World) ); - break; - } - case E_BLOCK_SIGN_POST: - case E_BLOCK_WALLSIGN: - { - AddBlockEntity( new cSignEntity( (ENUM_BLOCK_ID)a_BlockType, WorldPos.x, WorldPos.y, WorldPos.z, m_World) ); - break; - } - } // switch (a_BlockType) -} - - - - - -void cChunk::FastSetBlock( int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta) -{ - ASSERT(!((a_X < 0 || a_X >= Width || a_Y < 0 || a_Y >= Height || a_Z < 0 || a_Z >= Width))); - - ASSERT(IsValid()); - - const int index = MakeIndexNoCheck( a_X, a_Y, a_Z ); - const BLOCKTYPE OldBlock = m_BlockTypes[index]; - const BLOCKTYPE OldBlockMeta = GetNibble( m_BlockMeta, index ); - if ((OldBlock == a_BlockType) && (OldBlockMeta == a_BlockMeta)) - { - return; - } - - MarkDirty(); - - m_BlockTypes[index] = a_BlockType; - - { - cCSLock Lock(m_CSBlockLists); - m_PendingSendBlocks.push_back( index ); - } - - SetNibble( m_BlockMeta, index, a_BlockMeta ); - - // ONLY recalculate lighting if it's necessary! - if( - (g_BlockLightValue[ OldBlock ] != g_BlockLightValue[ a_BlockType ]) || - (g_BlockSpreadLightFalloff[ OldBlock ] != g_BlockSpreadLightFalloff[ a_BlockType ]) || - (g_BlockTransparent[ OldBlock ] != g_BlockTransparent[ a_BlockType ] ) - ) - { - m_IsLightValid = false; - } - - // Update heightmap, if needed: - if (a_Y >= m_HeightMap[a_X + a_Z * Width]) - { - if (a_BlockType != E_BLOCK_AIR) - { - m_HeightMap[a_X + a_Z * Width] = (unsigned char)a_Y; - } - else - { - for (int y = a_Y - 1; y > 0; --y) - { - if (m_BlockTypes[MakeIndexNoCheck(a_X, y, a_Z)] != E_BLOCK_AIR) - { - m_HeightMap[a_X + a_Z * Width] = (unsigned char)y; - break; - } - } // for y - column in m_BlockData - } - } -} - - - - - -void cChunk::SendBlockTo( int a_X, int a_Y, int a_Z, cClientHandle* a_Client ) -{ - if( a_Client == 0 ) - { - cCSLock Lock(m_CSBlockLists); - unsigned int index = MakeIndex( a_X, a_Y, a_Z ); - if( index != INDEX_OUT_OF_RANGE ) - { - m_PendingSendBlocks.push_back( index ); - } - else - { - LOGWARN("cChunk::SendBlockTo Index out of range!"); - } - return; - } - - for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr ) - { - if ( *itr == a_Client ) - { - unsigned int index = MakeIndex( a_X, a_Y, a_Z ); - Vector3i WorldPos = PositionToWorldPosition( a_X, a_Y, a_Z ); - cPacket_BlockChange BlockChange; - BlockChange.m_PosX = WorldPos.x; - BlockChange.m_PosY = (unsigned char)WorldPos.y; - BlockChange.m_PosZ = WorldPos.z; - if( index != INDEX_OUT_OF_RANGE ) - { - BlockChange.m_BlockType = m_BlockTypes[ index ]; - BlockChange.m_BlockMeta = GetNibble( m_BlockMeta, index ); - } // else it's both 0 - a_Client->Send( BlockChange ); - break; - } - } -} - - - - - -void cChunk::AddBlockEntity( cBlockEntity* a_BlockEntity ) -{ - cCSLock Lock(m_CSBlockLists); - m_BlockEntities.push_back( a_BlockEntity ); -} - - - - - -cBlockEntity * cChunk::GetBlockEntity(int a_X, int a_Y, int a_Z) -{ - // Assumes that the m_CSBlockList is already locked, we're being called from SetBlock() - for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) - { - if ( - ((*itr)->GetPosX() == a_X) && - ((*itr)->GetPosY() == a_Y) && - ((*itr)->GetPosZ() == a_Z) - ) - { - return *itr; - } - } // for itr - m_BlockEntities[] - - return NULL; -} - - - - - -void cChunk::UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z) -{ - cBlockEntity * be = GetBlockEntity(a_X, a_Y, a_Z); - if (be != NULL) - { - be->UsedBy(a_Player); - } -} - - - - - -void cChunk::CollectPickupsByPlayer(cPlayer * a_Player) -{ - double PosX = a_Player->GetPosX(); - double PosY = a_Player->GetPosY(); - double PosZ = a_Player->GetPosZ(); - - for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) - { - if ( (*itr)->GetEntityType() != cEntity::eEntityType_Pickup ) - { - continue; // Only pickups - } - float DiffX = (float)((*itr)->GetPosX() - PosX ); - float DiffY = (float)((*itr)->GetPosY() - PosY ); - float DiffZ = (float)((*itr)->GetPosZ() - PosZ ); - float SqrDist = DiffX * DiffX + DiffY * DiffY + DiffZ * DiffZ; - if (SqrDist < 1.5f * 1.5f) // 1.5 block - { - MarkDirty(); - (reinterpret_cast(*itr))->CollectedBy( a_Player ); - } - } -} - - - - - -void cChunk::UpdateSign(int a_PosX, int a_PosY, int a_PosZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) -{ - // Also sends update packets to all clients in the chunk - for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) - { - if ( - ((*itr)->GetPosX() == a_PosX) && - ((*itr)->GetPosY() == a_PosY) && - ((*itr)->GetPosZ() == a_PosZ) && - ( - ((*itr)->GetBlockType() == E_BLOCK_WALLSIGN) || - ((*itr)->GetBlockType() == E_BLOCK_SIGN_POST) - ) - ) - { - MarkDirty(); - (reinterpret_cast(*itr))->SetLines(a_Line1, a_Line2, a_Line3, a_Line4); - (*itr)->SendTo(NULL); - } - } // for itr - m_BlockEntities[] -} - - - - - -void cChunk::RemoveBlockEntity( cBlockEntity* a_BlockEntity ) -{ - cCSLock Lock(m_CSBlockLists); - MarkDirty(); - m_BlockEntities.remove( a_BlockEntity ); -} - - - - - -bool cChunk::AddClient(cClientHandle* a_Client) -{ - for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) - { - if (a_Client == *itr) - { - // Already there, nothing needed - return false; - } - } - m_LoadedByClient.push_back( a_Client ); - - for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr ) - { - LOGD("cChunk: Entity #%d (%s) at [%i, %i, %i] spawning for player \"%s\"", (*itr)->GetUniqueID(), (*itr)->GetClass(), m_PosX, m_PosY, m_PosZ, a_Client->GetUsername().c_str() ); - (*itr)->SpawnOn( a_Client ); - } - return true; -} - - - - - -void cChunk::RemoveClient( cClientHandle* a_Client ) -{ - for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) - { - if (*itr != a_Client) - { - continue; - } - - m_LoadedByClient.erase(itr); - - if ( !a_Client->IsDestroyed() ) - { - for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr ) - { - LOGD("chunk [%i, %i] destroying entity #%i for player \"%s\"", m_PosX, m_PosZ, (*itr)->GetUniqueID(), a_Client->GetUsername().c_str() ); - cPacket_DestroyEntity DestroyEntity( *itr ); - a_Client->Send( DestroyEntity ); - } - } - return; - } // for itr - m_LoadedByClient[] -} - - - - - -bool cChunk::HasClient( cClientHandle* a_Client ) -{ - for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) - { - if ((*itr) == a_Client) - { - return true; - } - } - return false; -} - - - - - -bool cChunk::HasAnyClients(void) -{ - return !m_LoadedByClient.empty(); -} - - - - - -void cChunk::AddEntity( cEntity * a_Entity) -{ - if (a_Entity->GetEntityType() != cEntity::eEntityType_Player) - { - MarkDirty(); - } - m_Entities.push_back( a_Entity ); -} - - - - - -void cChunk::RemoveEntity(cEntity * a_Entity) -{ - size_t SizeBefore = m_Entities.size(); - m_Entities.remove(a_Entity); - size_t SizeAfter = m_Entities.size(); - - if (SizeBefore != SizeAfter) - { - // Mark as dirty if it was a server-generated entity: - if (a_Entity->GetEntityType() != cEntity::eEntityType_Player) - { - MarkDirty(); - } - } -} - - - - - -BLOCKTYPE cChunk::GetBlock( int a_X, int a_Y, int a_Z ) -{ - if ((a_X < 0) || (a_X >= Width) || (a_Y < 0) || (a_Y >= Height) || (a_Z < 0) || (a_Z >= Width)) return 0; // Clip - - return m_BlockTypes[ MakeIndexNoCheck( a_X, a_Y, a_Z ) ]; -} - - - - - -BLOCKTYPE cChunk::GetBlock( int a_BlockIdx ) -{ - if( a_BlockIdx < 0 || a_BlockIdx >= NumBlocks ) return 0; - return m_BlockTypes[ a_BlockIdx ]; -} - - - - - -void cChunk::GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) -{ - int Idx = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ); - a_BlockType = cChunkDef::GetBlock (m_BlockTypes, a_RelX, a_RelY, a_RelZ); - a_BlockMeta = cChunkDef::GetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ); -} - - - - - -/* -// _X 2012_02_23: Loading in old format not supported anymore -/// Loads the chunk from the old-format disk file, erases the file afterwards. Returns true if successful -bool cChunk::LoadFromDisk() -{ - AString SourceFile; - Printf(SourceFile, "world/X%i_Y%i_Z%i.bin", m_PosX, m_PosY, m_PosZ ); - - cFile f; - if (!f.Open(SourceFile, cFile::fmRead)) - { - return false; - } - - if (f.Read(m_BlockData, sizeof(m_BlockData)) != sizeof(m_BlockData)) - { - LOGERROR("ERROR READING FROM FILE %s", SourceFile.c_str()); - return false; - } - - // Now load Block Entities: - ENUM_BLOCK_ID BlockType; - while (f.Read(&BlockType, sizeof(ENUM_BLOCK_ID)) == sizeof(ENUM_BLOCK_ID)) - { - switch (BlockType) - { - case E_BLOCK_CHEST: - { - cChestEntity * ChestEntity = new cChestEntity( 0, 0, 0, m_World ); - if (!ChestEntity->LoadFromFile(f)) - { - LOGERROR("ERROR READING CHEST FROM FILE %s", SourceFile.c_str()); - delete ChestEntity; - return false; - } - m_BlockEntities.push_back( ChestEntity ); - break; - } - - case E_BLOCK_FURNACE: - { - cFurnaceEntity* FurnaceEntity = new cFurnaceEntity( 0, 0, 0, m_World ); - if (!FurnaceEntity->LoadFromFile(f)) - { - LOGERROR("ERROR READING FURNACE FROM FILE %s", SourceFile.c_str()); - delete FurnaceEntity; - return false; - } - m_BlockEntities.push_back( FurnaceEntity ); - break; - } - - case E_BLOCK_SIGN_POST: - case E_BLOCK_WALLSIGN: - { - cSignEntity * SignEntity = new cSignEntity(BlockType, 0, 0, 0, m_World ); - if (!SignEntity->LoadFromFile( f ) ) - { - LOGERROR("ERROR READING SIGN FROM FILE %s", SourceFile.c_str()); - delete SignEntity; - return false; - } - m_BlockEntities.push_back( SignEntity ); - break; - } - - default: - { - ASSERT(!"Unhandled block entity in file"); - break; - } - } - } - f.Close(); - - // Delete old format file - if (std::remove(SourceFile.c_str()) != 0) - { - LOGERROR("Could not delete file %s", SourceFile.c_str()); - } - else - { - LOGINFO("Successfully deleted old format file \"%s\"", SourceFile.c_str()); - } - m_IsDirty = false; - return true; -} -*/ - - - - - -void cChunk::Broadcast( const cPacket * a_Packet, cClientHandle* a_Exclude) -{ - for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr ) - { - if (*itr == a_Exclude) - { - continue; - } - (*itr)->Send(*a_Packet); - } // for itr - LoadedByClient[] -} - - - - - -void cChunk::PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, int & a_X, int & a_Y, int & a_Z) -{ - a_Y = a_ChunkY; - a_X = m_PosX * Width + a_ChunkX; - a_Z = m_PosZ * Width + a_ChunkZ; -} - - - - - -Vector3i cChunk::PositionToWorldPosition( int a_ChunkX, int a_ChunkY, int a_ChunkZ ) -{ - return Vector3i( m_PosX * Width + a_ChunkX, m_PosY * Height + a_ChunkY, m_PosZ * Width + a_ChunkZ ); -} - - - - - -#if !C_CHUNK_USE_INLINE -# include "cChunk.inl.h" -#endif - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#ifndef _WIN32 + #include +#endif + + +#include "cChunk.h" +#include "cWorld.h" +#include "cWaterSimulator.h" +#include "cLavaSimulator.h" +#include "cClientHandle.h" +#include "cServer.h" +#include "zlib.h" +#include "Defines.h" +#include "cChestEntity.h" +#include "cFurnaceEntity.h" +#include "cSignEntity.h" +#include "cTorch.h" +#include "cLadder.h" +#include "cPickup.h" +#include "cRedstone.h" +#include "cItem.h" +#include "cNoise.h" +#include "cRoot.h" +#include "cBlockToPickup.h" +#include "MersenneTwister.h" +#include "cPlayer.h" + +#include "packets/cPacket_DestroyEntity.h" +#include "packets/cPacket_PreChunk.h" +#include "packets/cPacket_BlockChange.h" +#include "packets/cPacket_MultiBlock.h" + +#include + + + + + +extern bool g_bWaterPhysics; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// sSetBlock: + +sSetBlock::sSetBlock( int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) // absolute block position + : x( a_BlockX ) + , y( a_BlockY ) + , z( a_BlockZ ) + , BlockType( a_BlockType ) + , BlockMeta( a_BlockMeta ) +{ + cChunkDef::AbsoluteToRelative(x, y, z, ChunkX, ChunkZ); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cChunk: + +cChunk::cChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkMap * a_ChunkMap, cWorld * a_World) + : m_PosX( a_ChunkX ) + , m_PosY( a_ChunkY ) + , m_PosZ( a_ChunkZ ) + , m_BlockTickX( 0 ) + , m_BlockTickY( 0 ) + , m_BlockTickZ( 0 ) + , m_World( a_World ) + , m_ChunkMap(a_ChunkMap) + , m_IsValid(false) + , m_IsLightValid(false) + , m_IsDirty(false) + , m_IsSaving(false) + , m_StayCount(0) +{ + // LOGINFO("### new cChunk (%i, %i) at %p, thread 0x%x ###", a_X, a_Z, this, GetCurrentThreadId()); +} + + + + + +cChunk::~cChunk() +{ + // LOGINFO("### delete cChunk() (%i, %i) from %p, thread 0x%x ###", m_PosX, m_PosZ, this, GetCurrentThreadId() ); + + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) + { + delete *itr; + } + m_BlockEntities.clear(); + + // Remove and destroy all entities that are not players: + cEntityList Entities; + for (cEntityList::const_iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) + { + if ((*itr)->GetEntityType() != cEntity::eEntityType_Player) + { + Entities.push_back(*itr); + } + } + for (cEntityList::iterator itr = Entities.begin(); itr != Entities.end(); ++itr) + { + (*itr)->RemoveFromChunk(); + (*itr)->Destroy(); + } + m_Entities.clear(); +} + + + + + +void cChunk::SetValid(void) +{ + m_IsValid = true; + + m_World->GetChunkMap()->ChunkValidated(); +} + + + + + +void cChunk::MarkRegenerating(void) +{ + // Tell all clients attached to this chunk that they want this chunk: + for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) + { + (*itr)->AddWantedChunk(m_PosX, m_PosZ); + } // for itr - m_LoadedByClient[] +} + + + + + +bool cChunk::CanUnload(void) +{ + return m_LoadedByClient.empty() && !m_IsDirty && (m_StayCount == 0); +} + + + + + +void cChunk::MarkSaving(void) +{ + m_IsSaving = true; +} + + + + + +void cChunk::MarkSaved(void) +{ + if (!m_IsSaving) + { + return; + } + m_IsDirty = false; +} + + + + + +void cChunk::MarkLoaded(void) +{ + m_IsDirty = false; + SetValid(); +} + + + + + +void cChunk::MarkLoadFailed(void) +{ + if (m_IsValid) + { + return; + } + + m_HasLoadFailed = true; +} + + + + + +void cChunk::GetAllData(cChunkDataCallback & a_Callback) +{ + a_Callback.HeightMap (&m_HeightMap); + a_Callback.BiomeData (&m_BiomeMap); + a_Callback.BlockTypes (m_BlockTypes); + a_Callback.BlockMeta (m_BlockMeta); + a_Callback.LightIsValid (m_IsLightValid); + a_Callback.BlockLight (m_BlockLight); + a_Callback.BlockSkyLight(m_BlockSkyLight); + + for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) + { + a_Callback.Entity(*itr); + } + + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) + { + a_Callback.BlockEntity(*itr); + } +} + + + + + +void cChunk::SetAllData( + const BLOCKTYPE * a_BlockTypes, + const NIBBLETYPE * a_BlockMeta, + const NIBBLETYPE * a_BlockLight, + const NIBBLETYPE * a_BlockSkyLight, + const HeightMap * a_HeightMap, + const BiomeMap & a_BiomeMap, + cEntityList & a_Entities, + cBlockEntityList & a_BlockEntities +) +{ + memcpy(m_BiomeMap, a_BiomeMap, sizeof(m_BiomeMap)); + + if (a_HeightMap != NULL) + { + memcpy(m_HeightMap, a_HeightMap, sizeof(m_HeightMap)); + } + + memcpy(m_BlockTypes, a_BlockTypes, sizeof(m_BlockTypes)); + memcpy(m_BlockMeta, a_BlockMeta, sizeof(m_BlockMeta)); + if (a_BlockLight != NULL) + { + memcpy(m_BlockLight, a_BlockLight, sizeof(m_BlockLight)); + } + if (a_BlockSkyLight != NULL) + { + memcpy(m_BlockSkyLight, a_BlockSkyLight, sizeof(m_BlockSkyLight)); + } + + m_IsLightValid = (a_BlockLight != NULL) && (a_BlockSkyLight != NULL); + + if (a_HeightMap == NULL) + { + CalculateHeightmap(); + } + + // Append entities to current entity list: + m_Entities.splice(m_Entities.end(), a_Entities); + + // Clear the block entities present - either the loader / saver has better, or we'll create empty ones: + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) + { + delete *itr; + } + std::swap(a_BlockEntities, m_BlockEntities); + + // Create block entities that the loader didn't load; fill them with defaults + CreateBlockEntities(); + + m_HasLoadFailed = false; +} + + + + + +void cChunk::SetLight( + const cChunkDef::BlockNibbles & a_BlockLight, + const cChunkDef::BlockNibbles & a_SkyLight +) +{ + // TODO: We might get cases of wrong lighting when a chunk changes in the middle of a lighting calculation. + // Postponing until we see how bad it is :) + memcpy(m_BlockLight, a_BlockLight, sizeof(m_BlockLight)); + memcpy(m_BlockSkyLight, a_SkyLight, sizeof(m_BlockSkyLight)); + m_IsLightValid = true; +} + + + + + +void cChunk::GetBlockTypes(BLOCKTYPE * a_BlockTypes) +{ + memcpy(a_BlockTypes, m_BlockTypes, NumBlocks); +} + + + + + +void cChunk::GetBlockData(BLOCKTYPE * a_BlockData) +{ + memcpy(a_BlockData, m_BlockTypes, NumBlocks); + memcpy(a_BlockData + MetaOffset, m_BlockMeta, NumBlocks / 2); + memcpy(a_BlockData + LightOffset, m_BlockLight, NumBlocks / 2); + memcpy(a_BlockData + SkyLightOffset, m_BlockSkyLight, NumBlocks / 2); +} + + + + + +/// Returns true if there is a block entity at the coords specified +bool cChunk::HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) + { + if ( + ((*itr)->GetPosX() == a_BlockX) && + ((*itr)->GetPosY() == a_BlockY) && + ((*itr)->GetPosZ() == a_BlockZ) + ) + { + return true; + } + } // for itr - m_BlockEntities[] + return false; +} + + + + + +/// Sets or resets the internal flag that prevents chunk from being unloaded +void cChunk::Stay(bool a_Stay) +{ + m_StayCount += (a_Stay ? 1 : -1); + ASSERT(m_StayCount >= 0); +} + + + + + +void cChunk::Tick(float a_Dt, MTRand & a_TickRandom) +{ + cCSLock Lock(m_CSBlockLists); + unsigned int PendingSendBlocks = m_PendingSendBlocks.size(); + if( PendingSendBlocks > 1 ) + { + cPacket_MultiBlock MultiBlock; + MultiBlock.m_ChunkX = m_PosX; + MultiBlock.m_ChunkZ = m_PosZ; + MultiBlock.m_NumBlocks = (short)PendingSendBlocks; + MultiBlock.m_Data = new cPacket_MultiBlock::sBlockChange[ PendingSendBlocks ]; + MultiBlock.m_DataSize = PendingSendBlocks * sizeof( cPacket_MultiBlock::sBlockChange ); + //LOG("Sending multiblock packet for %i blocks", PendingSendBlocks ); + for( unsigned int i = 0; i < PendingSendBlocks; i++) + { + unsigned int index = m_PendingSendBlocks[i]; + Vector3i BlockPos = IndexToCoordinate( index ); + + unsigned int Coords = BlockPos.y | (BlockPos.z << 8) | (BlockPos.x << 12); + unsigned int Blocks = GetNibble( m_BlockMeta, index ) | (m_BlockTypes[index] << 4); + MultiBlock.m_Data[i].Data = Coords << 16 | Blocks; + } + m_PendingSendBlocks.clear(); + PendingSendBlocks = m_PendingSendBlocks.size(); + Broadcast( MultiBlock ); + } + if( PendingSendBlocks > 0 ) + { + for( unsigned int i = 0; i < PendingSendBlocks; i++) + { + unsigned int index = m_PendingSendBlocks[i]; + Vector3i WorldPos = PositionToWorldPosition( IndexToCoordinate( index ) ); + + cPacket_BlockChange BlockChange; + BlockChange.m_PosX = WorldPos.x; + BlockChange.m_PosY = (unsigned char)WorldPos.y; + BlockChange.m_PosZ = WorldPos.z; + BlockChange.m_BlockType = m_BlockTypes[index]; + BlockChange.m_BlockMeta = GetNibble( m_BlockMeta, index ); + Broadcast( BlockChange ); + } + m_PendingSendBlocks.clear(); + } + Lock.Unlock(); + + while ( !m_UnloadQuery.empty() ) + { + cPacket_PreChunk UnloadPacket; + UnloadPacket.m_PosX = GetPosX(); + UnloadPacket.m_PosZ = GetPosZ(); + UnloadPacket.m_bLoad = false; // Unload + (*m_UnloadQuery.begin())->Send( UnloadPacket ); + m_UnloadQuery.remove( *m_UnloadQuery.begin() ); + } + + CheckBlocks(); + + TickBlocks(a_TickRandom); + + // Tick block entities (furnaces) + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) + { + if ((*itr)->GetBlockType() == E_BLOCK_FURNACE) + { + m_IsDirty = ((cFurnaceEntity *)(*itr))->Tick( a_Dt ) | m_IsDirty; + } + } +} + + + + + +void cChunk::CheckBlocks(void) +{ + cCSLock Lock2(m_CSBlockLists); + unsigned int NumTickBlocks = m_ToTickBlocks.size(); + Lock2.Unlock(); + + if (NumTickBlocks == 0) + { + return; + } + + Lock2.Lock(); + std::deque< unsigned int > ToTickBlocks = m_ToTickBlocks; + m_ToTickBlocks.clear(); + Lock2.Unlock(); + + for (std::deque< unsigned int >::const_iterator itr = ToTickBlocks.begin(); itr != ToTickBlocks.end(); ++itr) + { + unsigned int index = (*itr); + Vector3i BlockPos = IndexToCoordinate(index); + + BLOCKTYPE BlockType = GetBlock(index); + NIBBLETYPE BlockMeta = GetMeta (index); + switch (BlockType) + { + // Stuff that drops when block below is destroyed: + case E_BLOCK_REDSTONE_REPEATER_OFF: + case E_BLOCK_REDSTONE_REPEATER_ON: + case E_BLOCK_REDSTONE_WIRE: + case E_BLOCK_CACTUS: + case E_BLOCK_REEDS: + case E_BLOCK_WOODEN_PRESSURE_PLATE: + case E_BLOCK_STONE_PRESSURE_PLATE: + case E_BLOCK_MINECART_TRACKS: + case E_BLOCK_SIGN_POST: + case E_BLOCK_CROPS: + case E_BLOCK_SAPLING: + case E_BLOCK_YELLOW_FLOWER: + case E_BLOCK_RED_ROSE: + case E_BLOCK_RED_MUSHROOM: + case E_BLOCK_BROWN_MUSHROOM: + case E_BLOCK_SNOW: + { + if (GetBlock(BlockPos.x, BlockPos.y - 1, BlockPos.z) == E_BLOCK_AIR) + { + SetBlock( BlockPos, E_BLOCK_AIR, 0 ); + + Vector3i WorldPos = PositionToWorldPosition( BlockPos ); + + m_World->GetSimulatorManager()->WakeUp(WorldPos.x, WorldPos.y, WorldPos.z); + + cItems Pickups; + cBlockToPickup::ToPickup(BlockType, BlockMeta, E_ITEM_EMPTY, Pickups); + m_World->SpawnItemPickups(Pickups, WorldPos.x, WorldPos.y, WorldPos.z); + } + break; + } + + case E_BLOCK_REDSTONE_TORCH_OFF: + case E_BLOCK_REDSTONE_TORCH_ON: + case E_BLOCK_TORCH: + { + char Dir = cTorch::MetaDataToDirection( GetNibble( m_BlockMeta, BlockPos ) ); + Vector3i WorldPos = PositionToWorldPosition( BlockPos ); + + Vector3i AttachedTo = WorldPos; + AddDirection( AttachedTo.x, AttachedTo.y, AttachedTo.z, Dir, true ); + if( m_World->GetBlock( AttachedTo ) == E_BLOCK_AIR ) + { + SetBlock( BlockPos, E_BLOCK_AIR, 0 ); + + m_World->GetSimulatorManager()->WakeUp(WorldPos.x, WorldPos.y, WorldPos.z); + + cItems Pickups; + cBlockToPickup::ToPickup(BlockType, BlockMeta, E_ITEM_EMPTY, Pickups); + m_World->SpawnItemPickups(Pickups, WorldPos.x, WorldPos.y, WorldPos.z); + } + break; + } + + case E_BLOCK_LADDER: + { + char Dir = cLadder::MetaDataToDirection( GetNibble( m_BlockMeta, BlockPos ) ); + Vector3i WorldPos = PositionToWorldPosition( BlockPos ); + Vector3i AttachedTo = WorldPos; + AddDirection( AttachedTo.x, AttachedTo.y, AttachedTo.z, Dir, true ); + if( m_World->GetBlock( AttachedTo ) == E_BLOCK_AIR ) + { + SetBlock( BlockPos, E_BLOCK_AIR, 0 ); + cItems Pickups; + cBlockToPickup::ToPickup(BlockType, BlockMeta, E_ITEM_EMPTY, Pickups); + m_World->SpawnItemPickups(Pickups, WorldPos.x, WorldPos.y, WorldPos.z); + } + break; + } + } // switch (BlockType) + } // for itr - ToTickBlocks[] +} + + + + + +void cChunk::TickBlocks(MTRand & a_TickRandom) +{ + // Tick dem blocks + // _X: We must limit the random number or else we get a nasty int overflow bug ( http://forum.mc-server.org/showthread.php?tid=457 ) + int RandomX = a_TickRandom.randInt(0x00ffffff); + int RandomY = a_TickRandom.randInt(0x00ffffff); + int RandomZ = a_TickRandom.randInt(0x00ffffff); + int TickX = m_BlockTickX; + int TickY = m_BlockTickY; + int TickZ = m_BlockTickZ; + + // This for loop looks disgusting, but it actually does a simple thing - first processes m_BlockTick, then adds random to it + // This is so that SetNextBlockTick() works + for (int i = 0; i < 50; i++, + + // This weird construct (*2, then /2) is needed, + // otherwise the blocktick distribution is too biased towards even coords! + + TickX = (TickX + RandomX) % (Width * 2), + TickY = (TickY + RandomY) % (Height * 2), + TickZ = (TickZ + RandomZ) % (Width * 2), + m_BlockTickX = TickX / 2, + m_BlockTickY = TickY / 2, + m_BlockTickZ = TickZ / 2 + ) + { + + if (m_BlockTickY > cChunkDef::GetHeight(m_HeightMap, m_BlockTickX, m_BlockTickZ)) + { + continue; // It's all air up here + } + + unsigned int Index = MakeIndexNoCheck( m_BlockTickX, m_BlockTickY, m_BlockTickZ ); + BLOCKTYPE ID = m_BlockTypes[Index]; + switch( ID ) + { + case E_BLOCK_CROPS: + { + NIBBLETYPE Meta = GetMeta(Index); + if (Meta < 7) + { + FastSetBlock(m_BlockTickX, m_BlockTickY, m_BlockTickZ, E_BLOCK_CROPS, ++Meta); + } + break; + } + + case E_BLOCK_GRASS: TickGrass (m_BlockTickX, m_BlockTickY, m_BlockTickZ, a_TickRandom); break; + case E_BLOCK_PUMPKIN_STEM: + case E_BLOCK_MELON_STEM: TickMelonPumpkin(m_BlockTickX, m_BlockTickY, m_BlockTickZ, Index, ID, a_TickRandom); break; + case E_BLOCK_FARMLAND: TickFarmland (m_BlockTickX, m_BlockTickY, m_BlockTickZ); break; + case E_BLOCK_SUGARCANE: GrowSugarcane (m_BlockTickX, m_BlockTickY, m_BlockTickZ, 1); break; + case E_BLOCK_CACTUS: GrowCactus (m_BlockTickX, m_BlockTickY, m_BlockTickZ, 1); break; + + case E_BLOCK_SAPLING: + { + // Check the highest bit, if set, grow the tree, if not, set it (1-bit delay): + NIBBLETYPE Meta = GetMeta(m_BlockTickX, m_BlockTickY, m_BlockTickZ); + if ((Meta & 0x08) != 0) + { + m_World->GrowTree( m_BlockTickX + m_PosX*Width, m_BlockTickY, m_BlockTickZ + m_PosZ*Width ); + } + else + { + SetMeta(m_BlockTickX, m_BlockTickY, m_BlockTickZ, Meta | 0x08); + } + break; + } + + case E_BLOCK_LEAVES: //todo, http://www.minecraftwiki.net/wiki/Data_values#Leaves + { + break; + } + + default: + { + break; + } + } + } +} + + + + + +void cChunk::TickGrass(int a_RelX, int a_RelY, int a_RelZ, MTRand & a_TickRandom) +{ + // Grass turns into dirt if there's another block on top of it: + { + BLOCKTYPE AboveBlock = cChunkDef::GetBlock(m_BlockTypes, a_RelX, a_RelY + 1, a_RelZ); + if (!((g_BlockOneHitDig[AboveBlock]) || (g_BlockTransparent[AboveBlock]))) + { + FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, 0); + return; + } + } + + // Grass spreads to nearby blocks if there's enough light (TODO) and free space above that block + // Ref.: http://www.minecraftwiki.net/wiki/Grass_Block#Growth + for (int i = 0; i < 2; i++) // Pick two blocks to grow to + { + int OfsX = a_TickRandom.randInt(2) - 1; // [-1 .. 1] + int OfsY = a_TickRandom.randInt(4) - 3; // [-3 .. 1] + int OfsZ = a_TickRandom.randInt(2) - 1; // [-1 .. 1] + + BLOCKTYPE DestBlock; + NIBBLETYPE DestMeta; + if ( + !UnboundedRelGetBlock(a_RelX + OfsX, a_RelY + OfsY, a_RelZ + OfsZ, DestBlock, DestMeta) || + (DestBlock != E_BLOCK_DIRT) + ) + { + continue; + } + + BLOCKTYPE AboveDest; + NIBBLETYPE AboveMeta; + if ( + UnboundedRelGetBlock(a_RelX + OfsX, a_RelY + OfsY + 1, a_RelZ + OfsZ, AboveDest, AboveMeta) && + ((g_BlockOneHitDig[AboveDest]) || (g_BlockTransparent[AboveDest])) + // TODO: Query dest light, if it's enough + ) + { + UnboundedRelFastSetBlock(a_RelX + OfsX, a_RelY + OfsY, a_RelZ + OfsZ, E_BLOCK_GRASS, 0); + } + } // for i - repeat twice +} + + + + + +void cChunk::TickMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, int a_BlockIdx, BLOCKTYPE a_BlockType, MTRand & a_TickRandom) +{ + NIBBLETYPE Meta = GetMeta(a_BlockIdx); + if (Meta < 7) + { + FastSetBlock(m_BlockTickX, m_BlockTickY, m_BlockTickZ, a_BlockType, ++Meta); + return; + } + GrowMelonPumpkin(a_RelX, a_RelY, a_RelZ, a_BlockType, a_TickRandom); +} + + + + + +void cChunk::TickFarmland(int a_RelX, int a_RelY, int a_RelZ) +{ + // TODO: Rain hydrates blocks, too. Check world weather, don't search for water if raining. + + // Search for water in a close proximity: + // Ref.: http://www.minecraftwiki.net/wiki/Farmland#Hydrated_Farmland_Tiles + bool Found = false; + for (int y = a_RelY; y <= a_RelY + 1; y++) + { + for (int z = a_RelZ - 4; z <= a_RelZ + 4; z++) + { + for (int x = a_RelX - 4; x <= a_RelX + 4; x++) + { + BLOCKTYPE BlockType; + NIBBLETYPE Meta; // unused + + if (!UnboundedRelGetBlock(x, y, z, BlockType, Meta)) + { + // Too close to an unloaded chunk, we might miss a water block there, so don't tick at all + return; + } + if ( + (BlockType == E_BLOCK_WATER) || + (BlockType == E_BLOCK_STATIONARY_WATER) + ) + { + Found = true; + break; + } + } // for x + if (Found) + { + break; + } + } // for z + if (Found) + { + break; + } + } // for y + + NIBBLETYPE BlockMeta = GetMeta(a_RelX, a_RelY, a_RelZ); + + if (Found) + { + // Water was found, hydrate the block until hydration reaches 7: + if (BlockMeta < 7) + { + FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_FARMLAND, ++BlockMeta); + } + return; + } + + // Water wasn't found, de-hydrate block: + if (BlockMeta > 0) + { + FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_FARMLAND, --BlockMeta); + return; + } + + // Farmland too dry. Turn back to dirt: + FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, 0); + + // TODO: Uproot whatever was growing on top: +} + + + + + +void cChunk::GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, MTRand & a_TickRandom) +{ + // Convert the stem BlockType into produce BlockType + BLOCKTYPE ProduceType; + switch (a_BlockType) + { + case E_BLOCK_MELON_STEM: ProduceType = E_BLOCK_MELON; break; + case E_BLOCK_PUMPKIN_STEM: ProduceType = E_BLOCK_PUMPKIN; break; + default: + { + ASSERT(!"Unhandled blocktype in TickMelonPumpkin()"); + return; + } + } + + // Check if there's another melon / pumpkin around that stem, if so, abort: + bool IsValid; + BLOCKTYPE BlockType[4]; + NIBBLETYPE BlockMeta; // unused + IsValid = UnboundedRelGetBlock(a_RelX + 1, a_RelY, a_RelZ, BlockType[0], BlockMeta); + IsValid = IsValid && UnboundedRelGetBlock(a_RelX - 1, a_RelY, a_RelZ, BlockType[1], BlockMeta); + IsValid = IsValid && UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ + 1, BlockType[2], BlockMeta); + IsValid = IsValid && UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ - 1, BlockType[3], BlockMeta); + if ( + !IsValid || + (BlockType[0] == ProduceType) || + (BlockType[1] == ProduceType) || + (BlockType[2] == ProduceType) || + (BlockType[3] == ProduceType) + ) + { + // Neighbors not valid or already taken by the same produce + return; + } + + // Pick a direction in which to place the produce: + int x = 0, z = 0; + int CheckType = a_TickRandom.randInt(3); // The index to the neighbors array which should be checked for emptiness + switch (CheckType) + { + case 0: x = 1; break; + case 1: x = -1; break; + case 2: z = 1; break; + case 3: z = -1; break; + } + + // Check that the block in that direction is empty: + switch (BlockType[CheckType]) + { + case E_BLOCK_AIR: + case E_BLOCK_SNOW: + case E_BLOCK_TALL_GRASS: + case E_BLOCK_DEAD_BUSH: + { + break; + } + default: return; + } + + // Check if there's soil under the neighbor. We already know the neighbors are valid. Place produce if ok + BLOCKTYPE Soil; + UnboundedRelGetBlock(a_RelX + x, a_RelY - 1, a_RelZ + z, Soil, BlockMeta); + switch (Soil) + { + case E_BLOCK_DIRT: + case E_BLOCK_GRASS: + case E_BLOCK_FARMLAND: + { + // Place a randomly-facing produce: + UnboundedRelFastSetBlock(a_RelX + x, a_RelY, a_RelZ + z, ProduceType, (NIBBLETYPE)(a_TickRandom.randInt(4) % 4)); + break; + } + } +} + + + + + +void cChunk::GrowSugarcane(int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks) +{ + // Check the total height of the sugarcane blocks here: + int Top = a_RelY + 1; + while ( + (Top < cChunkDef::Height) && + (GetBlock(a_RelX, Top, a_RelZ) == E_BLOCK_SUGARCANE) + ) + { + ++Top; + } + int Bottom = a_RelY - 1; + while ( + (Bottom > 0) && + (GetBlock(a_RelX, Bottom, a_RelZ) == E_BLOCK_SUGARCANE) + ) + { + --Bottom; + } + + // Grow by at most a_NumBlocks, but no more than max height: + int ToGrow = std::min(a_NumBlocks, m_World->GetMaxSugarcaneHeight() + 1 - (Top - Bottom)); + for (int i = 0; i < ToGrow; i++) + { + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + if (UnboundedRelGetBlock(a_RelX, Top + i, a_RelZ, BlockType, BlockMeta) && (BlockType == E_BLOCK_AIR)) + { + UnboundedRelFastSetBlock(a_RelX, Top + i, a_RelZ, E_BLOCK_SUGARCANE, 0); + } + else + { + break; + } + } // for i +} + + + + + +void cChunk::GrowCactus(int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks) +{ + // Check the total height of the sugarcane blocks here: + int Top = a_RelY + 1; + while ( + (Top < cChunkDef::Height) && + (GetBlock(a_RelX, Top, a_RelZ) == E_BLOCK_CACTUS) + ) + { + ++Top; + } + int Bottom = a_RelY - 1; + while ( + (Bottom > 0) && + (GetBlock(a_RelX, Bottom, a_RelZ) == E_BLOCK_CACTUS) + ) + { + --Bottom; + } + + // Grow by at most a_NumBlocks, but no more than max height: + int ToGrow = std::min(a_NumBlocks, m_World->GetMaxCactusHeight() + 1 - (Top - Bottom)); + for (int i = 0; i < ToGrow; i++) + { + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + if (UnboundedRelGetBlock(a_RelX, Top + i, a_RelZ, BlockType, BlockMeta) && (BlockType == E_BLOCK_AIR)) + { + // TODO: Check the surrounding blocks, if they aren't air, break the cactus block into pickups (and continue breaking blocks above in the next loop iterations) + UnboundedRelFastSetBlock(a_RelX, Top + i, a_RelZ, E_BLOCK_CACTUS, 0); + } + else + { + break; + } + } // for i +} + + + + + +bool cChunk::UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) +{ + if ((a_RelY < 0) || (a_RelY > cChunkDef::Height)) + { + return false; + } + + if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width)) + { + int BlockIdx = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ); + a_BlockType = GetBlock(BlockIdx); + a_BlockMeta = GetMeta(BlockIdx); + return true; + } + return m_ChunkMap->LockedGetBlock( + m_PosX * cChunkDef::Width + a_RelX, + ZERO_CHUNK_Y * cChunkDef::Height + a_RelY, + m_PosZ * cChunkDef::Width + a_RelZ, + a_BlockType, a_BlockMeta + ); +} + + + + + +bool cChunk::UnboundedRelSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width)) + { + SetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); + return true; + } + return m_ChunkMap->LockedSetBlock( + m_PosX * cChunkDef::Width + a_RelX, + ZERO_CHUNK_Y * cChunkDef::Height + a_RelY, + m_PosZ * cChunkDef::Width + a_RelZ, + a_BlockType, a_BlockMeta + ); +} + + + + + +bool cChunk::UnboundedRelFastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width)) + { + FastSetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); + return true; + } + return m_ChunkMap->LockedFastSetBlock( + m_PosX * cChunkDef::Width + a_RelX, + ZERO_CHUNK_Y * cChunkDef::Height + a_RelY, + m_PosZ * cChunkDef::Width + a_RelZ, + a_BlockType, a_BlockMeta + ); +} + + + + + +int cChunk::GetHeight( int a_X, int a_Z ) +{ + ASSERT((a_X >= 0) && (a_X < Width) && (a_Z >= 0) && (a_Z < Width)); + + if ((a_X >= 0) && (a_X < Width) && (a_Z >= 0) && (a_Z < Width)) + { + return m_HeightMap[a_X + a_Z * Width]; + } + return 0; +} + + + + + +void cChunk::CreateBlockEntities(void) +{ + for (int x = 0; x < Width; x++) + { + for (int z = 0; z < Width; z++) + { + for (int y = 0; y < Height; y++) + { + ENUM_BLOCK_ID BlockType = (ENUM_BLOCK_ID)m_BlockTypes[ MakeIndex( x, y, z ) ]; + switch ( BlockType ) + { + case E_BLOCK_CHEST: + { + if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width)) + { + m_BlockEntities.push_back( new cChestEntity( x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) ); + } + break; + } + + case E_BLOCK_FURNACE: + { + if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width)) + { + m_BlockEntities.push_back( new cFurnaceEntity( x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) ); + } + break; + } + + case E_BLOCK_SIGN_POST: + case E_BLOCK_WALLSIGN: + { + if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width)) + { + m_BlockEntities.push_back( new cSignEntity( BlockType, x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) ); + } + break; + } + } // switch (BlockType) + } // for y + } // for z + } // for x +} + + + + + +void cChunk::CalculateHeightmap() +{ + for (int x = 0; x < Width; x++) + { + for (int z = 0; z < Width; z++) + { + for (int y = Height - 1; y > -1; y--) + { + int index = MakeIndex( x, y, z ); + if (m_BlockTypes[index] != E_BLOCK_AIR) + { + m_HeightMap[x + z * Width] = (unsigned char)y; + break; + } + } // for y + } // for z + } // for x +} + + + + + +void cChunk::SetBlock( int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) +{ + if (a_RelX < 0 || a_RelX >= Width || a_RelY < 0 || a_RelY >= Height || a_RelZ < 0 || a_RelZ >= Width) + { + return; // Clip + } + + ASSERT(IsValid()); // Is this chunk loaded / generated? + + int index = MakeIndexNoCheck( a_RelX, a_RelY, a_RelZ ); + BLOCKTYPE OldBlockMeta = GetNibble( m_BlockMeta, index ); + BLOCKTYPE OldBlockType = m_BlockTypes[index]; + m_BlockTypes[index] = a_BlockType; + + SetNibble( m_BlockMeta, index, a_BlockMeta ); + + if ((OldBlockType == a_BlockType) && (OldBlockMeta == a_BlockMeta)) + { + return; + } + + MarkDirty(); + + { + cCSLock Lock(m_CSBlockLists); + m_PendingSendBlocks.push_back( index ); + } + + // ONLY recalculate lighting if it's necessary! + if( + (g_BlockLightValue[ OldBlockType ] != g_BlockLightValue[ a_BlockType ]) || + (g_BlockSpreadLightFalloff[ OldBlockType ] != g_BlockSpreadLightFalloff[ a_BlockType ]) || + (g_BlockTransparent[ OldBlockType ] != g_BlockTransparent[ a_BlockType ] ) + ) + { + m_IsLightValid = false; + } + + // Update heightmap, if needed: + if (a_RelY >= m_HeightMap[a_RelX + a_RelZ * Width]) + { + if (a_BlockType != E_BLOCK_AIR) + { + SetHeight(m_HeightMap, a_RelX, a_RelZ, a_RelY); + } + else + { + for (int y = a_RelY - 1; y > 0; --y) + { + if (cChunkDef::GetBlock(m_BlockTypes, a_RelX, y, a_RelZ) != E_BLOCK_AIR) + { + SetHeight(m_HeightMap, a_RelX, a_RelZ, y); + break; + } + } // for y - column in m_BlockData + } + } + + m_ToTickBlocks.push_back( MakeIndex( a_RelX, a_RelY, a_RelZ ) ); + m_ToTickBlocks.push_back( MakeIndex( a_RelX + 1, a_RelY, a_RelZ ) ); + m_ToTickBlocks.push_back( MakeIndex( a_RelX - 1, a_RelY, a_RelZ ) ); + m_ToTickBlocks.push_back( MakeIndex( a_RelX, a_RelY + 1, a_RelZ ) ); + m_ToTickBlocks.push_back( MakeIndex( a_RelX, a_RelY - 1, a_RelZ ) ); + m_ToTickBlocks.push_back( MakeIndex( a_RelX, a_RelY, a_RelZ + 1 ) ); + m_ToTickBlocks.push_back( MakeIndex( a_RelX, a_RelY, a_RelZ - 1 ) ); + + Vector3i WorldPos = PositionToWorldPosition( a_RelX, a_RelY, a_RelZ ); + cBlockEntity* BlockEntity = GetBlockEntity( WorldPos ); + if( BlockEntity ) + { + BlockEntity->Destroy(); + RemoveBlockEntity( BlockEntity ); + delete BlockEntity; + } + switch( a_BlockType ) + { + case E_BLOCK_CHEST: + { + AddBlockEntity( new cChestEntity( WorldPos.x, WorldPos.y, WorldPos.z, m_World) ); + break; + } + case E_BLOCK_FURNACE: + { + AddBlockEntity( new cFurnaceEntity( WorldPos.x, WorldPos.y, WorldPos.z, m_World) ); + break; + } + case E_BLOCK_SIGN_POST: + case E_BLOCK_WALLSIGN: + { + AddBlockEntity( new cSignEntity( (ENUM_BLOCK_ID)a_BlockType, WorldPos.x, WorldPos.y, WorldPos.z, m_World) ); + break; + } + } // switch (a_BlockType) +} + + + + + +void cChunk::FastSetBlock( int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta) +{ + ASSERT(!((a_X < 0 || a_X >= Width || a_Y < 0 || a_Y >= Height || a_Z < 0 || a_Z >= Width))); + + ASSERT(IsValid()); + + const int index = MakeIndexNoCheck( a_X, a_Y, a_Z ); + const BLOCKTYPE OldBlock = m_BlockTypes[index]; + const BLOCKTYPE OldBlockMeta = GetNibble( m_BlockMeta, index ); + if ((OldBlock == a_BlockType) && (OldBlockMeta == a_BlockMeta)) + { + return; + } + + MarkDirty(); + + m_BlockTypes[index] = a_BlockType; + + { + cCSLock Lock(m_CSBlockLists); + m_PendingSendBlocks.push_back( index ); + } + + SetNibble( m_BlockMeta, index, a_BlockMeta ); + + // ONLY recalculate lighting if it's necessary! + if( + (g_BlockLightValue[ OldBlock ] != g_BlockLightValue[ a_BlockType ]) || + (g_BlockSpreadLightFalloff[ OldBlock ] != g_BlockSpreadLightFalloff[ a_BlockType ]) || + (g_BlockTransparent[ OldBlock ] != g_BlockTransparent[ a_BlockType ] ) + ) + { + m_IsLightValid = false; + } + + // Update heightmap, if needed: + if (a_Y >= m_HeightMap[a_X + a_Z * Width]) + { + if (a_BlockType != E_BLOCK_AIR) + { + m_HeightMap[a_X + a_Z * Width] = (unsigned char)a_Y; + } + else + { + for (int y = a_Y - 1; y > 0; --y) + { + if (m_BlockTypes[MakeIndexNoCheck(a_X, y, a_Z)] != E_BLOCK_AIR) + { + m_HeightMap[a_X + a_Z * Width] = (unsigned char)y; + break; + } + } // for y - column in m_BlockData + } + } +} + + + + + +void cChunk::SendBlockTo( int a_X, int a_Y, int a_Z, cClientHandle* a_Client ) +{ + if( a_Client == 0 ) + { + cCSLock Lock(m_CSBlockLists); + unsigned int index = MakeIndex( a_X, a_Y, a_Z ); + if( index != INDEX_OUT_OF_RANGE ) + { + m_PendingSendBlocks.push_back( index ); + } + else + { + LOGWARN("cChunk::SendBlockTo Index out of range!"); + } + return; + } + + for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr ) + { + if ( *itr == a_Client ) + { + unsigned int index = MakeIndex( a_X, a_Y, a_Z ); + Vector3i WorldPos = PositionToWorldPosition( a_X, a_Y, a_Z ); + cPacket_BlockChange BlockChange; + BlockChange.m_PosX = WorldPos.x; + BlockChange.m_PosY = (unsigned char)WorldPos.y; + BlockChange.m_PosZ = WorldPos.z; + if( index != INDEX_OUT_OF_RANGE ) + { + BlockChange.m_BlockType = m_BlockTypes[ index ]; + BlockChange.m_BlockMeta = GetNibble( m_BlockMeta, index ); + } // else it's both 0 + a_Client->Send( BlockChange ); + break; + } + } +} + + + + + +void cChunk::AddBlockEntity( cBlockEntity* a_BlockEntity ) +{ + cCSLock Lock(m_CSBlockLists); + m_BlockEntities.push_back( a_BlockEntity ); +} + + + + + +cBlockEntity * cChunk::GetBlockEntity(int a_X, int a_Y, int a_Z) +{ + // Assumes that the m_CSBlockList is already locked, we're being called from SetBlock() + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) + { + if ( + ((*itr)->GetPosX() == a_X) && + ((*itr)->GetPosY() == a_Y) && + ((*itr)->GetPosZ() == a_Z) + ) + { + return *itr; + } + } // for itr - m_BlockEntities[] + + return NULL; +} + + + + + +void cChunk::UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z) +{ + cBlockEntity * be = GetBlockEntity(a_X, a_Y, a_Z); + if (be != NULL) + { + be->UsedBy(a_Player); + } +} + + + + + +void cChunk::CollectPickupsByPlayer(cPlayer * a_Player) +{ + double PosX = a_Player->GetPosX(); + double PosY = a_Player->GetPosY(); + double PosZ = a_Player->GetPosZ(); + + for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) + { + if ( (*itr)->GetEntityType() != cEntity::eEntityType_Pickup ) + { + continue; // Only pickups + } + float DiffX = (float)((*itr)->GetPosX() - PosX ); + float DiffY = (float)((*itr)->GetPosY() - PosY ); + float DiffZ = (float)((*itr)->GetPosZ() - PosZ ); + float SqrDist = DiffX * DiffX + DiffY * DiffY + DiffZ * DiffZ; + if (SqrDist < 1.5f * 1.5f) // 1.5 block + { + MarkDirty(); + (reinterpret_cast(*itr))->CollectedBy( a_Player ); + } + } +} + + + + + +void cChunk::UpdateSign(int a_PosX, int a_PosY, int a_PosZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) +{ + // Also sends update packets to all clients in the chunk + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) + { + if ( + ((*itr)->GetPosX() == a_PosX) && + ((*itr)->GetPosY() == a_PosY) && + ((*itr)->GetPosZ() == a_PosZ) && + ( + ((*itr)->GetBlockType() == E_BLOCK_WALLSIGN) || + ((*itr)->GetBlockType() == E_BLOCK_SIGN_POST) + ) + ) + { + MarkDirty(); + (reinterpret_cast(*itr))->SetLines(a_Line1, a_Line2, a_Line3, a_Line4); + (*itr)->SendTo(NULL); + } + } // for itr - m_BlockEntities[] +} + + + + + +void cChunk::RemoveBlockEntity( cBlockEntity* a_BlockEntity ) +{ + cCSLock Lock(m_CSBlockLists); + MarkDirty(); + m_BlockEntities.remove( a_BlockEntity ); +} + + + + + +bool cChunk::AddClient(cClientHandle* a_Client) +{ + for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) + { + if (a_Client == *itr) + { + // Already there, nothing needed + return false; + } + } + m_LoadedByClient.push_back( a_Client ); + + for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr ) + { + LOGD("cChunk: Entity #%d (%s) at [%i, %i, %i] spawning for player \"%s\"", (*itr)->GetUniqueID(), (*itr)->GetClass(), m_PosX, m_PosY, m_PosZ, a_Client->GetUsername().c_str() ); + (*itr)->SpawnOn( a_Client ); + } + return true; +} + + + + + +void cChunk::RemoveClient( cClientHandle* a_Client ) +{ + for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) + { + if (*itr != a_Client) + { + continue; + } + + m_LoadedByClient.erase(itr); + + if ( !a_Client->IsDestroyed() ) + { + for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr ) + { + LOGD("chunk [%i, %i] destroying entity #%i for player \"%s\"", m_PosX, m_PosZ, (*itr)->GetUniqueID(), a_Client->GetUsername().c_str() ); + cPacket_DestroyEntity DestroyEntity( *itr ); + a_Client->Send( DestroyEntity ); + } + } + return; + } // for itr - m_LoadedByClient[] +} + + + + + +bool cChunk::HasClient( cClientHandle* a_Client ) +{ + for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) + { + if ((*itr) == a_Client) + { + return true; + } + } + return false; +} + + + + + +bool cChunk::HasAnyClients(void) +{ + return !m_LoadedByClient.empty(); +} + + + + + +void cChunk::AddEntity( cEntity * a_Entity) +{ + if (a_Entity->GetEntityType() != cEntity::eEntityType_Player) + { + MarkDirty(); + } + m_Entities.push_back( a_Entity ); +} + + + + + +void cChunk::RemoveEntity(cEntity * a_Entity) +{ + size_t SizeBefore = m_Entities.size(); + m_Entities.remove(a_Entity); + size_t SizeAfter = m_Entities.size(); + + if (SizeBefore != SizeAfter) + { + // Mark as dirty if it was a server-generated entity: + if (a_Entity->GetEntityType() != cEntity::eEntityType_Player) + { + MarkDirty(); + } + } +} + + + + + +BLOCKTYPE cChunk::GetBlock( int a_X, int a_Y, int a_Z ) +{ + if ((a_X < 0) || (a_X >= Width) || (a_Y < 0) || (a_Y >= Height) || (a_Z < 0) || (a_Z >= Width)) return 0; // Clip + + return m_BlockTypes[ MakeIndexNoCheck( a_X, a_Y, a_Z ) ]; +} + + + + + +BLOCKTYPE cChunk::GetBlock( int a_BlockIdx ) +{ + if( a_BlockIdx < 0 || a_BlockIdx >= NumBlocks ) return 0; + return m_BlockTypes[ a_BlockIdx ]; +} + + + + + +void cChunk::GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) +{ + int Idx = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ); + a_BlockType = cChunkDef::GetBlock (m_BlockTypes, a_RelX, a_RelY, a_RelZ); + a_BlockMeta = cChunkDef::GetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ); +} + + + + + +/* +// _X 2012_02_23: Loading in old format not supported anymore +/// Loads the chunk from the old-format disk file, erases the file afterwards. Returns true if successful +bool cChunk::LoadFromDisk() +{ + AString SourceFile; + Printf(SourceFile, "world/X%i_Y%i_Z%i.bin", m_PosX, m_PosY, m_PosZ ); + + cFile f; + if (!f.Open(SourceFile, cFile::fmRead)) + { + return false; + } + + if (f.Read(m_BlockData, sizeof(m_BlockData)) != sizeof(m_BlockData)) + { + LOGERROR("ERROR READING FROM FILE %s", SourceFile.c_str()); + return false; + } + + // Now load Block Entities: + ENUM_BLOCK_ID BlockType; + while (f.Read(&BlockType, sizeof(ENUM_BLOCK_ID)) == sizeof(ENUM_BLOCK_ID)) + { + switch (BlockType) + { + case E_BLOCK_CHEST: + { + cChestEntity * ChestEntity = new cChestEntity( 0, 0, 0, m_World ); + if (!ChestEntity->LoadFromFile(f)) + { + LOGERROR("ERROR READING CHEST FROM FILE %s", SourceFile.c_str()); + delete ChestEntity; + return false; + } + m_BlockEntities.push_back( ChestEntity ); + break; + } + + case E_BLOCK_FURNACE: + { + cFurnaceEntity* FurnaceEntity = new cFurnaceEntity( 0, 0, 0, m_World ); + if (!FurnaceEntity->LoadFromFile(f)) + { + LOGERROR("ERROR READING FURNACE FROM FILE %s", SourceFile.c_str()); + delete FurnaceEntity; + return false; + } + m_BlockEntities.push_back( FurnaceEntity ); + break; + } + + case E_BLOCK_SIGN_POST: + case E_BLOCK_WALLSIGN: + { + cSignEntity * SignEntity = new cSignEntity(BlockType, 0, 0, 0, m_World ); + if (!SignEntity->LoadFromFile( f ) ) + { + LOGERROR("ERROR READING SIGN FROM FILE %s", SourceFile.c_str()); + delete SignEntity; + return false; + } + m_BlockEntities.push_back( SignEntity ); + break; + } + + default: + { + ASSERT(!"Unhandled block entity in file"); + break; + } + } + } + f.Close(); + + // Delete old format file + if (std::remove(SourceFile.c_str()) != 0) + { + LOGERROR("Could not delete file %s", SourceFile.c_str()); + } + else + { + LOGINFO("Successfully deleted old format file \"%s\"", SourceFile.c_str()); + } + m_IsDirty = false; + return true; +} +*/ + + + + + +void cChunk::Broadcast( const cPacket * a_Packet, cClientHandle* a_Exclude) +{ + for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr ) + { + if (*itr == a_Exclude) + { + continue; + } + (*itr)->Send(*a_Packet); + } // for itr - LoadedByClient[] +} + + + + + +void cChunk::PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, int & a_X, int & a_Y, int & a_Z) +{ + a_Y = a_ChunkY; + a_X = m_PosX * Width + a_ChunkX; + a_Z = m_PosZ * Width + a_ChunkZ; +} + + + + + +Vector3i cChunk::PositionToWorldPosition( int a_ChunkX, int a_ChunkY, int a_ChunkZ ) +{ + return Vector3i( m_PosX * Width + a_ChunkX, m_PosY * Height + a_ChunkY, m_PosZ * Width + a_ChunkZ ); +} + + + + + +#if !C_CHUNK_USE_INLINE +# include "cChunk.inl.h" +#endif + + + + diff --git a/source/cChunk.h b/source/cChunk.h index b92b62ff8..e24990982 100644 --- a/source/cChunk.h +++ b/source/cChunk.h @@ -1,271 +1,271 @@ - -#pragma once - -#include "cEntity.h" -#include "ChunkDef.h" - - - - - -#define C_CHUNK_USE_INLINE 1 - -// Do not touch -#if C_CHUNK_USE_INLINE - #define __C_CHUNK_INLINE__ inline -#else - #define __C_CHUNK_INLINE__ -#endif - - - - - -namespace Json -{ - class Value; -}; - - - - - -class cWorld; -class cFurnaceEntity; -class cPacket; -class cClientHandle; -class cServer; -class MTRand; -class cPlayer; -class cChunkMap; - -typedef std::list cClientHandleList; - - - - - -// This class is not to be used directly -// Instead, call actions on cChunkMap (such as cChunkMap::SetBlock() etc.) -class cChunk : - public cChunkDef // The inheritance is "misused" here only to inherit the functions and constants defined in cChunkDef -{ -public: - cChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkMap * a_ChunkMap, cWorld * a_World); - ~cChunk(); - - bool IsValid(void) const {return m_IsValid; } // Returns true if the chunk block data is valid (loaded / generated) - void SetValid(void); // Also wakes up any calls to cChunkMap::GetHeight() - void MarkRegenerating(void); // Marks all clients attached to this chunk as wanting this chunk - bool IsDirty(void) const {return m_IsDirty; } // Returns true if the chunk has changed since it was last saved - bool HasLoadFailed(void) const {return m_HasLoadFailed; } // Returns true if the chunk failed to load and hasn't been generated since then - bool CanUnload(void); - - bool IsLightValid(void) const {return m_IsLightValid; } - - /* - To save a chunk, the WSSchema must: - 1. Mark the chunk as being saved (MarkSaving() ) - 2. Get the chunk's data using GetAllData() - 3. Mark the chunk as saved (MarkSaved() ) - If anywhere inside this sequence another thread mmodifies the chunk, the chunk will not get marked as saved in MarkSaved() - */ - void MarkSaving(void); // Marks the chunk as being saved. - void MarkSaved(void); // Marks the chunk as saved, if it didn't change from the last call to MarkSaving() - void MarkLoaded(void); // Marks the chunk as freshly loaded. Fails if the chunk is already valid - void MarkLoadFailed(void); // Marks the chunk as failed to load. Ignored is the chunk is already valid - - /// Gets all chunk data, calls the a_Callback's methods for each data type - void GetAllData(cChunkDataCallback & a_Callback); - - /// Sets all chunk data - void SetAllData( - const BLOCKTYPE * a_BlockTypes, - const NIBBLETYPE * a_BlockMeta, - const NIBBLETYPE * a_BlockLight, - const NIBBLETYPE * a_BlockSkyLight, - const cChunkDef::HeightMap * a_HeightMap, - const cChunkDef::BiomeMap & a_BiomeMap, - cEntityList & a_Entities, - cBlockEntityList & a_BlockEntities - ); - - void SetLight( - const cChunkDef::BlockNibbles & a_BlockLight, - const cChunkDef::BlockNibbles & a_SkyLight - ); - - /// Copies m_BlockData into a_BlockTypes, only the block types - void GetBlockTypes(BLOCKTYPE * a_BlockTypes); - - /// Copies entire block data into a_BlockData, the entire 4 arrays (Type, Meta, Light, SkyLight) - void GetBlockData(BLOCKTYPE * a_BlockData); - - /// Returns true if there is a block entity at the coords specified - bool HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ); - - /// Sets or resets the internal flag that prevents chunk from being unloaded - void Stay(bool a_Stay = true); - - void Tick(float a_Dt, MTRand & a_TickRandom); - - int GetPosX() { return m_PosX; } - int GetPosY() { return m_PosY; } - int GetPosZ() { return m_PosZ; } - cWorld * GetWorld() { return m_World; } - - // OBSOLETE void SendTo( cClientHandle * a_Client ); - - void SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ); - // SetBlock() does a lot of work (heightmap, tickblocks, blockentities) so a BlockIdx version doesn't make sense - void SetBlock( const Vector3i & a_RelBlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) { SetBlock( a_RelBlockPos.x, a_RelBlockPos.y, a_RelBlockPos.z, a_BlockType, a_BlockMeta ); } - void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta ); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc. - BLOCKTYPE GetBlock( int a_X, int a_Y, int a_Z ); - BLOCKTYPE GetBlock( int a_BlockIdx ); - void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); - - EMCSBiome GetBiomeAt(int a_RelX, int a_RelZ) const {return cChunkDef::GetBiome(m_BiomeMap, a_RelX, a_RelZ); } - - void CollectPickupsByPlayer(cPlayer * a_Player); - void UpdateSign(int a_PosX, int a_PosY, int a_PosZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); // Also sends update packets to all clients in the chunk - - int GetHeight( int a_X, int a_Z ); - - void SendBlockTo( int a_X, int a_Y, int a_Z, cClientHandle* a_Client ); - - /// Adds a client to the chunk; returns true if added, false if already there - bool AddClient (cClientHandle* a_Client ); - - void RemoveClient (cClientHandle* a_Client ); - bool HasClient (cClientHandle* a_Client ); - bool HasAnyClients(void); // Returns true if theres any client in the chunk; false otherwise - - void AddEntity( cEntity * a_Entity); - void RemoveEntity( cEntity * a_Entity); - - void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z); // [x, y, z] in world block coords - - void CalculateLighting(); // Recalculate right now - void CalculateHeightmap(); - - // Broadcasts to all clients that have loaded this chunk - void Broadcast( const cPacket & a_Packet, cClientHandle * a_Exclude = NULL) {Broadcast(&a_Packet, a_Exclude); } - void Broadcast( const cPacket * a_Packet, cClientHandle * a_Exclude = NULL); - - void PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, int & a_X, int & a_Y, int & a_Z); - Vector3i PositionToWorldPosition( const Vector3i & a_InChunkPos ) { return PositionToWorldPosition( a_InChunkPos.x, a_InChunkPos.y, a_InChunkPos.z ); } - Vector3i PositionToWorldPosition( int a_ChunkX, int a_ChunkY, int a_ChunkZ ); - - inline void MarkDirty(void) - { - m_IsDirty = true; - m_IsSaving = false; - } - - /// Sets the blockticking to start at the specified block. Only one blocktick may be set, second call overwrites the first call - inline void SetNextBlockTick(int a_RelX, int a_RelY, int a_RelZ) - { - m_BlockTickX = a_RelX; - m_BlockTickY = a_RelY; - m_BlockTickZ = a_RelZ; - } - - inline NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) {return cChunkDef::GetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ); } - inline NIBBLETYPE GetMeta(int a_BlockIdx) {return cChunkDef::GetNibble(m_BlockMeta, a_BlockIdx); } - inline void SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta) { cChunkDef::SetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ, a_Meta); } - - inline NIBBLETYPE GetLight(int a_RelX, int a_RelY, int a_RelZ) {return cChunkDef::GetNibble(m_BlockLight, a_RelX, a_RelY, a_RelZ); } - inline NIBBLETYPE GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) {return cChunkDef::GetNibble(m_BlockSkyLight, a_RelX, a_RelY, a_RelZ); } - -private: - - friend class cChunkMap; - - bool m_IsValid; // True if the chunk is loaded / generated - bool m_IsLightValid; // True if the blocklight and skylight are calculated - bool m_IsDirty; // True if the chunk has changed since it was last saved - bool m_IsSaving; // True if the chunk is being saved - bool m_HasLoadFailed; // True if chunk failed to load and hasn't been generated yet since then - - cCriticalSection m_CSBlockLists; - std::deque< unsigned int > m_ToTickBlocks; - std::vector< unsigned int > m_PendingSendBlocks; - - // A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers - cClientHandleList m_LoadedByClient; - cClientHandleList m_UnloadQuery; - cEntityList m_Entities; - cBlockEntityList m_BlockEntities; - - /// Number of times the chunk has been requested to stay (by various cChunkStay objects); if zero, the chunk can be unloaded - int m_StayCount; - - int m_PosX, m_PosY, m_PosZ; - cWorld * m_World; - cChunkMap * m_ChunkMap; - - // TODO: Make these pointers and don't allocate what isn't needed - BLOCKTYPE m_BlockTypes [cChunkDef::NumBlocks]; - NIBBLETYPE m_BlockMeta [cChunkDef::NumBlocks / 2]; - NIBBLETYPE m_BlockLight [cChunkDef::NumBlocks / 2]; - NIBBLETYPE m_BlockSkyLight[cChunkDef::NumBlocks / 2]; - - cChunkDef::HeightMap m_HeightMap; - cChunkDef::BiomeMap m_BiomeMap; - - int m_BlockTickX, m_BlockTickY, m_BlockTickZ; - - void RemoveBlockEntity( cBlockEntity* a_BlockEntity ); - void AddBlockEntity( cBlockEntity* a_BlockEntity ); - cBlockEntity * GetBlockEntity( int a_X, int a_Y, int a_Z ); - cBlockEntity * GetBlockEntity( const Vector3i & a_BlockPos ) { return GetBlockEntity( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z ); } - - void SpreadLightOfBlock(NIBBLETYPE * a_LightBuffer, int a_X, int a_Y, int a_Z, char a_Falloff); - - void CreateBlockEntities(void); - - // Makes a copy of the list - cClientHandleList GetAllClients(void) const {return m_LoadedByClient; } - - /// Checks the block scheduled for checking in m_ToTickBlocks[] - void CheckBlocks(void); - - void TickBlocks (MTRand & a_TickRandom); - void TickGrass (int a_RelX, int a_RelY, int a_RelZ, MTRand & a_TickRandom); - void TickMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, int a_BlockIdx, BLOCKTYPE a_BlockType, MTRand & a_TickRandom); - void TickFarmland (int a_RelX, int a_RelY, int a_RelZ); - - /// Grows sugarcane by the specified number of blocks, but no more than 3 blocks high (used by both bonemeal and ticking) - void GrowSugarcane (int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks); - - /// Grows cactus by the specified number of blocks, but no more than 3 blocks high (used by both bonemeal and ticking) - void GrowCactus (int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks); - - /// Grows a melon or a pumpkin next to the block specified (assumed to be the stem) - void GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, MTRand & a_Random); - - /// Same as GetBlock(), but relative coords needn't be in this chunk (uses m_ChunkMap in such a case); returns true on success; only usable in Tick() - bool UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); - - /// Same as SetBlock(), but relative coords needn't be in this chunk (uses m_ChunkMap in such a case); returns true on success; only usable in Tick() - bool UnboundedRelSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); - - /// Same as FastSetBlock(), but relative coords needn't be in this chunk (uses m_ChunkMap in such a case); returns true on success; only usable in Tick() - bool UnboundedRelFastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); -}; - -typedef cChunk * cChunkPtr; - -typedef std::list cChunkPtrList; - - - - - -#if C_CHUNK_USE_INLINE - #include "cChunk.inl.h" -#endif - - - - + +#pragma once + +#include "cEntity.h" +#include "ChunkDef.h" + + + + + +#define C_CHUNK_USE_INLINE 1 + +// Do not touch +#if C_CHUNK_USE_INLINE + #define __C_CHUNK_INLINE__ inline +#else + #define __C_CHUNK_INLINE__ +#endif + + + + + +namespace Json +{ + class Value; +}; + + + + + +class cWorld; +class cFurnaceEntity; +class cPacket; +class cClientHandle; +class cServer; +class MTRand; +class cPlayer; +class cChunkMap; + +typedef std::list cClientHandleList; + + + + + +// This class is not to be used directly +// Instead, call actions on cChunkMap (such as cChunkMap::SetBlock() etc.) +class cChunk : + public cChunkDef // The inheritance is "misused" here only to inherit the functions and constants defined in cChunkDef +{ +public: + cChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkMap * a_ChunkMap, cWorld * a_World); + ~cChunk(); + + bool IsValid(void) const {return m_IsValid; } // Returns true if the chunk block data is valid (loaded / generated) + void SetValid(void); // Also wakes up any calls to cChunkMap::GetHeight() + void MarkRegenerating(void); // Marks all clients attached to this chunk as wanting this chunk + bool IsDirty(void) const {return m_IsDirty; } // Returns true if the chunk has changed since it was last saved + bool HasLoadFailed(void) const {return m_HasLoadFailed; } // Returns true if the chunk failed to load and hasn't been generated since then + bool CanUnload(void); + + bool IsLightValid(void) const {return m_IsLightValid; } + + /* + To save a chunk, the WSSchema must: + 1. Mark the chunk as being saved (MarkSaving() ) + 2. Get the chunk's data using GetAllData() + 3. Mark the chunk as saved (MarkSaved() ) + If anywhere inside this sequence another thread mmodifies the chunk, the chunk will not get marked as saved in MarkSaved() + */ + void MarkSaving(void); // Marks the chunk as being saved. + void MarkSaved(void); // Marks the chunk as saved, if it didn't change from the last call to MarkSaving() + void MarkLoaded(void); // Marks the chunk as freshly loaded. Fails if the chunk is already valid + void MarkLoadFailed(void); // Marks the chunk as failed to load. Ignored is the chunk is already valid + + /// Gets all chunk data, calls the a_Callback's methods for each data type + void GetAllData(cChunkDataCallback & a_Callback); + + /// Sets all chunk data + void SetAllData( + const BLOCKTYPE * a_BlockTypes, + const NIBBLETYPE * a_BlockMeta, + const NIBBLETYPE * a_BlockLight, + const NIBBLETYPE * a_BlockSkyLight, + const cChunkDef::HeightMap * a_HeightMap, + const cChunkDef::BiomeMap & a_BiomeMap, + cEntityList & a_Entities, + cBlockEntityList & a_BlockEntities + ); + + void SetLight( + const cChunkDef::BlockNibbles & a_BlockLight, + const cChunkDef::BlockNibbles & a_SkyLight + ); + + /// Copies m_BlockData into a_BlockTypes, only the block types + void GetBlockTypes(BLOCKTYPE * a_BlockTypes); + + /// Copies entire block data into a_BlockData, the entire 4 arrays (Type, Meta, Light, SkyLight) + void GetBlockData(BLOCKTYPE * a_BlockData); + + /// Returns true if there is a block entity at the coords specified + bool HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ); + + /// Sets or resets the internal flag that prevents chunk from being unloaded + void Stay(bool a_Stay = true); + + void Tick(float a_Dt, MTRand & a_TickRandom); + + int GetPosX() { return m_PosX; } + int GetPosY() { return m_PosY; } + int GetPosZ() { return m_PosZ; } + cWorld * GetWorld() { return m_World; } + + // OBSOLETE void SendTo( cClientHandle * a_Client ); + + void SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ); + // SetBlock() does a lot of work (heightmap, tickblocks, blockentities) so a BlockIdx version doesn't make sense + void SetBlock( const Vector3i & a_RelBlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) { SetBlock( a_RelBlockPos.x, a_RelBlockPos.y, a_RelBlockPos.z, a_BlockType, a_BlockMeta ); } + void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta ); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc. + BLOCKTYPE GetBlock( int a_X, int a_Y, int a_Z ); + BLOCKTYPE GetBlock( int a_BlockIdx ); + void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); + + EMCSBiome GetBiomeAt(int a_RelX, int a_RelZ) const {return cChunkDef::GetBiome(m_BiomeMap, a_RelX, a_RelZ); } + + void CollectPickupsByPlayer(cPlayer * a_Player); + void UpdateSign(int a_PosX, int a_PosY, int a_PosZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); // Also sends update packets to all clients in the chunk + + int GetHeight( int a_X, int a_Z ); + + void SendBlockTo( int a_X, int a_Y, int a_Z, cClientHandle* a_Client ); + + /// Adds a client to the chunk; returns true if added, false if already there + bool AddClient (cClientHandle* a_Client ); + + void RemoveClient (cClientHandle* a_Client ); + bool HasClient (cClientHandle* a_Client ); + bool HasAnyClients(void); // Returns true if theres any client in the chunk; false otherwise + + void AddEntity( cEntity * a_Entity); + void RemoveEntity( cEntity * a_Entity); + + void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z); // [x, y, z] in world block coords + + void CalculateLighting(); // Recalculate right now + void CalculateHeightmap(); + + // Broadcasts to all clients that have loaded this chunk + void Broadcast( const cPacket & a_Packet, cClientHandle * a_Exclude = NULL) {Broadcast(&a_Packet, a_Exclude); } + void Broadcast( const cPacket * a_Packet, cClientHandle * a_Exclude = NULL); + + void PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, int & a_X, int & a_Y, int & a_Z); + Vector3i PositionToWorldPosition( const Vector3i & a_InChunkPos ) { return PositionToWorldPosition( a_InChunkPos.x, a_InChunkPos.y, a_InChunkPos.z ); } + Vector3i PositionToWorldPosition( int a_ChunkX, int a_ChunkY, int a_ChunkZ ); + + inline void MarkDirty(void) + { + m_IsDirty = true; + m_IsSaving = false; + } + + /// Sets the blockticking to start at the specified block. Only one blocktick may be set, second call overwrites the first call + inline void SetNextBlockTick(int a_RelX, int a_RelY, int a_RelZ) + { + m_BlockTickX = a_RelX; + m_BlockTickY = a_RelY; + m_BlockTickZ = a_RelZ; + } + + inline NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) {return cChunkDef::GetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ); } + inline NIBBLETYPE GetMeta(int a_BlockIdx) {return cChunkDef::GetNibble(m_BlockMeta, a_BlockIdx); } + inline void SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta) { cChunkDef::SetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ, a_Meta); } + + inline NIBBLETYPE GetLight(int a_RelX, int a_RelY, int a_RelZ) {return cChunkDef::GetNibble(m_BlockLight, a_RelX, a_RelY, a_RelZ); } + inline NIBBLETYPE GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) {return cChunkDef::GetNibble(m_BlockSkyLight, a_RelX, a_RelY, a_RelZ); } + +private: + + friend class cChunkMap; + + bool m_IsValid; // True if the chunk is loaded / generated + bool m_IsLightValid; // True if the blocklight and skylight are calculated + bool m_IsDirty; // True if the chunk has changed since it was last saved + bool m_IsSaving; // True if the chunk is being saved + bool m_HasLoadFailed; // True if chunk failed to load and hasn't been generated yet since then + + cCriticalSection m_CSBlockLists; + std::deque< unsigned int > m_ToTickBlocks; + std::vector< unsigned int > m_PendingSendBlocks; + + // A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers + cClientHandleList m_LoadedByClient; + cClientHandleList m_UnloadQuery; + cEntityList m_Entities; + cBlockEntityList m_BlockEntities; + + /// Number of times the chunk has been requested to stay (by various cChunkStay objects); if zero, the chunk can be unloaded + int m_StayCount; + + int m_PosX, m_PosY, m_PosZ; + cWorld * m_World; + cChunkMap * m_ChunkMap; + + // TODO: Make these pointers and don't allocate what isn't needed + BLOCKTYPE m_BlockTypes [cChunkDef::NumBlocks]; + NIBBLETYPE m_BlockMeta [cChunkDef::NumBlocks / 2]; + NIBBLETYPE m_BlockLight [cChunkDef::NumBlocks / 2]; + NIBBLETYPE m_BlockSkyLight[cChunkDef::NumBlocks / 2]; + + cChunkDef::HeightMap m_HeightMap; + cChunkDef::BiomeMap m_BiomeMap; + + int m_BlockTickX, m_BlockTickY, m_BlockTickZ; + + void RemoveBlockEntity( cBlockEntity* a_BlockEntity ); + void AddBlockEntity( cBlockEntity* a_BlockEntity ); + cBlockEntity * GetBlockEntity( int a_X, int a_Y, int a_Z ); + cBlockEntity * GetBlockEntity( const Vector3i & a_BlockPos ) { return GetBlockEntity( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z ); } + + void SpreadLightOfBlock(NIBBLETYPE * a_LightBuffer, int a_X, int a_Y, int a_Z, char a_Falloff); + + void CreateBlockEntities(void); + + // Makes a copy of the list + cClientHandleList GetAllClients(void) const {return m_LoadedByClient; } + + /// Checks the block scheduled for checking in m_ToTickBlocks[] + void CheckBlocks(void); + + void TickBlocks (MTRand & a_TickRandom); + void TickGrass (int a_RelX, int a_RelY, int a_RelZ, MTRand & a_TickRandom); + void TickMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, int a_BlockIdx, BLOCKTYPE a_BlockType, MTRand & a_TickRandom); + void TickFarmland (int a_RelX, int a_RelY, int a_RelZ); + + /// Grows sugarcane by the specified number of blocks, but no more than 3 blocks high (used by both bonemeal and ticking) + void GrowSugarcane (int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks); + + /// Grows cactus by the specified number of blocks, but no more than 3 blocks high (used by both bonemeal and ticking) + void GrowCactus (int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks); + + /// Grows a melon or a pumpkin next to the block specified (assumed to be the stem) + void GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, MTRand & a_Random); + + /// Same as GetBlock(), but relative coords needn't be in this chunk (uses m_ChunkMap in such a case); returns true on success; only usable in Tick() + bool UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); + + /// Same as SetBlock(), but relative coords needn't be in this chunk (uses m_ChunkMap in such a case); returns true on success; only usable in Tick() + bool UnboundedRelSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); + + /// Same as FastSetBlock(), but relative coords needn't be in this chunk (uses m_ChunkMap in such a case); returns true on success; only usable in Tick() + bool UnboundedRelFastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); +}; + +typedef cChunk * cChunkPtr; + +typedef std::list cChunkPtrList; + + + + + +#if C_CHUNK_USE_INLINE + #include "cChunk.inl.h" +#endif + + + + diff --git a/source/cChunk.inl.h b/source/cChunk.inl.h index f0353521c..fb9c4dad1 100644 --- a/source/cChunk.inl.h +++ b/source/cChunk.inl.h @@ -1,34 +1,34 @@ - -#ifndef __C_CHUNK_INL_H__ -#define __C_CHUNK_INL_H__ - -#ifndef MAX -# define MAX(a,b) (((a)>(b))?(a):(b)) -#endif - - - - - -__C_CHUNK_INLINE__ -void cChunk::SpreadLightOfBlock(NIBBLETYPE * a_LightBuffer, int a_X, int a_Y, int a_Z, char a_Falloff) -{ - unsigned char CurrentLight = cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y, a_Z ); - cChunkDef::SetNibble( a_LightBuffer, a_X-1, a_Y, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X-1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) ); - cChunkDef::SetNibble( a_LightBuffer, a_X+1, a_Y, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X+1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) ); - cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y-1, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y-1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) ); - cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y+1, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y+1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) ); - cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y, a_Z-1, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y, a_Z-1 ), MAX(0,CurrentLight-a_Falloff) ) ); - cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y, a_Z+1, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y, a_Z+1 ), MAX(0,CurrentLight-a_Falloff) ) ); - MarkDirty(); -} - - - - - -#endif - - - - + +#ifndef __C_CHUNK_INL_H__ +#define __C_CHUNK_INL_H__ + +#ifndef MAX +# define MAX(a,b) (((a)>(b))?(a):(b)) +#endif + + + + + +__C_CHUNK_INLINE__ +void cChunk::SpreadLightOfBlock(NIBBLETYPE * a_LightBuffer, int a_X, int a_Y, int a_Z, char a_Falloff) +{ + unsigned char CurrentLight = cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y, a_Z ); + cChunkDef::SetNibble( a_LightBuffer, a_X-1, a_Y, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X-1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) ); + cChunkDef::SetNibble( a_LightBuffer, a_X+1, a_Y, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X+1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) ); + cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y-1, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y-1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) ); + cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y+1, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y+1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) ); + cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y, a_Z-1, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y, a_Z-1 ), MAX(0,CurrentLight-a_Falloff) ) ); + cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y, a_Z+1, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y, a_Z+1 ), MAX(0,CurrentLight-a_Falloff) ) ); + MarkDirty(); +} + + + + + +#endif + + + + diff --git a/source/cChunkGenerator.cpp b/source/cChunkGenerator.cpp index 82dc432e3..bed9d5cb8 100644 --- a/source/cChunkGenerator.cpp +++ b/source/cChunkGenerator.cpp @@ -1,544 +1,544 @@ - -#include "Globals.h" - -#include "cChunkGenerator.h" -#include "cWorld.h" -#include "../iniFile/iniFile.h" -#include "BioGen.h" -#include "HeiGen.h" -#include "CompoGen.h" -#include "StructGen.h" -#include "FinishGen.h" -#include "cRoot.h" -#include "cPluginManager.h" -#include "cLuaChunk.h" - - - - - -/// If the generation queue size exceeds this number, a warning will be output -const int QUEUE_WARNING_LIMIT = 1000; - -/// If the generation queue size exceeds this number, chunks with no clients will be skipped -const int QUEUE_SKIP_LIMIT = 500; - - - - - -static BLOCKTYPE GetIniBlock(cIniFile & a_IniFile, const AString & a_SectionName, const AString & a_ValueName, const AString & a_Default) -{ - AString BlockType = a_IniFile.GetValueSet(a_SectionName, a_ValueName, a_Default); - BLOCKTYPE Block = BlockStringToType(BlockType); - if (Block < 0) - { - LOGWARN("[&s].%s Could not parse block value \"%s\". Using default: \"%s\".", a_SectionName.c_str(), a_ValueName.c_str(), BlockType.c_str(),a_Default.c_str()); - return BlockStringToType(a_Default); - } - return Block; -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cChunkGenerator: - -cChunkGenerator::cChunkGenerator(void) - : super("cChunkGenerator") - , m_World(NULL) - , m_BiomeGen(NULL) - , m_HeightGen(NULL) - , m_CompositionGen(NULL) -{ -} - - - - - -cChunkGenerator::~cChunkGenerator() -{ - Stop(); -} - - - - - -bool cChunkGenerator::Start(cWorld * a_World, cIniFile & a_IniFile) -{ - MTRand rnd; - m_World = a_World; - m_Seed = a_IniFile.GetValueSetI("Seed", "Seed", rnd.randInt()); - - InitBiomeGen(a_IniFile); - InitHeightGen(a_IniFile); - InitCompositionGen(a_IniFile); - InitStructureGens(a_IniFile); - InitFinishGens(a_IniFile); - - a_IniFile.WriteFile(); - - return super::Start(); -} - - - - - -void cChunkGenerator::Stop(void) -{ - m_ShouldTerminate = true; - m_Event.Set(); - m_evtRemoved.Set(); // Wake up anybody waiting for empty queue - Wait(); - - // Delete the generating composition: - for (cFinishGenList::const_iterator itr = m_FinishGens.begin(); itr != m_FinishGens.end(); ++itr) - { - delete *itr; - } - m_FinishGens.clear(); - for (cStructureGenList::const_iterator itr = m_StructureGens.begin(); itr != m_StructureGens.end(); ++itr) - { - delete *itr; - } - m_StructureGens.clear(); - delete m_CompositionGen; - m_CompositionGen = NULL; - delete m_HeightGen; - m_HeightGen = NULL; - delete m_BiomeGen; - m_BiomeGen = NULL; -} - - - - - -void cChunkGenerator::InitBiomeGen(cIniFile & a_IniFile) -{ - AString BiomeGenName = a_IniFile.GetValueSet("Generator", "BiomeGen", ""); - if (BiomeGenName.empty()) - { - LOGWARN("[Generator]::BiomeGen value not found in world.ini, using \"DistortedVoronoi\"."); - BiomeGenName = "DistortedVoronoi"; - } - - bool CacheOffByDefault = false; - if (NoCaseCompare(BiomeGenName, "constant") == 0) - { - AString Biome = a_IniFile.GetValueSet("Generator", "ConstantBiome", "Plains"); - EMCSBiome b = StringToBiome(Biome); - if (b == -1) - { - LOGWARN("[Generator]::ConstantBiome value \"%s\" not recognized, using \"Plains\".", Biome.c_str()); - b = biPlains; - } - m_BiomeGen = new cBioGenConstant(b); - CacheOffByDefault = true; // we're generating faster than a cache would retrieve data :) - } - else if (NoCaseCompare(BiomeGenName, "checkerboard") == 0) - { - int BiomeSize = a_IniFile.GetValueSetI("Generator", "CheckerboardBiomeSize", 64); - AString Biomes = a_IniFile.GetValueSet ("Generator", "CheckerBoardBiomes", ""); - m_BiomeGen = new cBioGenCheckerboard(BiomeSize, Biomes); - CacheOffByDefault = true; // we're (probably) generating faster than a cache would retrieve data - } - else if (NoCaseCompare(BiomeGenName, "voronoi") == 0) - { - int CellSize = a_IniFile.GetValueSetI("Generator", "VoronoiCellSize", 64); - AString Biomes = a_IniFile.GetValueSet ("Generator", "VoronoiBiomes", ""); - m_BiomeGen = new cBioGenVoronoi(m_Seed, CellSize, Biomes); - } - else - { - if (NoCaseCompare(BiomeGenName, "distortedvoronoi") != 0) - { - LOGWARNING("Unknown BiomeGen \"%s\", using \"DistortedVoronoi\" instead.", BiomeGenName.c_str()); - } - int CellSize = a_IniFile.GetValueSetI("Generator", "DistortedVoronoiCellSize", 96); - AString Biomes = a_IniFile.GetValueSet ("Generator", "DistortedVoronoiBiomes", ""); - m_BiomeGen = new cBioGenDistortedVoronoi(m_Seed, CellSize, Biomes); - } - - // Add a cache, if requested: - int CacheSize = a_IniFile.GetValueSetI("Generator", "BiomeGenCacheSize", CacheOffByDefault ? 0 : 64); - if (CacheSize > 0) - { - if (CacheSize < 4) - { - LOGWARNING("Biomegen cache size set too low, would hurt performance instead of helping. Increasing from %d to %d", - CacheSize, 4 - ); - CacheSize = 4; - } - LOGINFO("Using a cache for biomegen of size %d.", CacheSize); - m_BiomeGen = new cBioGenCache(m_BiomeGen, CacheSize); - } -} - - - - - -void cChunkGenerator::InitHeightGen(cIniFile & a_IniFile) -{ - AString HeightGenName = a_IniFile.GetValueSet("Generator", "HeightGen", ""); - if (HeightGenName.empty()) - { - LOGWARN("[Generator]::HeightGen value not found in world.ini, using \"Biomal\"."); - HeightGenName = "Biomal"; - } - - bool CacheOffByDefault = false; - if (NoCaseCompare(HeightGenName, "flat") == 0) - { - int Height = a_IniFile.GetValueSetI("Generator", "FlatHeight", 5); - m_HeightGen = new cHeiGenFlat(Height); - CacheOffByDefault = true; // We're generating faster than a cache would retrieve data - } - else if (NoCaseCompare(HeightGenName, "classic") == 0) - { - // These used to be in terrain.ini, but now they are in world.ini (so that multiple worlds can have different values): - float HeightFreq1 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightFreq1", 0.1); - float HeightFreq2 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightFreq2", 1.0); - float HeightFreq3 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightFreq3", 2.0); - float HeightAmp1 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightAmp1", 1.0); - float HeightAmp2 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightAmp2", 0.5); - float HeightAmp3 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightAmp3", 0.5); - m_HeightGen = new cHeiGenClassic(m_Seed, HeightFreq1, HeightAmp1, HeightFreq2, HeightAmp2, HeightFreq3, HeightAmp3); - } - else // "biomal" or - { - if (NoCaseCompare(HeightGenName, "biomal") != 0) - { - LOGWARN("Unknown HeightGen \"%s\", using \"Biomal\" instead.", HeightGenName.c_str()); - } - m_HeightGen = new cHeiGenBiomal(m_Seed, *m_BiomeGen); - } - - // Add a cache, if requested: - int CacheSize = a_IniFile.GetValueSetI("Generator", "HeightGenCacheSize", CacheOffByDefault ? 0 : 64); - if (CacheSize > 0) - { - if (CacheSize < 4) - { - LOGWARNING("Heightgen cache size set too low, would hurt performance instead of helping. Increasing from %d to %d", - CacheSize, 4 - ); - CacheSize = 4; - } - LOGINFO("Using a cache for Heightgen of size %d.", CacheSize); - m_HeightGen = new cHeiGenCache(m_HeightGen, CacheSize); - } -} - - - - - -void cChunkGenerator::InitCompositionGen(cIniFile & a_IniFile) -{ - AString CompoGenName = a_IniFile.GetValueSet("Generator", "CompositionGen", ""); - if (CompoGenName.empty()) - { - LOGWARN("[Generator]::CompositionGen value not found in world.ini, using \"Biomal\"."); - CompoGenName = "Biomal"; - } - if (NoCaseCompare(CompoGenName, "sameblock") == 0) - { - AString BlockType = a_IniFile.GetValueSet("Generator", "SameBlockType", ""); - if (BlockType.empty()) - { - LOGWARN("[Generator]::SameBlockType value not found in world.ini, using \"stone\"."); - BlockType = "stone"; - } - int Block = GetIniBlock(a_IniFile, "[Generator]", "SameBlockType", "stone"); - bool Bedrocked = (a_IniFile.GetValueSetI("Generator", "SameBlockBedrocked", 1) != 0); - m_CompositionGen = new cCompoGenSameBlock((BLOCKTYPE)Block, Bedrocked); - } - else if (NoCaseCompare(CompoGenName, "debugbiomes") == 0) - { - m_CompositionGen = new cCompoGenDebugBiomes; - } - else if (NoCaseCompare(CompoGenName, "classic") == 0) - { - int SeaLevel = a_IniFile.GetValueSetI("Generator", "ClassicSeaLevel", 60); - int BeachHeight = a_IniFile.GetValueSetI("Generator", "ClassicBeachHeight", 2); - int BeachDepth = a_IniFile.GetValueSetI("Generator", "ClassicBeachDepth", 4); - BLOCKTYPE BlockTop = GetIniBlock(a_IniFile, "Generator", "ClassicBlockTop", "grass"); - BLOCKTYPE BlockMiddle = GetIniBlock(a_IniFile, "Generator", "ClassicBlockMiddle", "dirt"); - BLOCKTYPE BlockBottom = GetIniBlock(a_IniFile, "Generator", "ClassicBlockBottom", "stone"); - BLOCKTYPE BlockBeach = GetIniBlock(a_IniFile, "Generator", "ClassicBlockBeach", "sand"); - BLOCKTYPE BlockBeachBottom = GetIniBlock(a_IniFile, "Generator", "ClassicBlockBeachBottom", "sandstone"); - BLOCKTYPE BlockSea = GetIniBlock(a_IniFile, "Generator", "ClassicBlockSea", "9"); - m_CompositionGen = new cCompoGenClassic( - SeaLevel, BeachHeight, BeachDepth, BlockTop, BlockMiddle, BlockBottom, BlockBeach, - BlockBeachBottom, BlockSea - ); - } - else - { - if (NoCaseCompare(CompoGenName, "biomal") != 0) - { - LOGWARN("Unknown CompositionGen \"%s\", using \"biomal\" instead.", CompoGenName.c_str()); - } - int SeaLevel = a_IniFile.GetValueSetI("Generator", "BiomalSeaLevel", 62); - m_CompositionGen = new cCompoGenBiomal(m_Seed, SeaLevel); - } -} - - - - - -void cChunkGenerator::InitStructureGens(cIniFile & a_IniFile) -{ - AString Structures = a_IniFile.GetValueSet("Generator", "Structures", "Trees,MarbleCaves,OreNests"); - - AStringVector Str = StringSplit(Structures, ","); - for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr) - { - if (NoCaseCompare(*itr, "trees") == 0) - { - m_StructureGens.push_back(new cStructGenTrees(m_Seed, m_BiomeGen, m_HeightGen, m_CompositionGen)); - } - else if (NoCaseCompare(*itr, "marblecaves") == 0) - { - m_StructureGens.push_back(new cStructGenMarbleCaves(m_Seed)); - } - else if (NoCaseCompare(*itr, "orenests") == 0) - { - m_StructureGens.push_back(new cStructGenOreNests(m_Seed)); - } - else - { - LOGWARNING("Unknown structure generator: \"%s\". Ignoring.", itr->c_str()); - } - } // for itr - Str[] -} - - - - - -void cChunkGenerator::InitFinishGens(cIniFile & a_IniFile) -{ - AString Structures = a_IniFile.GetValueSet("Generator", "Finishers", "SprinkleFoliage,Ice,Snow"); - - AStringVector Str = StringSplit(Structures, ","); - for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr) - { - if (NoCaseCompare(*itr, "SprinkleFoliage") == 0) - { - m_FinishGens.push_back(new cFinishGenSprinkleFoliage(m_Seed)); - } - else if (NoCaseCompare(*itr, "Snow") == 0) - { - m_FinishGens.push_back(new cFinishGenSnow); - } - else if (NoCaseCompare(*itr, "Ice") == 0) - { - m_FinishGens.push_back(new cFinishGenIce); - } - } // for itr - Str[] -} - - - - - -void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - { - cCSLock Lock(m_CS); - - // Check if it is already in the queue: - for (cChunkCoordsList::iterator itr = m_Queue.begin(); itr != m_Queue.end(); ++itr) - { - if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ)) - { - // Already in the queue, bail out - return; - } - } // for itr - m_Queue[] - - // Add to queue, issue a warning if too many: - if (m_Queue.size() >= QUEUE_WARNING_LIMIT) - { - LOGWARN("WARNING: Adding chunk [%i, %i] to generation queue; Queue is too big! (%i)", a_ChunkX, a_ChunkZ, m_Queue.size()); - } - m_Queue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); - } - - m_Event.Set(); -} - - - - - -void cChunkGenerator::GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) -{ - m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap); -} - - - - - -void cChunkGenerator::WaitForQueueEmpty(void) -{ - cCSLock Lock(m_CS); - while (!m_ShouldTerminate && !m_Queue.empty()) - { - cCSUnlock Unlock(Lock); - m_evtRemoved.Wait(); - } -} - - - - - -int cChunkGenerator::GetQueueLength(void) -{ - cCSLock Lock(m_CS); - return (int)m_Queue.size(); -} - - - - - -EMCSBiome cChunkGenerator::GetBiomeAt(int a_BlockX, int a_BlockZ) -{ - cChunkDef::BiomeMap Biomes; - int Y = 0; - int ChunkX, ChunkZ; - cWorld::AbsoluteToRelative(a_BlockX, Y, a_BlockZ, ChunkX, Y, ChunkZ); - m_BiomeGen->GenBiomes(ChunkX, ChunkZ, Biomes); - return cChunkDef::GetBiome(Biomes, a_BlockX, a_BlockZ); -} - - - - - -void cChunkGenerator::Execute(void) -{ - while (!m_ShouldTerminate) - { - cCSLock Lock(m_CS); - while (m_Queue.size() == 0) - { - cCSUnlock Unlock(Lock); - m_Event.Wait(); - if (m_ShouldTerminate) - { - return; - } - } - - cChunkCoords coords = m_Queue.front(); // Get next coord from queue - m_Queue.erase( m_Queue.begin() ); // Remove coordinate from queue - bool SkipEnabled = (m_Queue.size() > QUEUE_SKIP_LIMIT); - Lock.Unlock(); // Unlock ASAP - m_evtRemoved.Set(); - - // Hack for regenerating chunks: if Y != 0, the chunk is considered invalid, even if it has its data set - if ((coords.m_ChunkY == 0) && m_World->IsChunkValid(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ)) - { - LOGD("Chunk [%d, %d] already generated, skipping generation", coords.m_ChunkX, coords.m_ChunkZ); - // Already generated, ignore request - continue; - } - - if (SkipEnabled && !m_World->HasChunkAnyClients(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ)) - { - LOGWARNING("Chunk generator overloaded, skipping chunk [%d, %d, %d]", coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ); - continue; - } - - LOGD("Generating chunk [%d, %d, %d]", coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ); - DoGenerate(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ); - - // Save the chunk right after generating, so that we don't have to generate it again on next run - m_World->GetStorage().QueueSaveChunk(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ); - } // while (!bStop) -} - - - - -void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - cChunkDef::BiomeMap BiomeMap; - cChunkDef::BlockTypes BlockTypes; - cChunkDef::BlockNibbles BlockMeta; - cChunkDef::HeightMap HeightMap; - cEntityList Entities; - cBlockEntityList BlockEntities; - - cLuaChunk LuaChunk( BlockTypes, BlockMeta, HeightMap, BiomeMap ); - if( cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_CHUNK_GENERATING, 3, a_ChunkX, a_ChunkZ, &LuaChunk ) ) - { - // A plugin interrupted generation, handle something plugin specific - if( LuaChunk.IsUsingDefaultBiomes() ) - { - m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, BiomeMap); - } - if( LuaChunk.IsUsingDefaultComposition() ) - { - m_CompositionGen->ComposeTerrain(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, BiomeMap, Entities, BlockEntities); - } - if( LuaChunk.IsUsingDefaultStructures() ) - { - for (cStructureGenList::iterator itr = m_StructureGens.begin(); itr != m_StructureGens.end(); ++itr) - { - (*itr)->GenStructures(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, Entities, BlockEntities); - } // for itr - m_StructureGens[] - } - if( LuaChunk.IsUsingDefaultFinish() ) - { - for (cFinishGenList::iterator itr = m_FinishGens.begin(); itr != m_FinishGens.end(); ++itr) - { - (*itr)->GenFinish(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, BiomeMap, Entities, BlockEntities); - } // for itr - m_FinishGens[] - } - } - else - { - // Use the composed generator: - m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, BiomeMap); - m_HeightGen->GenHeightMap(a_ChunkX, a_ChunkZ, HeightMap); - m_CompositionGen->ComposeTerrain(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, BiomeMap, Entities, BlockEntities); - for (cStructureGenList::iterator itr = m_StructureGens.begin(); itr != m_StructureGens.end(); ++itr) - { - (*itr)->GenStructures(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, Entities, BlockEntities); - } // for itr - m_StructureGens[] - for (cFinishGenList::iterator itr = m_FinishGens.begin(); itr != m_FinishGens.end(); ++itr) - { - (*itr)->GenFinish(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, BiomeMap, Entities, BlockEntities); - } // for itr - m_FinishGens[] - } - - m_World->SetChunkData( - a_ChunkX, a_ChunkY, a_ChunkZ, - BlockTypes, BlockMeta, - NULL, NULL, // We don't have lighting, chunk will be lighted when needed - &HeightMap, &BiomeMap, - Entities, BlockEntities, - true - ); - - cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_CHUNK_GENERATED, 3, m_World, a_ChunkX, a_ChunkZ); -} - - - - + +#include "Globals.h" + +#include "cChunkGenerator.h" +#include "cWorld.h" +#include "../iniFile/iniFile.h" +#include "BioGen.h" +#include "HeiGen.h" +#include "CompoGen.h" +#include "StructGen.h" +#include "FinishGen.h" +#include "cRoot.h" +#include "cPluginManager.h" +#include "cLuaChunk.h" + + + + + +/// If the generation queue size exceeds this number, a warning will be output +const int QUEUE_WARNING_LIMIT = 1000; + +/// If the generation queue size exceeds this number, chunks with no clients will be skipped +const int QUEUE_SKIP_LIMIT = 500; + + + + + +static BLOCKTYPE GetIniBlock(cIniFile & a_IniFile, const AString & a_SectionName, const AString & a_ValueName, const AString & a_Default) +{ + AString BlockType = a_IniFile.GetValueSet(a_SectionName, a_ValueName, a_Default); + BLOCKTYPE Block = BlockStringToType(BlockType); + if (Block < 0) + { + LOGWARN("[&s].%s Could not parse block value \"%s\". Using default: \"%s\".", a_SectionName.c_str(), a_ValueName.c_str(), BlockType.c_str(),a_Default.c_str()); + return BlockStringToType(a_Default); + } + return Block; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cChunkGenerator: + +cChunkGenerator::cChunkGenerator(void) + : super("cChunkGenerator") + , m_World(NULL) + , m_BiomeGen(NULL) + , m_HeightGen(NULL) + , m_CompositionGen(NULL) +{ +} + + + + + +cChunkGenerator::~cChunkGenerator() +{ + Stop(); +} + + + + + +bool cChunkGenerator::Start(cWorld * a_World, cIniFile & a_IniFile) +{ + MTRand rnd; + m_World = a_World; + m_Seed = a_IniFile.GetValueSetI("Seed", "Seed", rnd.randInt()); + + InitBiomeGen(a_IniFile); + InitHeightGen(a_IniFile); + InitCompositionGen(a_IniFile); + InitStructureGens(a_IniFile); + InitFinishGens(a_IniFile); + + a_IniFile.WriteFile(); + + return super::Start(); +} + + + + + +void cChunkGenerator::Stop(void) +{ + m_ShouldTerminate = true; + m_Event.Set(); + m_evtRemoved.Set(); // Wake up anybody waiting for empty queue + Wait(); + + // Delete the generating composition: + for (cFinishGenList::const_iterator itr = m_FinishGens.begin(); itr != m_FinishGens.end(); ++itr) + { + delete *itr; + } + m_FinishGens.clear(); + for (cStructureGenList::const_iterator itr = m_StructureGens.begin(); itr != m_StructureGens.end(); ++itr) + { + delete *itr; + } + m_StructureGens.clear(); + delete m_CompositionGen; + m_CompositionGen = NULL; + delete m_HeightGen; + m_HeightGen = NULL; + delete m_BiomeGen; + m_BiomeGen = NULL; +} + + + + + +void cChunkGenerator::InitBiomeGen(cIniFile & a_IniFile) +{ + AString BiomeGenName = a_IniFile.GetValueSet("Generator", "BiomeGen", ""); + if (BiomeGenName.empty()) + { + LOGWARN("[Generator]::BiomeGen value not found in world.ini, using \"DistortedVoronoi\"."); + BiomeGenName = "DistortedVoronoi"; + } + + bool CacheOffByDefault = false; + if (NoCaseCompare(BiomeGenName, "constant") == 0) + { + AString Biome = a_IniFile.GetValueSet("Generator", "ConstantBiome", "Plains"); + EMCSBiome b = StringToBiome(Biome); + if (b == -1) + { + LOGWARN("[Generator]::ConstantBiome value \"%s\" not recognized, using \"Plains\".", Biome.c_str()); + b = biPlains; + } + m_BiomeGen = new cBioGenConstant(b); + CacheOffByDefault = true; // we're generating faster than a cache would retrieve data :) + } + else if (NoCaseCompare(BiomeGenName, "checkerboard") == 0) + { + int BiomeSize = a_IniFile.GetValueSetI("Generator", "CheckerboardBiomeSize", 64); + AString Biomes = a_IniFile.GetValueSet ("Generator", "CheckerBoardBiomes", ""); + m_BiomeGen = new cBioGenCheckerboard(BiomeSize, Biomes); + CacheOffByDefault = true; // we're (probably) generating faster than a cache would retrieve data + } + else if (NoCaseCompare(BiomeGenName, "voronoi") == 0) + { + int CellSize = a_IniFile.GetValueSetI("Generator", "VoronoiCellSize", 64); + AString Biomes = a_IniFile.GetValueSet ("Generator", "VoronoiBiomes", ""); + m_BiomeGen = new cBioGenVoronoi(m_Seed, CellSize, Biomes); + } + else + { + if (NoCaseCompare(BiomeGenName, "distortedvoronoi") != 0) + { + LOGWARNING("Unknown BiomeGen \"%s\", using \"DistortedVoronoi\" instead.", BiomeGenName.c_str()); + } + int CellSize = a_IniFile.GetValueSetI("Generator", "DistortedVoronoiCellSize", 96); + AString Biomes = a_IniFile.GetValueSet ("Generator", "DistortedVoronoiBiomes", ""); + m_BiomeGen = new cBioGenDistortedVoronoi(m_Seed, CellSize, Biomes); + } + + // Add a cache, if requested: + int CacheSize = a_IniFile.GetValueSetI("Generator", "BiomeGenCacheSize", CacheOffByDefault ? 0 : 64); + if (CacheSize > 0) + { + if (CacheSize < 4) + { + LOGWARNING("Biomegen cache size set too low, would hurt performance instead of helping. Increasing from %d to %d", + CacheSize, 4 + ); + CacheSize = 4; + } + LOGINFO("Using a cache for biomegen of size %d.", CacheSize); + m_BiomeGen = new cBioGenCache(m_BiomeGen, CacheSize); + } +} + + + + + +void cChunkGenerator::InitHeightGen(cIniFile & a_IniFile) +{ + AString HeightGenName = a_IniFile.GetValueSet("Generator", "HeightGen", ""); + if (HeightGenName.empty()) + { + LOGWARN("[Generator]::HeightGen value not found in world.ini, using \"Biomal\"."); + HeightGenName = "Biomal"; + } + + bool CacheOffByDefault = false; + if (NoCaseCompare(HeightGenName, "flat") == 0) + { + int Height = a_IniFile.GetValueSetI("Generator", "FlatHeight", 5); + m_HeightGen = new cHeiGenFlat(Height); + CacheOffByDefault = true; // We're generating faster than a cache would retrieve data + } + else if (NoCaseCompare(HeightGenName, "classic") == 0) + { + // These used to be in terrain.ini, but now they are in world.ini (so that multiple worlds can have different values): + float HeightFreq1 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightFreq1", 0.1); + float HeightFreq2 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightFreq2", 1.0); + float HeightFreq3 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightFreq3", 2.0); + float HeightAmp1 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightAmp1", 1.0); + float HeightAmp2 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightAmp2", 0.5); + float HeightAmp3 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightAmp3", 0.5); + m_HeightGen = new cHeiGenClassic(m_Seed, HeightFreq1, HeightAmp1, HeightFreq2, HeightAmp2, HeightFreq3, HeightAmp3); + } + else // "biomal" or + { + if (NoCaseCompare(HeightGenName, "biomal") != 0) + { + LOGWARN("Unknown HeightGen \"%s\", using \"Biomal\" instead.", HeightGenName.c_str()); + } + m_HeightGen = new cHeiGenBiomal(m_Seed, *m_BiomeGen); + } + + // Add a cache, if requested: + int CacheSize = a_IniFile.GetValueSetI("Generator", "HeightGenCacheSize", CacheOffByDefault ? 0 : 64); + if (CacheSize > 0) + { + if (CacheSize < 4) + { + LOGWARNING("Heightgen cache size set too low, would hurt performance instead of helping. Increasing from %d to %d", + CacheSize, 4 + ); + CacheSize = 4; + } + LOGINFO("Using a cache for Heightgen of size %d.", CacheSize); + m_HeightGen = new cHeiGenCache(m_HeightGen, CacheSize); + } +} + + + + + +void cChunkGenerator::InitCompositionGen(cIniFile & a_IniFile) +{ + AString CompoGenName = a_IniFile.GetValueSet("Generator", "CompositionGen", ""); + if (CompoGenName.empty()) + { + LOGWARN("[Generator]::CompositionGen value not found in world.ini, using \"Biomal\"."); + CompoGenName = "Biomal"; + } + if (NoCaseCompare(CompoGenName, "sameblock") == 0) + { + AString BlockType = a_IniFile.GetValueSet("Generator", "SameBlockType", ""); + if (BlockType.empty()) + { + LOGWARN("[Generator]::SameBlockType value not found in world.ini, using \"stone\"."); + BlockType = "stone"; + } + int Block = GetIniBlock(a_IniFile, "[Generator]", "SameBlockType", "stone"); + bool Bedrocked = (a_IniFile.GetValueSetI("Generator", "SameBlockBedrocked", 1) != 0); + m_CompositionGen = new cCompoGenSameBlock((BLOCKTYPE)Block, Bedrocked); + } + else if (NoCaseCompare(CompoGenName, "debugbiomes") == 0) + { + m_CompositionGen = new cCompoGenDebugBiomes; + } + else if (NoCaseCompare(CompoGenName, "classic") == 0) + { + int SeaLevel = a_IniFile.GetValueSetI("Generator", "ClassicSeaLevel", 60); + int BeachHeight = a_IniFile.GetValueSetI("Generator", "ClassicBeachHeight", 2); + int BeachDepth = a_IniFile.GetValueSetI("Generator", "ClassicBeachDepth", 4); + BLOCKTYPE BlockTop = GetIniBlock(a_IniFile, "Generator", "ClassicBlockTop", "grass"); + BLOCKTYPE BlockMiddle = GetIniBlock(a_IniFile, "Generator", "ClassicBlockMiddle", "dirt"); + BLOCKTYPE BlockBottom = GetIniBlock(a_IniFile, "Generator", "ClassicBlockBottom", "stone"); + BLOCKTYPE BlockBeach = GetIniBlock(a_IniFile, "Generator", "ClassicBlockBeach", "sand"); + BLOCKTYPE BlockBeachBottom = GetIniBlock(a_IniFile, "Generator", "ClassicBlockBeachBottom", "sandstone"); + BLOCKTYPE BlockSea = GetIniBlock(a_IniFile, "Generator", "ClassicBlockSea", "9"); + m_CompositionGen = new cCompoGenClassic( + SeaLevel, BeachHeight, BeachDepth, BlockTop, BlockMiddle, BlockBottom, BlockBeach, + BlockBeachBottom, BlockSea + ); + } + else + { + if (NoCaseCompare(CompoGenName, "biomal") != 0) + { + LOGWARN("Unknown CompositionGen \"%s\", using \"biomal\" instead.", CompoGenName.c_str()); + } + int SeaLevel = a_IniFile.GetValueSetI("Generator", "BiomalSeaLevel", 62); + m_CompositionGen = new cCompoGenBiomal(m_Seed, SeaLevel); + } +} + + + + + +void cChunkGenerator::InitStructureGens(cIniFile & a_IniFile) +{ + AString Structures = a_IniFile.GetValueSet("Generator", "Structures", "Trees,MarbleCaves,OreNests"); + + AStringVector Str = StringSplit(Structures, ","); + for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr) + { + if (NoCaseCompare(*itr, "trees") == 0) + { + m_StructureGens.push_back(new cStructGenTrees(m_Seed, m_BiomeGen, m_HeightGen, m_CompositionGen)); + } + else if (NoCaseCompare(*itr, "marblecaves") == 0) + { + m_StructureGens.push_back(new cStructGenMarbleCaves(m_Seed)); + } + else if (NoCaseCompare(*itr, "orenests") == 0) + { + m_StructureGens.push_back(new cStructGenOreNests(m_Seed)); + } + else + { + LOGWARNING("Unknown structure generator: \"%s\". Ignoring.", itr->c_str()); + } + } // for itr - Str[] +} + + + + + +void cChunkGenerator::InitFinishGens(cIniFile & a_IniFile) +{ + AString Structures = a_IniFile.GetValueSet("Generator", "Finishers", "SprinkleFoliage,Ice,Snow"); + + AStringVector Str = StringSplit(Structures, ","); + for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr) + { + if (NoCaseCompare(*itr, "SprinkleFoliage") == 0) + { + m_FinishGens.push_back(new cFinishGenSprinkleFoliage(m_Seed)); + } + else if (NoCaseCompare(*itr, "Snow") == 0) + { + m_FinishGens.push_back(new cFinishGenSnow); + } + else if (NoCaseCompare(*itr, "Ice") == 0) + { + m_FinishGens.push_back(new cFinishGenIce); + } + } // for itr - Str[] +} + + + + + +void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + { + cCSLock Lock(m_CS); + + // Check if it is already in the queue: + for (cChunkCoordsList::iterator itr = m_Queue.begin(); itr != m_Queue.end(); ++itr) + { + if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ)) + { + // Already in the queue, bail out + return; + } + } // for itr - m_Queue[] + + // Add to queue, issue a warning if too many: + if (m_Queue.size() >= QUEUE_WARNING_LIMIT) + { + LOGWARN("WARNING: Adding chunk [%i, %i] to generation queue; Queue is too big! (%i)", a_ChunkX, a_ChunkZ, m_Queue.size()); + } + m_Queue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); + } + + m_Event.Set(); +} + + + + + +void cChunkGenerator::GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) +{ + m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap); +} + + + + + +void cChunkGenerator::WaitForQueueEmpty(void) +{ + cCSLock Lock(m_CS); + while (!m_ShouldTerminate && !m_Queue.empty()) + { + cCSUnlock Unlock(Lock); + m_evtRemoved.Wait(); + } +} + + + + + +int cChunkGenerator::GetQueueLength(void) +{ + cCSLock Lock(m_CS); + return (int)m_Queue.size(); +} + + + + + +EMCSBiome cChunkGenerator::GetBiomeAt(int a_BlockX, int a_BlockZ) +{ + cChunkDef::BiomeMap Biomes; + int Y = 0; + int ChunkX, ChunkZ; + cWorld::AbsoluteToRelative(a_BlockX, Y, a_BlockZ, ChunkX, Y, ChunkZ); + m_BiomeGen->GenBiomes(ChunkX, ChunkZ, Biomes); + return cChunkDef::GetBiome(Biomes, a_BlockX, a_BlockZ); +} + + + + + +void cChunkGenerator::Execute(void) +{ + while (!m_ShouldTerminate) + { + cCSLock Lock(m_CS); + while (m_Queue.size() == 0) + { + cCSUnlock Unlock(Lock); + m_Event.Wait(); + if (m_ShouldTerminate) + { + return; + } + } + + cChunkCoords coords = m_Queue.front(); // Get next coord from queue + m_Queue.erase( m_Queue.begin() ); // Remove coordinate from queue + bool SkipEnabled = (m_Queue.size() > QUEUE_SKIP_LIMIT); + Lock.Unlock(); // Unlock ASAP + m_evtRemoved.Set(); + + // Hack for regenerating chunks: if Y != 0, the chunk is considered invalid, even if it has its data set + if ((coords.m_ChunkY == 0) && m_World->IsChunkValid(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ)) + { + LOGD("Chunk [%d, %d] already generated, skipping generation", coords.m_ChunkX, coords.m_ChunkZ); + // Already generated, ignore request + continue; + } + + if (SkipEnabled && !m_World->HasChunkAnyClients(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ)) + { + LOGWARNING("Chunk generator overloaded, skipping chunk [%d, %d, %d]", coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ); + continue; + } + + LOGD("Generating chunk [%d, %d, %d]", coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ); + DoGenerate(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ); + + // Save the chunk right after generating, so that we don't have to generate it again on next run + m_World->GetStorage().QueueSaveChunk(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ); + } // while (!bStop) +} + + + + +void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cChunkDef::BiomeMap BiomeMap; + cChunkDef::BlockTypes BlockTypes; + cChunkDef::BlockNibbles BlockMeta; + cChunkDef::HeightMap HeightMap; + cEntityList Entities; + cBlockEntityList BlockEntities; + + cLuaChunk LuaChunk( BlockTypes, BlockMeta, HeightMap, BiomeMap ); + if( cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_CHUNK_GENERATING, 3, a_ChunkX, a_ChunkZ, &LuaChunk ) ) + { + // A plugin interrupted generation, handle something plugin specific + if( LuaChunk.IsUsingDefaultBiomes() ) + { + m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, BiomeMap); + } + if( LuaChunk.IsUsingDefaultComposition() ) + { + m_CompositionGen->ComposeTerrain(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, BiomeMap, Entities, BlockEntities); + } + if( LuaChunk.IsUsingDefaultStructures() ) + { + for (cStructureGenList::iterator itr = m_StructureGens.begin(); itr != m_StructureGens.end(); ++itr) + { + (*itr)->GenStructures(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, Entities, BlockEntities); + } // for itr - m_StructureGens[] + } + if( LuaChunk.IsUsingDefaultFinish() ) + { + for (cFinishGenList::iterator itr = m_FinishGens.begin(); itr != m_FinishGens.end(); ++itr) + { + (*itr)->GenFinish(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, BiomeMap, Entities, BlockEntities); + } // for itr - m_FinishGens[] + } + } + else + { + // Use the composed generator: + m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, BiomeMap); + m_HeightGen->GenHeightMap(a_ChunkX, a_ChunkZ, HeightMap); + m_CompositionGen->ComposeTerrain(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, BiomeMap, Entities, BlockEntities); + for (cStructureGenList::iterator itr = m_StructureGens.begin(); itr != m_StructureGens.end(); ++itr) + { + (*itr)->GenStructures(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, Entities, BlockEntities); + } // for itr - m_StructureGens[] + for (cFinishGenList::iterator itr = m_FinishGens.begin(); itr != m_FinishGens.end(); ++itr) + { + (*itr)->GenFinish(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, BiomeMap, Entities, BlockEntities); + } // for itr - m_FinishGens[] + } + + m_World->SetChunkData( + a_ChunkX, a_ChunkY, a_ChunkZ, + BlockTypes, BlockMeta, + NULL, NULL, // We don't have lighting, chunk will be lighted when needed + &HeightMap, &BiomeMap, + Entities, BlockEntities, + true + ); + + cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_CHUNK_GENERATED, 3, m_World, a_ChunkX, a_ChunkZ); +} + + + + diff --git a/source/cChunkGenerator.h b/source/cChunkGenerator.h index 126d94fb8..2faacfd47 100644 --- a/source/cChunkGenerator.h +++ b/source/cChunkGenerator.h @@ -1,226 +1,226 @@ - -// cChunkGenerator.h - -// Interfaces to the cChunkGenerator class representing the thread that generates chunks - -/* -The object takes requests for generating chunks and processes them in a separate thread one by one. -The requests are not added to the queue if there is already a request with the same coords -Before generating, the thread checks if the chunk hasn't been already generated. -It is theoretically possible to have multiple generator threads by having multiple instances of this object, -but then it MAY happen that the chunk is generated twice. -If the generator queue is overloaded, the generator skips chunks with no clients in them - -Generating works by composing several algorithms: -Biome, TerrainHeight, TerrainComposition, Ores, Structures and SmallFoliage -Each algorithm may be chosen from a pool of available algorithms in the same class and combined with others, -based on user's preferences in the world.ini. -See http://forum.mc-server.org/showthread.php?tid=409 for details. -*/ - - - - - -#pragma once - -#include "cIsThread.h" -#include "ChunkDef.h" - - - - - -// fwd: -class cWorld; -class cIniFile; - -// TODO: remove this: -class cWorldGenerator; - - - - - -/** The interface that a biome generator must implement -A biome generator takes chunk coords on input and outputs an array of biome indices for that chunk on output. -The output array is sequenced in the same way as the MapChunk packet's biome data. -*/ -class cBiomeGen -{ -public: - virtual ~cBiomeGen() {} // Force a virtual destructor in descendants - - /// Generates biomes for the given chunk - virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) = 0; -} ; - - - - - -/** The interface that a terrain height generator must implement -A terrain height generator takes chunk coords on input and outputs an array of terrain heights for that chunk. -The output array is sequenced in the same way as the BiomeGen's biome data. -The generator may request biome information from the underlying BiomeGen, it may even request information for -other chunks than the one it's currently generating (possibly neighbors - for averaging) -*/ -class cTerrainHeightGen -{ -public: - virtual ~cTerrainHeightGen() {} // Force a virtual destructor in descendants - - /// Generates heightmap for the given chunk - virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) = 0; -} ; - - - - - -/** The interface that a terrain composition generator must implement -Terrain composition takes chunk coords on input and outputs the blockdata for that entire chunk, along with -the list of entities. It is supposed to make use of the underlying TerrainHeightGen and BiomeGen for that purpose, -but it may request information for other chunks than the one it's currently generating from them. -*/ -class cTerrainCompositionGen -{ -public: - virtual ~cTerrainCompositionGen() {} // Force a virtual destructor in descendants - - virtual void ComposeTerrain( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated (the whole array gets initialized, even air) - cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated (the whole array gets initialized) - const cChunkDef::HeightMap & a_HeightMap, // The height map to fit - const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to - cEntityList & a_Entities, // Entitites may be generated along with the terrain - cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) - ) = 0; -} ; - - - - - -/** The interface that a structure generator must implement -Structures are generated after the terrain composition took place. It should modify the blocktype data to account -for whatever structures the generator is generating. -Note that ores are considered structures too, at least from the interface point of view. -Also note that a worldgenerator may contain multiple structure generators, one for each type of structure -*/ -class cStructureGen -{ -public: - virtual ~cStructureGen() {} // Force a virtual destructor in descendants - - virtual void GenStructures( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change - cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change - cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data - cEntityList & a_Entities, // Entities may be added or deleted - cBlockEntityList & a_BlockEntities // Block entities may be added or deleted - ) = 0; -} ; - -typedef std::list cStructureGenList; - - - - - -/** The interface that a finisher must implement -Finisher implements small additions after all structures have been generated. -*/ -class cFinishGen -{ -public: - virtual ~cFinishGen() {} // Force a virtual destructor in descendants - - virtual void GenFinish( - int a_ChunkX, int a_ChunkZ, - cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change - cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change - cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data - const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to - cEntityList & a_Entities, // Entities may be added or deleted - cBlockEntityList & a_BlockEntities // Block entities may be added or deleted - ) = 0; -} ; - -typedef std::list cFinishGenList; - - - - - -/// The chunk generator itself -class cChunkGenerator : - cIsThread -{ - typedef cIsThread super; - -public: - - cChunkGenerator (void); - ~cChunkGenerator(); - - bool Start(cWorld * a_World, cIniFile & a_IniFile); - void Stop(void); - - void QueueGenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Queues the chunk for generation; removes duplicate requests - - /// Generates the biomes for the specified chunk (directly, not in a separate thread) - void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap); - - void WaitForQueueEmpty(void); - - int GetQueueLength(void); - - int GetSeed(void) const { return m_Seed; } - - EMCSBiome GetBiomeAt(int a_BlockX, int a_BlockZ); - -private: - - cWorld * m_World; - - // The generation composition: - cBiomeGen * m_BiomeGen; - cTerrainHeightGen * m_HeightGen; - cTerrainCompositionGen * m_CompositionGen; - cStructureGenList m_StructureGens; - cFinishGenList m_FinishGens; - - int m_Seed; - - cCriticalSection m_CS; - cChunkCoordsList m_Queue; - cEvent m_Event; // Set when an item is added to the queue or the thread should terminate - cEvent m_evtRemoved; // Set when an item is removed from the queue - - /// Reads the biome gen settings from the ini and initializes m_BiomeGen accordingly - void InitBiomeGen(cIniFile & a_IniFile); - - /// Reads the HeightGen settings from the ini and initializes m_HeightGen accordingly - void InitHeightGen(cIniFile & a_IniFile); - - /// Reads the CompositionGen settings from the ini and initializes m_CompositionGen accordingly - void InitCompositionGen(cIniFile & a_IniFile); - - /// Reads the structures to generate from the ini and initializes m_StructureGens accordingly - void InitStructureGens(cIniFile & a_IniFile); - - /// Reads the finishers from the ini and initializes m_FinishGens accordingly - void InitFinishGens(cIniFile & a_IniFile); - - // cIsThread override: - virtual void Execute(void) override; - - void DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ); -}; - - - - + +// cChunkGenerator.h + +// Interfaces to the cChunkGenerator class representing the thread that generates chunks + +/* +The object takes requests for generating chunks and processes them in a separate thread one by one. +The requests are not added to the queue if there is already a request with the same coords +Before generating, the thread checks if the chunk hasn't been already generated. +It is theoretically possible to have multiple generator threads by having multiple instances of this object, +but then it MAY happen that the chunk is generated twice. +If the generator queue is overloaded, the generator skips chunks with no clients in them + +Generating works by composing several algorithms: +Biome, TerrainHeight, TerrainComposition, Ores, Structures and SmallFoliage +Each algorithm may be chosen from a pool of available algorithms in the same class and combined with others, +based on user's preferences in the world.ini. +See http://forum.mc-server.org/showthread.php?tid=409 for details. +*/ + + + + + +#pragma once + +#include "cIsThread.h" +#include "ChunkDef.h" + + + + + +// fwd: +class cWorld; +class cIniFile; + +// TODO: remove this: +class cWorldGenerator; + + + + + +/** The interface that a biome generator must implement +A biome generator takes chunk coords on input and outputs an array of biome indices for that chunk on output. +The output array is sequenced in the same way as the MapChunk packet's biome data. +*/ +class cBiomeGen +{ +public: + virtual ~cBiomeGen() {} // Force a virtual destructor in descendants + + /// Generates biomes for the given chunk + virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) = 0; +} ; + + + + + +/** The interface that a terrain height generator must implement +A terrain height generator takes chunk coords on input and outputs an array of terrain heights for that chunk. +The output array is sequenced in the same way as the BiomeGen's biome data. +The generator may request biome information from the underlying BiomeGen, it may even request information for +other chunks than the one it's currently generating (possibly neighbors - for averaging) +*/ +class cTerrainHeightGen +{ +public: + virtual ~cTerrainHeightGen() {} // Force a virtual destructor in descendants + + /// Generates heightmap for the given chunk + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) = 0; +} ; + + + + + +/** The interface that a terrain composition generator must implement +Terrain composition takes chunk coords on input and outputs the blockdata for that entire chunk, along with +the list of entities. It is supposed to make use of the underlying TerrainHeightGen and BiomeGen for that purpose, +but it may request information for other chunks than the one it's currently generating from them. +*/ +class cTerrainCompositionGen +{ +public: + virtual ~cTerrainCompositionGen() {} // Force a virtual destructor in descendants + + virtual void ComposeTerrain( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated (the whole array gets initialized, even air) + cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated (the whole array gets initialized) + const cChunkDef::HeightMap & a_HeightMap, // The height map to fit + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entitites may be generated along with the terrain + cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) + ) = 0; +} ; + + + + + +/** The interface that a structure generator must implement +Structures are generated after the terrain composition took place. It should modify the blocktype data to account +for whatever structures the generator is generating. +Note that ores are considered structures too, at least from the interface point of view. +Also note that a worldgenerator may contain multiple structure generators, one for each type of structure +*/ +class cStructureGen +{ +public: + virtual ~cStructureGen() {} // Force a virtual destructor in descendants + + virtual void GenStructures( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) = 0; +} ; + +typedef std::list cStructureGenList; + + + + + +/** The interface that a finisher must implement +Finisher implements small additions after all structures have been generated. +*/ +class cFinishGen +{ +public: + virtual ~cFinishGen() {} // Force a virtual destructor in descendants + + virtual void GenFinish( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) = 0; +} ; + +typedef std::list cFinishGenList; + + + + + +/// The chunk generator itself +class cChunkGenerator : + cIsThread +{ + typedef cIsThread super; + +public: + + cChunkGenerator (void); + ~cChunkGenerator(); + + bool Start(cWorld * a_World, cIniFile & a_IniFile); + void Stop(void); + + void QueueGenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Queues the chunk for generation; removes duplicate requests + + /// Generates the biomes for the specified chunk (directly, not in a separate thread) + void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap); + + void WaitForQueueEmpty(void); + + int GetQueueLength(void); + + int GetSeed(void) const { return m_Seed; } + + EMCSBiome GetBiomeAt(int a_BlockX, int a_BlockZ); + +private: + + cWorld * m_World; + + // The generation composition: + cBiomeGen * m_BiomeGen; + cTerrainHeightGen * m_HeightGen; + cTerrainCompositionGen * m_CompositionGen; + cStructureGenList m_StructureGens; + cFinishGenList m_FinishGens; + + int m_Seed; + + cCriticalSection m_CS; + cChunkCoordsList m_Queue; + cEvent m_Event; // Set when an item is added to the queue or the thread should terminate + cEvent m_evtRemoved; // Set when an item is removed from the queue + + /// Reads the biome gen settings from the ini and initializes m_BiomeGen accordingly + void InitBiomeGen(cIniFile & a_IniFile); + + /// Reads the HeightGen settings from the ini and initializes m_HeightGen accordingly + void InitHeightGen(cIniFile & a_IniFile); + + /// Reads the CompositionGen settings from the ini and initializes m_CompositionGen accordingly + void InitCompositionGen(cIniFile & a_IniFile); + + /// Reads the structures to generate from the ini and initializes m_StructureGens accordingly + void InitStructureGens(cIniFile & a_IniFile); + + /// Reads the finishers from the ini and initializes m_FinishGens accordingly + void InitFinishGens(cIniFile & a_IniFile); + + // cIsThread override: + virtual void Execute(void) override; + + void DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ); +}; + + + + diff --git a/source/cChunkMap.cpp b/source/cChunkMap.cpp index a881c71ef..c2c26bae7 100644 --- a/source/cChunkMap.cpp +++ b/source/cChunkMap.cpp @@ -1,1485 +1,1485 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cChunkMap.h" -#include "cWorld.h" -#include "cRoot.h" -#include "cMakeDir.h" -#include "cPlayer.h" -#include "BlockID.h" -#include "cItem.h" -#include "cPickup.h" -#include "cChunk.h" -#include "Trees.h" // used in cChunkMap::ReplaceTreeBlocks() for tree block discrimination - -#ifndef _WIN32 - #include // abs -#endif - -#include "zlib.h" -#include - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cChunkMap: - -cChunkMap::cChunkMap(cWorld * a_World ) - : m_World( a_World ) -{ -} - - - - - -cChunkMap::~cChunkMap() -{ - cCSLock Lock(m_CSLayers); - for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) - { - delete *itr; - } // for itr - m_Layers[] -} - - - - - -void cChunkMap::RemoveLayer( cChunkLayer* a_Layer ) -{ - cCSLock Lock(m_CSLayers); - m_Layers.remove(a_Layer); -} - - - - - -cChunkMap::cChunkLayer * cChunkMap::GetLayer(int a_LayerX, int a_LayerZ) -{ - cCSLock Lock(m_CSLayers); - for (cChunkLayerList::const_iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) - { - if (((*itr)->GetX() == a_LayerX) && ((*itr)->GetZ() == a_LayerZ)) - { - return *itr; - } - } - - // Not found, create new: - cChunkLayer * Layer = new cChunkLayer(a_LayerX, a_LayerZ, this); - if (Layer == NULL) - { - LOGERROR("cChunkMap: Cannot create new layer, server out of memory?"); - return NULL; - } - m_Layers.push_back(Layer); - return Layer; -} - - - - - -cChunkMap::cChunkLayer * cChunkMap::GetLayerForChunk( int a_ChunkX, int a_ChunkZ ) -{ - const int LayerX = (int)(floorf((float)a_ChunkX / (float)(LAYER_SIZE))); - const int LayerZ = (int)(floorf((float)a_ChunkZ / (float)(LAYER_SIZE))); - return GetLayer( LayerX, LayerZ ); -} - - - - - -cChunkPtr cChunkMap::GetChunk( int a_ChunkX, int a_ChunkY, int a_ChunkZ ) -{ - // No need to lock m_CSLayers, since it's already locked by the operation that called us - cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ ); - if (Layer == NULL) - { - // An error must have occurred, since layers are automatically created if they don't exist - return NULL; - } - - cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ); - if (Chunk == NULL) - { - return NULL; - } - if (!(Chunk->IsValid())) - { - m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ, true); - } - return Chunk; -} - - - - - -cChunkPtr cChunkMap::GetChunkNoGen( int a_ChunkX, int a_ChunkY, int a_ChunkZ ) -{ - // No need to lock m_CSLayers, since it's already locked by the operation that called us - cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ ); - if (Layer == NULL) - { - // An error must have occurred, since layers are automatically created if they don't exist - return NULL; - } - - cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ); - if (Chunk == NULL) - { - return NULL; - } - if (!(Chunk->IsValid())) - { - m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ, false); - } - - return Chunk; -} - - - - - -cChunkPtr cChunkMap::GetChunkNoLoad( int a_ChunkX, int a_ChunkY, int a_ChunkZ ) -{ - // No need to lock m_CSLayers, since it's already locked by the operation that called us - cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ ); - if (Layer == NULL) - { - // An error must have occurred, since layers are automatically created if they don't exist - return NULL; - } - - return Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ); -} - - - - - -bool cChunkMap::LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) -{ - // We already have m_CSLayers locked since this can be called only from within the tick thread - int ChunkX, ChunkZ; - cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); - if (Chunk == NULL) - { - return false; - } - - int Index = cChunkDef::MakeIndexNoCheck(a_BlockX, a_BlockY, a_BlockZ); - a_BlockType = Chunk->GetBlock(Index); - a_BlockMeta = Chunk->GetMeta(Index); - return true; -} - - - - - -bool cChunkMap::LockedSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) -{ - // We already have m_CSLayers locked since this can be called only from within the tick thread - int ChunkX, ChunkZ; - cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); - if (Chunk == NULL) - { - return false; - } - - Chunk->SetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); - return true; -} - - - - - -bool cChunkMap::LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) -{ - // We already have m_CSLayers locked since this can be called only from within the tick thread - int ChunkX, ChunkZ; - cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); - if (Chunk == NULL) - { - return false; - } - - Chunk->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); - return true; -} - - - - - -void cChunkMap::BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude) -{ - // Broadcasts a_Packet to all clients in the chunk where block [x, y, z] is, except to client a_Exclude - - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); - if (Chunk == NULL) - { - return; - } - // It's perfectly legal to broadcast packets even to invalid chunks! - Chunk->Broadcast(a_Packet, a_Exclude); -} - - - - - -void cChunkMap::BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, const cPacket * a_Packet, cClientHandle * a_Exclude) -{ - // Broadcasts a_Packet to all clients in the chunk where block [x, y, z] is, except to client a_Exclude - - cCSLock Lock(m_CSLayers); - int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); - if (Chunk == NULL) - { - return; - } - // It's perfectly legal to broadcast packets even to invalid chunks! - Chunk->Broadcast(a_Packet, a_Exclude); -} - - - - - -void cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z) -{ - // a_Player rclked block entity at the coords specified, handle it - cCSLock Lock(m_CSLayers); - int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) - { - return; - } - Chunk->UseBlockEntity(a_Player, a_X, a_Y, a_Z); -} - - - - - -void cChunkMap::MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) - { - return; - } - Chunk->MarkDirty(); -} - - - - - -void cChunkMap::MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) - { - return; - } - Chunk->MarkSaving(); -} - - - - - -void cChunkMap::MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) - { - return; - } - Chunk->MarkSaved(); -} - - - - - -void cChunkMap::SetChunkData( - int a_ChunkX, int a_ChunkY, int a_ChunkZ, - const BLOCKTYPE * a_BlockTypes, - const NIBBLETYPE * a_BlockMeta, - const NIBBLETYPE * a_BlockLight, - const NIBBLETYPE * a_BlockSkyLight, - const cChunkDef::HeightMap * a_HeightMap, - const cChunkDef::BiomeMap & a_BiomeMap, - cEntityList & a_Entities, - cBlockEntityList & a_BlockEntities, - bool a_MarkDirty -) -{ - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkY, a_ChunkZ); - if (Chunk == NULL) - { - return; - } - Chunk->SetAllData(a_BlockTypes, a_BlockMeta, a_BlockLight, a_BlockSkyLight, a_HeightMap, a_BiomeMap, a_Entities, a_BlockEntities); - Chunk->SetValid(); - - if (a_MarkDirty) - { - Chunk->MarkDirty(); - } -} - - - - - -void cChunkMap::ChunkLighted( - int a_ChunkX, int a_ChunkZ, - const cChunkDef::BlockNibbles & a_BlockLight, - const cChunkDef::BlockNibbles & a_SkyLight -) -{ - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); - if (Chunk == NULL) - { - return; - } - Chunk->SetLight(a_BlockLight, a_SkyLight); - Chunk->MarkDirty(); -} - - - - - -bool cChunkMap::GetChunkData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback) -{ - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) - { - return false; - } - Chunk->GetAllData(a_Callback); - return true; -} - - - - - -bool cChunkMap::GetChunkBlockTypes(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockTypes) -{ - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) - { - return false; - } - Chunk->GetBlockTypes(a_BlockTypes); - return true; -} - - - - - -bool cChunkMap::GetChunkBlockData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData) -{ - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) - { - return false; - } - Chunk->GetBlockData(a_BlockData); - return true; -} - - - - - -bool cChunkMap::IsChunkValid(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkY, a_ChunkZ); - return (Chunk != NULL) && Chunk->IsValid(); -} - - - - - -bool cChunkMap::HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); - return (Chunk != NULL) && Chunk->HasAnyClients(); -} - - - - - -int cChunkMap::GetHeight(int a_BlockX, int a_BlockZ) -{ - cCSLock Lock(m_CSLayers); - int ChunkX, ChunkZ, BlockY = 0; - cChunkDef::AbsoluteToRelative(a_BlockX, BlockY, a_BlockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); - if (Chunk == NULL) - { - return 0; - } - - // Wait for the chunk to become valid: - while (!Chunk->IsValid()) - { - GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); // Re-queue (in case it managed to get unloaded before we caught it - cCSUnlock Unlock(Lock); - m_evtChunkValid.Wait(); - } - - return Chunk->GetHeight(a_BlockX, a_BlockZ); -} - - - - - -void cChunkMap::FastSetBlocks(sSetBlockList & a_BlockList) -{ - sSetBlockList Failed; - - // Process all items from a_BlockList, either successfully or by placing into Failed - while (!a_BlockList.empty()) - { - int ChunkX = a_BlockList.front().ChunkX; - int ChunkZ = a_BlockList.front().ChunkZ; - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); - if ((Chunk != NULL) && Chunk->IsValid()) - { - for (sSetBlockList::iterator itr = a_BlockList.begin(); itr != a_BlockList.end();) - { - if ((itr->ChunkX == ChunkX) && (itr->ChunkZ == ChunkZ)) - { - Chunk->FastSetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta); - itr = a_BlockList.erase(itr); - } - else - { - ++itr; - } - } // for itr - a_BlockList[] - } - else - { - // The chunk is not valid, move all blocks within this chunk to Failed - for (sSetBlockList::iterator itr = a_BlockList.begin(); itr != a_BlockList.end();) - { - if ((itr->ChunkX == ChunkX) && (itr->ChunkZ == ChunkZ)) - { - Failed.push_back(*itr); - itr = a_BlockList.erase(itr); - } - else - { - ++itr; - } - } // for itr - a_BlockList[] - } - } - - // Return the failed: - std::swap(Failed, a_BlockList); -} - - - - - -void cChunkMap::CollectPickupsByPlayer(cPlayer * a_Player) -{ - int BlockX = (int)(a_Player->GetPosX()); // Truncating doesn't matter much; we're scanning entire chunks anyway - int BlockY = (int)(a_Player->GetPosY()); - int BlockZ = (int)(a_Player->GetPosZ()); - int ChunkX, ChunkZ, ChunkY = ZERO_CHUNK_Y; - cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); - int OtherChunkX = ChunkX + ((BlockX > 8) ? 1 : -1); - int OtherChunkZ = ChunkZ + ((BlockZ > 8) ? 1 : -1); - - // We suppose that each player keeps their chunks in memory, therefore it makes little sense to try to re-load or even generate them. - // The only time the chunks are not valid is when the player is downloading the initial world and they should not call this at that moment - - cCSLock Lock(m_CSLayers); - GetChunkNoLoad(ChunkX, ChunkY, ChunkZ)->CollectPickupsByPlayer(a_Player); - - // Check the neighboring chunks as well: - GetChunkNoLoad(OtherChunkX, ChunkY, ChunkZ )->CollectPickupsByPlayer(a_Player); - GetChunkNoLoad(OtherChunkX, ChunkY, OtherChunkZ)->CollectPickupsByPlayer(a_Player); - GetChunkNoLoad(ChunkX, ChunkY, ChunkZ )->CollectPickupsByPlayer(a_Player); - GetChunkNoLoad(ChunkX, ChunkY, OtherChunkZ)->CollectPickupsByPlayer(a_Player); -} - - - - - -BLOCKTYPE cChunkMap::GetBlock(int a_X, int a_Y, int a_Z) -{ - int ChunkX, ChunkZ; - cChunkDef::AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ ); - - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); - if ((Chunk != NULL) && Chunk->IsValid()) - { - return Chunk->GetBlock(a_X, a_Y, a_Z); - } - return 0; -} - - - - - -BLOCKTYPE cChunkMap::GetBlockMeta(int a_X, int a_Y, int a_Z) -{ - int ChunkX, ChunkZ; - cChunkDef::AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ ); - - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); - if ((Chunk != NULL) && Chunk->IsValid() ) - { - return Chunk->GetMeta(a_X, a_Y, a_Z); - } - return 0; -} - - - - - -BLOCKTYPE cChunkMap::GetBlockSkyLight(int a_X, int a_Y, int a_Z) -{ - int ChunkX, ChunkZ; - cChunkDef::AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ ); - - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); - if ((Chunk != NULL) && Chunk->IsValid() ) - { - return Chunk->GetSkyLight( a_X, a_Y, a_Z ); - } - return 0; -} - - - - - -void cChunkMap::SetBlockMeta(int a_X, int a_Y, int a_Z, char a_BlockMeta) -{ - int ChunkX, ChunkZ; - cChunkDef::AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ ); - - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); - if ((Chunk != NULL) && Chunk->IsValid() ) - { - Chunk->SetMeta(a_X, a_Y, a_Z, a_BlockMeta); - Chunk->MarkDirty(); - Chunk->SendBlockTo( a_X, a_Y, a_Z, NULL ); - } -} - - - - - -void cChunkMap::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta) -{ - int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; - cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ ); - - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); - if ((Chunk != NULL) && Chunk->IsValid()) - { - Chunk->SetBlock(X, Y, Z, a_BlockType, a_BlockMeta ); - } -} - - - - - -void cChunkMap::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) -{ - int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; - cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ ); - - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); - if ((Chunk != NULL) && Chunk->IsValid()) - { - Chunk->GetBlockTypeMeta(X, Y, Z, a_BlockType, a_BlockMeta); - } -} - - - - - -void cChunkMap::ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType) -{ - cCSLock Lock(m_CSLayers); - for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) - { - cChunkPtr Chunk = GetChunk(itr->ChunkX, ZERO_CHUNK_Y, itr->ChunkZ ); - if ((Chunk == NULL) || !Chunk->IsValid()) - { - continue; - } - if (Chunk->GetBlock(itr->x, itr->y, itr->z) == a_FilterBlockType) - { - Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta); - } - } -} - - - - - -void cChunkMap::ReplaceTreeBlocks(const sSetBlockVector & a_Blocks) -{ - cCSLock Lock(m_CSLayers); - for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) - { - cChunkPtr Chunk = GetChunk(itr->ChunkX, ZERO_CHUNK_Y, itr->ChunkZ ); - if ((Chunk == NULL) || !Chunk->IsValid()) - { - continue; - } - switch (Chunk->GetBlock(itr->x, itr->y, itr->z)) - { - CASE_TREE_OVERWRITTEN_BLOCKS: - { - Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta); - break; - } - } - } // for itr - a_Blocks[] -} - - - - - -EMCSBiome cChunkMap::GetBiomeAt (int a_BlockX, int a_BlockZ) -{ - int ChunkX, ChunkZ, X = a_BlockX, Y = 0, Z = a_BlockZ; - cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ ); - - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); - if ((Chunk != NULL) && Chunk->IsValid()) - { - return Chunk->GetBiomeAt(X, Z); - } - else - { - return m_World->GetGenerator().GetBiomeAt(a_BlockX, a_BlockZ); - } -} - - - - - -bool cChunkMap::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure) -{ - bool res = true; - cCSLock Lock(m_CSLayers); - for (sSetBlockVector::iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) - { - cChunkPtr Chunk = GetChunk(itr->ChunkX, ZERO_CHUNK_Y, itr->ChunkZ ); - if ((Chunk == NULL) || !Chunk->IsValid()) - { - if (!a_ContinueOnFailure) - { - return false; - } - res = false; - continue; - } - int idx = cChunkDef::MakeIndexNoCheck(itr->x, itr->y, itr->z); - itr->BlockType = Chunk->GetBlock(idx); - itr->BlockMeta = Chunk->GetMeta(idx); - } - return res; -} - - - - - -bool cChunkMap::DigBlock(int a_X, int a_Y, int a_Z) -{ - int PosX = a_X, PosY = a_Y, PosZ = a_Z, ChunkX, ChunkZ; - - cChunkDef::AbsoluteToRelative( PosX, PosY, PosZ, ChunkX, ChunkZ ); - - { - cCSLock Lock(m_CSLayers); - cChunkPtr DestChunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); - if ((DestChunk == NULL) || !DestChunk->IsValid()) - { - return false; - } - - DestChunk->SetBlock(PosX, PosY, PosZ, E_BLOCK_AIR, 0 ); - } - - m_World->GetSimulatorManager()->WakeUp(a_X, a_Y, a_Z); - - return true; -} - - - - - -void cChunkMap::SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player) -{ - int ChunkX, ChunkZ; - cChunkDef::AbsoluteToRelative(a_X, a_Y, a_Z, ChunkX, ChunkZ); - - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); - if (Chunk->IsValid()) - { - Chunk->SendBlockTo(a_X, a_Y, a_Z, a_Player->GetClientHandle()); - } -} - - - - - -void cChunkMap::CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback) -{ - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk1 = GetChunkNoGen(a_ChunkX1, a_ChunkY1, a_ChunkZ1); - if (Chunk1 == NULL) - { - return; - } - cChunkPtr Chunk2 = GetChunkNoGen(a_ChunkX2, a_ChunkY2, a_ChunkZ2); - if (Chunk2 == NULL) - { - return; - } - - cClientHandleList Clients1(Chunk1->GetAllClients()); - cClientHandleList Clients2(Chunk2->GetAllClients()); - - // Find "removed" clients: - for (cClientHandleList::iterator itr1 = Clients1.begin(); itr1 != Clients1.end(); ++itr1) - { - bool Found = false; - for (cClientHandleList::iterator itr2 = Clients2.begin(); itr2 != Clients2.end(); ++itr2) - { - if (*itr1 == *itr2) - { - Found = true; - break; - } - } // for itr2 - Clients2[] - if (!Found) - { - a_Callback.Removed(*itr1); - } - } // for itr1 - Clients1[] - - // Find "added" clients: - for (cClientHandleList::iterator itr2 = Clients2.begin(); itr2 != Clients2.end(); ++itr2) - { - bool Found = false; - for (cClientHandleList::iterator itr1 = Clients1.begin(); itr1 != Clients1.end(); ++itr1) - { - if (*itr1 == *itr2) - { - Found = true; - break; - } - } // for itr1 - Clients1[] - if (!Found) - { - a_Callback.Added(*itr2); - } - } // for itr2 - Clients2[] -} - - - - - -bool cChunkMap::AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) -{ - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ); - if (Chunk == NULL) - { - return false; - } - return Chunk->AddClient(a_Client); -} - - - - - -void cChunkMap::RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) -{ - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); - if (Chunk == NULL) - { - return; - } - Chunk->RemoveClient(a_Client); -} - - - - - -void cChunkMap::RemoveClientFromChunks(cClientHandle * a_Client) -{ - cCSLock Lock(m_CSLayers); - - for (cChunkLayerList::const_iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) - { - (*itr)->RemoveClient(a_Client); - } // for itr - m_Layers[] -} - - - - - -void cChunkMap::MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - cCSLock Lock(m_CSLayers); - cChunkPtr OldChunk = GetChunkNoGen(a_Entity->GetChunkX(), a_Entity->GetChunkY(), a_Entity->GetChunkZ()); - if (OldChunk != NULL) - { - OldChunk->RemoveEntity(a_Entity); - } - cChunkPtr NewChunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); - if (NewChunk != NULL) - { - NewChunk->AddEntity(a_Entity); - } -} - - - - - -void cChunkMap::RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); - if ((Chunk == NULL) && !Chunk->IsValid()) - { - return; - } - Chunk->RemoveEntity(a_Entity); -} - - - - - -void cChunkMap::TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - cCSLock Lock(m_CSLayers); - GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ); -} - - - - - -/// Loads the chunk synchronously, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before) -bool cChunkMap::LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - { - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); - if (Chunk == NULL) - { - // Internal error - return false; - } - if (Chunk->IsValid()) - { - // Already loaded - return true; - } - if (Chunk->HasLoadFailed()) - { - // Already tried loading and it failed - return false; - } - } - return m_World->GetStorage().LoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ); -} - - - - - -/// Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid() -void cChunkMap::LoadChunks(const cChunkCoordsList & a_Chunks) -{ - for (cChunkCoordsList::const_iterator itr = a_Chunks.begin(); itr != a_Chunks.end(); ++itr) - { - LoadChunk(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ); - } // for itr - a_Chunks[] -} - - - - - -void cChunkMap::ChunkLoadFailed(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkY, a_ChunkZ); - if (Chunk == NULL) - { - return; - } - Chunk->MarkLoadFailed(); -} - - - - - -void cChunkMap::UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) -{ - cCSLock Lock(m_CSLayers); - int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); - if ((Chunk == NULL) || !Chunk->IsValid()) - { - return; - } - Chunk->UpdateSign(a_X, a_Y, a_Z, a_Line1, a_Line2, a_Line3, a_Line4); -} - - - - - -void cChunkMap::ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay) -{ - cCSLock Lock(m_CSLayers); - for (cChunkCoordsList::const_iterator itr = a_Chunks.begin(); itr != a_Chunks.end(); ++itr) - { - cChunkPtr Chunk = GetChunkNoLoad(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ); - if (Chunk == NULL) - { - continue; - } - Chunk->Stay(a_Stay); - } -} - - - - - -void cChunkMap::MarkChunkRegenerating(int a_ChunkX, int a_ChunkZ) -{ - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); - if (Chunk == NULL) - { - // Not present - return; - } - Chunk->MarkRegenerating(); -} - - - - - -bool cChunkMap::IsChunkLighted(int a_ChunkX, int a_ChunkZ) -{ - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); - if (Chunk == NULL) - { - // Not present - return false; - } - return Chunk->IsLightValid(); -} - - - - - -void cChunkMap::GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty) -{ - a_NumChunksValid = 0; - a_NumChunksDirty = 0; - cCSLock Lock(m_CSLayers); - for (cChunkLayerList::const_iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) - { - int NumValid = 0, NumDirty = 0; - (*itr)->GetChunkStats(NumValid, NumDirty); - a_NumChunksValid += NumValid; - a_NumChunksDirty += NumDirty; - } // for itr - m_Layers[] -} - - - - - -void cChunkMap::GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, MTRand & a_Rand) -{ - int ChunkX, ChunkZ; - cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); - if (Chunk != NULL) - { - Chunk->GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_Rand); - } -} - - - - - -void cChunkMap::GrowSugarcane(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow) -{ - int ChunkX, ChunkZ; - cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); - if (Chunk != NULL) - { - Chunk->GrowSugarcane(a_BlockX, a_BlockY, a_BlockZ, a_NumBlocksToGrow); - } -} - - - - - -void cChunkMap::GrowCactus(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow) -{ - int ChunkX, ChunkZ; - cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); - if (Chunk != NULL) - { - Chunk->GrowCactus(a_BlockX, a_BlockY, a_BlockZ, a_NumBlocksToGrow); - } -} - - - - - -void cChunkMap::SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ) -{ - int ChunkX, ChunkZ; - cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); - if (Chunk != NULL) - { - Chunk->SetNextBlockTick(a_BlockX, a_BlockY, a_BlockZ); - } -} - - - - - -void cChunkMap::Tick( float a_Dt, MTRand & a_TickRandom ) -{ - cCSLock Lock(m_CSLayers); - for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) - { - (*itr)->Tick(a_Dt, a_TickRandom); - } // for itr - m_Layers -} - - - - - -void cChunkMap::UnloadUnusedChunks() -{ - cCSLock Lock(m_CSLayers); - for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) - { - (*itr)->UnloadUnusedChunks(); - } // for itr - m_Layers -} - - - - - -void cChunkMap::SaveAllChunks(void) -{ - cCSLock Lock(m_CSLayers); - for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) - { - (*itr)->Save(); - } // for itr - m_Layers[] -} - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cChunkMap::cChunkLayer: - -cChunkMap::cChunkLayer::cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent) - : m_LayerX( a_LayerX ) - , m_LayerZ( a_LayerZ ) - , m_Parent( a_Parent ) - , m_NumChunksLoaded( 0 ) -{ - memset(m_Chunks, 0, sizeof(m_Chunks)); -} - - - - - -cChunkMap::cChunkLayer::~cChunkLayer() -{ - for (int i = 0; i < ARRAYCOUNT(m_Chunks); ++i) - { - delete m_Chunks[i]; - } // for i - m_Chunks[] -} - - - - - -cChunkPtr cChunkMap::cChunkLayer::GetChunk( int a_ChunkX, int a_ChunkY, int a_ChunkZ ) -{ - // Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check - - const int LocalX = a_ChunkX - m_LayerX * LAYER_SIZE; - const int LocalZ = a_ChunkZ - m_LayerZ * LAYER_SIZE; - - if (!((LocalX < LAYER_SIZE) && (LocalZ < LAYER_SIZE) && (LocalX > -1) && (LocalZ > -1))) - { - ASSERT(!"Asking a cChunkLayer for a chunk that doesn't belong to it!"); - return NULL; - } - - int Index = LocalX + LocalZ * LAYER_SIZE; - if (m_Chunks[Index] == NULL) - { - m_Chunks[Index] = new cChunk(a_ChunkX, 0, a_ChunkZ, m_Parent, m_Parent->GetWorld()); - } - return m_Chunks[Index]; -} - - - - - -void cChunkMap::cChunkLayer::Tick(float a_Dt, MTRand & a_TickRand) -{ - for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++) - { - // Only tick chunks that are valid and have clients: - if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid() && m_Chunks[i]->HasAnyClients()) - { - m_Chunks[i]->Tick(a_Dt, a_TickRand); - } - } // for i - m_Chunks[] -} - - - - - -void cChunkMap::cChunkLayer::RemoveClient(cClientHandle * a_Client) -{ - for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++) - { - if (m_Chunks[i] != NULL) - { - m_Chunks[i]->RemoveClient(a_Client); - } - } // for i - m_Chunks[] -} - - - - - -int cChunkMap::cChunkLayer::GetNumChunksLoaded(void) const -{ - int NumChunks = 0; - for ( int i = 0; i < ARRAYCOUNT(m_Chunks); ++i ) - { - if (m_Chunks[i] != NULL) - { - NumChunks++; - } - } // for i - m_Chunks[] - return NumChunks; -} - - - - - -void cChunkMap::cChunkLayer::GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty) const -{ - int NumValid = 0; - int NumDirty = 0; - for ( int i = 0; i < ARRAYCOUNT(m_Chunks); ++i ) - { - if (m_Chunks[i] == NULL) - { - continue; - } - NumValid++; - if (m_Chunks[i]->IsDirty()) - { - NumDirty++; - } - } // for i - m_Chunks[] - a_NumChunksValid = NumValid; - a_NumChunksDirty = NumDirty; -} - - - - - -void cChunkMap::cChunkLayer::Save(void) -{ - cWorld * World = m_Parent->GetWorld(); - for (int i = 0; i < ARRAYCOUNT(m_Chunks); ++i) - { - if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid() && m_Chunks[i]->IsDirty()) - { - World->GetStorage().QueueSaveChunk(m_Chunks[i]->GetPosX(), m_Chunks[i]->GetPosY(), m_Chunks[i]->GetPosZ()); - } - } // for i - m_Chunks[] -} - - - - - -void cChunkMap::cChunkLayer::UnloadUnusedChunks(void) -{ - for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++) - { - if ((m_Chunks[i] != NULL) && (m_Chunks[i]->CanUnload())) - { - // The cChunk destructor calls our GetChunk() while removing its entities - // so we still need to be able to return the chunk. Therefore we first delete, then NULLify - // Doing otherwise results in bug http://forum.mc-server.org/showthread.php?tid=355 - delete m_Chunks[i]; - m_Chunks[i] = NULL; - } - } // for i - m_Chunks[] -} - - - - - -int cChunkMap::GetNumChunks(void) -{ - cCSLock Lock(m_CSLayers); - int NumChunks = 0; - for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) - { - NumChunks += (*itr)->GetNumChunksLoaded(); - } - return NumChunks; -} - - - - - -void cChunkMap::ChunkValidated(void) -{ - m_evtChunkValid.Set(); -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cChunkStay: - -cChunkStay::cChunkStay(cWorld * a_World) : - m_World(a_World), - m_IsEnabled(false) -{ -} - - - - - -cChunkStay::~cChunkStay() -{ - Clear(); -} - - - - - -void cChunkStay::Clear(void) -{ - if (m_IsEnabled) - { - Disable(); - } - m_Chunks.clear(); -} - - - - - -void cChunkStay::Add(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - ASSERT(!m_IsEnabled); - - for (cChunkCoordsList::const_iterator itr = m_Chunks.begin(); itr != m_Chunks.end(); ++itr) - { - if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ)) - { - // Already present - return; - } - } // for itr - Chunks[] - m_Chunks.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); -} - - - - - -void cChunkStay::Remove(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - ASSERT(!m_IsEnabled); - - for (cChunkCoordsList::iterator itr = m_Chunks.begin(); itr != m_Chunks.end(); ++itr) - { - if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ)) - { - // Found, un-"stay" - m_Chunks.erase(itr); - return; - } - } // for itr - m_Chunks[] -} - - - - - -void cChunkStay::Enable(void) -{ - ASSERT(!m_IsEnabled); - - m_World->ChunksStay(*this, true); - m_IsEnabled = true; -} - - - - - -void cChunkStay::Load(void) -{ - for (cChunkCoordsList::iterator itr = m_Chunks.begin(); itr != m_Chunks.end(); ++itr) - { - m_World->TouchChunk(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ); - } // for itr - m_Chunks[] -} - - - - - -void cChunkStay::Disable(void) -{ - ASSERT(m_IsEnabled); - - m_World->ChunksStay(*this, false); - m_IsEnabled = false; -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cChunkMap.h" +#include "cWorld.h" +#include "cRoot.h" +#include "cMakeDir.h" +#include "cPlayer.h" +#include "BlockID.h" +#include "cItem.h" +#include "cPickup.h" +#include "cChunk.h" +#include "Trees.h" // used in cChunkMap::ReplaceTreeBlocks() for tree block discrimination + +#ifndef _WIN32 + #include // abs +#endif + +#include "zlib.h" +#include + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cChunkMap: + +cChunkMap::cChunkMap(cWorld * a_World ) + : m_World( a_World ) +{ +} + + + + + +cChunkMap::~cChunkMap() +{ + cCSLock Lock(m_CSLayers); + for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) + { + delete *itr; + } // for itr - m_Layers[] +} + + + + + +void cChunkMap::RemoveLayer( cChunkLayer* a_Layer ) +{ + cCSLock Lock(m_CSLayers); + m_Layers.remove(a_Layer); +} + + + + + +cChunkMap::cChunkLayer * cChunkMap::GetLayer(int a_LayerX, int a_LayerZ) +{ + cCSLock Lock(m_CSLayers); + for (cChunkLayerList::const_iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) + { + if (((*itr)->GetX() == a_LayerX) && ((*itr)->GetZ() == a_LayerZ)) + { + return *itr; + } + } + + // Not found, create new: + cChunkLayer * Layer = new cChunkLayer(a_LayerX, a_LayerZ, this); + if (Layer == NULL) + { + LOGERROR("cChunkMap: Cannot create new layer, server out of memory?"); + return NULL; + } + m_Layers.push_back(Layer); + return Layer; +} + + + + + +cChunkMap::cChunkLayer * cChunkMap::GetLayerForChunk( int a_ChunkX, int a_ChunkZ ) +{ + const int LayerX = (int)(floorf((float)a_ChunkX / (float)(LAYER_SIZE))); + const int LayerZ = (int)(floorf((float)a_ChunkZ / (float)(LAYER_SIZE))); + return GetLayer( LayerX, LayerZ ); +} + + + + + +cChunkPtr cChunkMap::GetChunk( int a_ChunkX, int a_ChunkY, int a_ChunkZ ) +{ + // No need to lock m_CSLayers, since it's already locked by the operation that called us + cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ ); + if (Layer == NULL) + { + // An error must have occurred, since layers are automatically created if they don't exist + return NULL; + } + + cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ); + if (Chunk == NULL) + { + return NULL; + } + if (!(Chunk->IsValid())) + { + m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ, true); + } + return Chunk; +} + + + + + +cChunkPtr cChunkMap::GetChunkNoGen( int a_ChunkX, int a_ChunkY, int a_ChunkZ ) +{ + // No need to lock m_CSLayers, since it's already locked by the operation that called us + cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ ); + if (Layer == NULL) + { + // An error must have occurred, since layers are automatically created if they don't exist + return NULL; + } + + cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ); + if (Chunk == NULL) + { + return NULL; + } + if (!(Chunk->IsValid())) + { + m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ, false); + } + + return Chunk; +} + + + + + +cChunkPtr cChunkMap::GetChunkNoLoad( int a_ChunkX, int a_ChunkY, int a_ChunkZ ) +{ + // No need to lock m_CSLayers, since it's already locked by the operation that called us + cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ ); + if (Layer == NULL) + { + // An error must have occurred, since layers are automatically created if they don't exist + return NULL; + } + + return Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +bool cChunkMap::LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) +{ + // We already have m_CSLayers locked since this can be called only from within the tick thread + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk == NULL) + { + return false; + } + + int Index = cChunkDef::MakeIndexNoCheck(a_BlockX, a_BlockY, a_BlockZ); + a_BlockType = Chunk->GetBlock(Index); + a_BlockMeta = Chunk->GetMeta(Index); + return true; +} + + + + + +bool cChunkMap::LockedSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + // We already have m_CSLayers locked since this can be called only from within the tick thread + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk == NULL) + { + return false; + } + + Chunk->SetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); + return true; +} + + + + + +bool cChunkMap::LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + // We already have m_CSLayers locked since this can be called only from within the tick thread + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk == NULL) + { + return false; + } + + Chunk->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); + return true; +} + + + + + +void cChunkMap::BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude) +{ + // Broadcasts a_Packet to all clients in the chunk where block [x, y, z] is, except to client a_Exclude + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if (Chunk == NULL) + { + return; + } + // It's perfectly legal to broadcast packets even to invalid chunks! + Chunk->Broadcast(a_Packet, a_Exclude); +} + + + + + +void cChunkMap::BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, const cPacket * a_Packet, cClientHandle * a_Exclude) +{ + // Broadcasts a_Packet to all clients in the chunk where block [x, y, z] is, except to client a_Exclude + + cCSLock Lock(m_CSLayers); + int ChunkX, ChunkZ; + cChunkDef::BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk == NULL) + { + return; + } + // It's perfectly legal to broadcast packets even to invalid chunks! + Chunk->Broadcast(a_Packet, a_Exclude); +} + + + + + +void cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z) +{ + // a_Player rclked block entity at the coords specified, handle it + cCSLock Lock(m_CSLayers); + int ChunkX, ChunkZ; + cChunkDef::BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + return; + } + Chunk->UseBlockEntity(a_Player, a_X, a_Y, a_Z); +} + + + + + +void cChunkMap::MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + return; + } + Chunk->MarkDirty(); +} + + + + + +void cChunkMap::MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + return; + } + Chunk->MarkSaving(); +} + + + + + +void cChunkMap::MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + return; + } + Chunk->MarkSaved(); +} + + + + + +void cChunkMap::SetChunkData( + int a_ChunkX, int a_ChunkY, int a_ChunkZ, + const BLOCKTYPE * a_BlockTypes, + const NIBBLETYPE * a_BlockMeta, + const NIBBLETYPE * a_BlockLight, + const NIBBLETYPE * a_BlockSkyLight, + const cChunkDef::HeightMap * a_HeightMap, + const cChunkDef::BiomeMap & a_BiomeMap, + cEntityList & a_Entities, + cBlockEntityList & a_BlockEntities, + bool a_MarkDirty +) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkY, a_ChunkZ); + if (Chunk == NULL) + { + return; + } + Chunk->SetAllData(a_BlockTypes, a_BlockMeta, a_BlockLight, a_BlockSkyLight, a_HeightMap, a_BiomeMap, a_Entities, a_BlockEntities); + Chunk->SetValid(); + + if (a_MarkDirty) + { + Chunk->MarkDirty(); + } +} + + + + + +void cChunkMap::ChunkLighted( + int a_ChunkX, int a_ChunkZ, + const cChunkDef::BlockNibbles & a_BlockLight, + const cChunkDef::BlockNibbles & a_SkyLight +) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + if (Chunk == NULL) + { + return; + } + Chunk->SetLight(a_BlockLight, a_SkyLight); + Chunk->MarkDirty(); +} + + + + + +bool cChunkMap::GetChunkData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + return false; + } + Chunk->GetAllData(a_Callback); + return true; +} + + + + + +bool cChunkMap::GetChunkBlockTypes(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockTypes) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + return false; + } + Chunk->GetBlockTypes(a_BlockTypes); + return true; +} + + + + + +bool cChunkMap::GetChunkBlockData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + return false; + } + Chunk->GetBlockData(a_BlockData); + return true; +} + + + + + +bool cChunkMap::IsChunkValid(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkY, a_ChunkZ); + return (Chunk != NULL) && Chunk->IsValid(); +} + + + + + +bool cChunkMap::HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + return (Chunk != NULL) && Chunk->HasAnyClients(); +} + + + + + +int cChunkMap::GetHeight(int a_BlockX, int a_BlockZ) +{ + cCSLock Lock(m_CSLayers); + int ChunkX, ChunkZ, BlockY = 0; + cChunkDef::AbsoluteToRelative(a_BlockX, BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk == NULL) + { + return 0; + } + + // Wait for the chunk to become valid: + while (!Chunk->IsValid()) + { + GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); // Re-queue (in case it managed to get unloaded before we caught it + cCSUnlock Unlock(Lock); + m_evtChunkValid.Wait(); + } + + return Chunk->GetHeight(a_BlockX, a_BlockZ); +} + + + + + +void cChunkMap::FastSetBlocks(sSetBlockList & a_BlockList) +{ + sSetBlockList Failed; + + // Process all items from a_BlockList, either successfully or by placing into Failed + while (!a_BlockList.empty()) + { + int ChunkX = a_BlockList.front().ChunkX; + int ChunkZ = a_BlockList.front().ChunkZ; + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if ((Chunk != NULL) && Chunk->IsValid()) + { + for (sSetBlockList::iterator itr = a_BlockList.begin(); itr != a_BlockList.end();) + { + if ((itr->ChunkX == ChunkX) && (itr->ChunkZ == ChunkZ)) + { + Chunk->FastSetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta); + itr = a_BlockList.erase(itr); + } + else + { + ++itr; + } + } // for itr - a_BlockList[] + } + else + { + // The chunk is not valid, move all blocks within this chunk to Failed + for (sSetBlockList::iterator itr = a_BlockList.begin(); itr != a_BlockList.end();) + { + if ((itr->ChunkX == ChunkX) && (itr->ChunkZ == ChunkZ)) + { + Failed.push_back(*itr); + itr = a_BlockList.erase(itr); + } + else + { + ++itr; + } + } // for itr - a_BlockList[] + } + } + + // Return the failed: + std::swap(Failed, a_BlockList); +} + + + + + +void cChunkMap::CollectPickupsByPlayer(cPlayer * a_Player) +{ + int BlockX = (int)(a_Player->GetPosX()); // Truncating doesn't matter much; we're scanning entire chunks anyway + int BlockY = (int)(a_Player->GetPosY()); + int BlockZ = (int)(a_Player->GetPosZ()); + int ChunkX, ChunkZ, ChunkY = ZERO_CHUNK_Y; + cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); + int OtherChunkX = ChunkX + ((BlockX > 8) ? 1 : -1); + int OtherChunkZ = ChunkZ + ((BlockZ > 8) ? 1 : -1); + + // We suppose that each player keeps their chunks in memory, therefore it makes little sense to try to re-load or even generate them. + // The only time the chunks are not valid is when the player is downloading the initial world and they should not call this at that moment + + cCSLock Lock(m_CSLayers); + GetChunkNoLoad(ChunkX, ChunkY, ChunkZ)->CollectPickupsByPlayer(a_Player); + + // Check the neighboring chunks as well: + GetChunkNoLoad(OtherChunkX, ChunkY, ChunkZ )->CollectPickupsByPlayer(a_Player); + GetChunkNoLoad(OtherChunkX, ChunkY, OtherChunkZ)->CollectPickupsByPlayer(a_Player); + GetChunkNoLoad(ChunkX, ChunkY, ChunkZ )->CollectPickupsByPlayer(a_Player); + GetChunkNoLoad(ChunkX, ChunkY, OtherChunkZ)->CollectPickupsByPlayer(a_Player); +} + + + + + +BLOCKTYPE cChunkMap::GetBlock(int a_X, int a_Y, int a_Z) +{ + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if ((Chunk != NULL) && Chunk->IsValid()) + { + return Chunk->GetBlock(a_X, a_Y, a_Z); + } + return 0; +} + + + + + +BLOCKTYPE cChunkMap::GetBlockMeta(int a_X, int a_Y, int a_Z) +{ + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); + if ((Chunk != NULL) && Chunk->IsValid() ) + { + return Chunk->GetMeta(a_X, a_Y, a_Z); + } + return 0; +} + + + + + +BLOCKTYPE cChunkMap::GetBlockSkyLight(int a_X, int a_Y, int a_Z) +{ + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); + if ((Chunk != NULL) && Chunk->IsValid() ) + { + return Chunk->GetSkyLight( a_X, a_Y, a_Z ); + } + return 0; +} + + + + + +void cChunkMap::SetBlockMeta(int a_X, int a_Y, int a_Z, char a_BlockMeta) +{ + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); + if ((Chunk != NULL) && Chunk->IsValid() ) + { + Chunk->SetMeta(a_X, a_Y, a_Z, a_BlockMeta); + Chunk->MarkDirty(); + Chunk->SendBlockTo( a_X, a_Y, a_Z, NULL ); + } +} + + + + + +void cChunkMap::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta) +{ + int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; + cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); + if ((Chunk != NULL) && Chunk->IsValid()) + { + Chunk->SetBlock(X, Y, Z, a_BlockType, a_BlockMeta ); + } +} + + + + + +void cChunkMap::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) +{ + int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; + cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); + if ((Chunk != NULL) && Chunk->IsValid()) + { + Chunk->GetBlockTypeMeta(X, Y, Z, a_BlockType, a_BlockMeta); + } +} + + + + + +void cChunkMap::ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType) +{ + cCSLock Lock(m_CSLayers); + for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) + { + cChunkPtr Chunk = GetChunk(itr->ChunkX, ZERO_CHUNK_Y, itr->ChunkZ ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + continue; + } + if (Chunk->GetBlock(itr->x, itr->y, itr->z) == a_FilterBlockType) + { + Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta); + } + } +} + + + + + +void cChunkMap::ReplaceTreeBlocks(const sSetBlockVector & a_Blocks) +{ + cCSLock Lock(m_CSLayers); + for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) + { + cChunkPtr Chunk = GetChunk(itr->ChunkX, ZERO_CHUNK_Y, itr->ChunkZ ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + continue; + } + switch (Chunk->GetBlock(itr->x, itr->y, itr->z)) + { + CASE_TREE_OVERWRITTEN_BLOCKS: + { + Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta); + break; + } + } + } // for itr - a_Blocks[] +} + + + + + +EMCSBiome cChunkMap::GetBiomeAt (int a_BlockX, int a_BlockZ) +{ + int ChunkX, ChunkZ, X = a_BlockX, Y = 0, Z = a_BlockZ; + cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); + if ((Chunk != NULL) && Chunk->IsValid()) + { + return Chunk->GetBiomeAt(X, Z); + } + else + { + return m_World->GetGenerator().GetBiomeAt(a_BlockX, a_BlockZ); + } +} + + + + + +bool cChunkMap::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure) +{ + bool res = true; + cCSLock Lock(m_CSLayers); + for (sSetBlockVector::iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) + { + cChunkPtr Chunk = GetChunk(itr->ChunkX, ZERO_CHUNK_Y, itr->ChunkZ ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + if (!a_ContinueOnFailure) + { + return false; + } + res = false; + continue; + } + int idx = cChunkDef::MakeIndexNoCheck(itr->x, itr->y, itr->z); + itr->BlockType = Chunk->GetBlock(idx); + itr->BlockMeta = Chunk->GetMeta(idx); + } + return res; +} + + + + + +bool cChunkMap::DigBlock(int a_X, int a_Y, int a_Z) +{ + int PosX = a_X, PosY = a_Y, PosZ = a_Z, ChunkX, ChunkZ; + + cChunkDef::AbsoluteToRelative( PosX, PosY, PosZ, ChunkX, ChunkZ ); + + { + cCSLock Lock(m_CSLayers); + cChunkPtr DestChunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); + if ((DestChunk == NULL) || !DestChunk->IsValid()) + { + return false; + } + + DestChunk->SetBlock(PosX, PosY, PosZ, E_BLOCK_AIR, 0 ); + } + + m_World->GetSimulatorManager()->WakeUp(a_X, a_Y, a_Z); + + return true; +} + + + + + +void cChunkMap::SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player) +{ + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(a_X, a_Y, a_Z, ChunkX, ChunkZ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk->IsValid()) + { + Chunk->SendBlockTo(a_X, a_Y, a_Z, a_Player->GetClientHandle()); + } +} + + + + + +void cChunkMap::CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk1 = GetChunkNoGen(a_ChunkX1, a_ChunkY1, a_ChunkZ1); + if (Chunk1 == NULL) + { + return; + } + cChunkPtr Chunk2 = GetChunkNoGen(a_ChunkX2, a_ChunkY2, a_ChunkZ2); + if (Chunk2 == NULL) + { + return; + } + + cClientHandleList Clients1(Chunk1->GetAllClients()); + cClientHandleList Clients2(Chunk2->GetAllClients()); + + // Find "removed" clients: + for (cClientHandleList::iterator itr1 = Clients1.begin(); itr1 != Clients1.end(); ++itr1) + { + bool Found = false; + for (cClientHandleList::iterator itr2 = Clients2.begin(); itr2 != Clients2.end(); ++itr2) + { + if (*itr1 == *itr2) + { + Found = true; + break; + } + } // for itr2 - Clients2[] + if (!Found) + { + a_Callback.Removed(*itr1); + } + } // for itr1 - Clients1[] + + // Find "added" clients: + for (cClientHandleList::iterator itr2 = Clients2.begin(); itr2 != Clients2.end(); ++itr2) + { + bool Found = false; + for (cClientHandleList::iterator itr1 = Clients1.begin(); itr1 != Clients1.end(); ++itr1) + { + if (*itr1 == *itr2) + { + Found = true; + break; + } + } // for itr1 - Clients1[] + if (!Found) + { + a_Callback.Added(*itr2); + } + } // for itr2 - Clients2[] +} + + + + + +bool cChunkMap::AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ); + if (Chunk == NULL) + { + return false; + } + return Chunk->AddClient(a_Client); +} + + + + + +void cChunkMap::RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if (Chunk == NULL) + { + return; + } + Chunk->RemoveClient(a_Client); +} + + + + + +void cChunkMap::RemoveClientFromChunks(cClientHandle * a_Client) +{ + cCSLock Lock(m_CSLayers); + + for (cChunkLayerList::const_iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) + { + (*itr)->RemoveClient(a_Client); + } // for itr - m_Layers[] +} + + + + + +void cChunkMap::MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr OldChunk = GetChunkNoGen(a_Entity->GetChunkX(), a_Entity->GetChunkY(), a_Entity->GetChunkZ()); + if (OldChunk != NULL) + { + OldChunk->RemoveEntity(a_Entity); + } + cChunkPtr NewChunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if (NewChunk != NULL) + { + NewChunk->AddEntity(a_Entity); + } +} + + + + + +void cChunkMap::RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if ((Chunk == NULL) && !Chunk->IsValid()) + { + return; + } + Chunk->RemoveEntity(a_Entity); +} + + + + + +void cChunkMap::TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +/// Loads the chunk synchronously, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before) +bool cChunkMap::LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + { + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if (Chunk == NULL) + { + // Internal error + return false; + } + if (Chunk->IsValid()) + { + // Already loaded + return true; + } + if (Chunk->HasLoadFailed()) + { + // Already tried loading and it failed + return false; + } + } + return m_World->GetStorage().LoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +/// Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid() +void cChunkMap::LoadChunks(const cChunkCoordsList & a_Chunks) +{ + for (cChunkCoordsList::const_iterator itr = a_Chunks.begin(); itr != a_Chunks.end(); ++itr) + { + LoadChunk(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ); + } // for itr - a_Chunks[] +} + + + + + +void cChunkMap::ChunkLoadFailed(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkY, a_ChunkZ); + if (Chunk == NULL) + { + return; + } + Chunk->MarkLoadFailed(); +} + + + + + +void cChunkMap::UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) +{ + cCSLock Lock(m_CSLayers); + int ChunkX, ChunkZ; + cChunkDef::BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + return; + } + Chunk->UpdateSign(a_X, a_Y, a_Z, a_Line1, a_Line2, a_Line3, a_Line4); +} + + + + + +void cChunkMap::ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay) +{ + cCSLock Lock(m_CSLayers); + for (cChunkCoordsList::const_iterator itr = a_Chunks.begin(); itr != a_Chunks.end(); ++itr) + { + cChunkPtr Chunk = GetChunkNoLoad(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ); + if (Chunk == NULL) + { + continue; + } + Chunk->Stay(a_Stay); + } +} + + + + + +void cChunkMap::MarkChunkRegenerating(int a_ChunkX, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + if (Chunk == NULL) + { + // Not present + return; + } + Chunk->MarkRegenerating(); +} + + + + + +bool cChunkMap::IsChunkLighted(int a_ChunkX, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + if (Chunk == NULL) + { + // Not present + return false; + } + return Chunk->IsLightValid(); +} + + + + + +void cChunkMap::GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty) +{ + a_NumChunksValid = 0; + a_NumChunksDirty = 0; + cCSLock Lock(m_CSLayers); + for (cChunkLayerList::const_iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) + { + int NumValid = 0, NumDirty = 0; + (*itr)->GetChunkStats(NumValid, NumDirty); + a_NumChunksValid += NumValid; + a_NumChunksDirty += NumDirty; + } // for itr - m_Layers[] +} + + + + + +void cChunkMap::GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, MTRand & a_Rand) +{ + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk != NULL) + { + Chunk->GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_Rand); + } +} + + + + + +void cChunkMap::GrowSugarcane(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow) +{ + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk != NULL) + { + Chunk->GrowSugarcane(a_BlockX, a_BlockY, a_BlockZ, a_NumBlocksToGrow); + } +} + + + + + +void cChunkMap::GrowCactus(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow) +{ + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk != NULL) + { + Chunk->GrowCactus(a_BlockX, a_BlockY, a_BlockZ, a_NumBlocksToGrow); + } +} + + + + + +void cChunkMap::SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk != NULL) + { + Chunk->SetNextBlockTick(a_BlockX, a_BlockY, a_BlockZ); + } +} + + + + + +void cChunkMap::Tick( float a_Dt, MTRand & a_TickRandom ) +{ + cCSLock Lock(m_CSLayers); + for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) + { + (*itr)->Tick(a_Dt, a_TickRandom); + } // for itr - m_Layers +} + + + + + +void cChunkMap::UnloadUnusedChunks() +{ + cCSLock Lock(m_CSLayers); + for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) + { + (*itr)->UnloadUnusedChunks(); + } // for itr - m_Layers +} + + + + + +void cChunkMap::SaveAllChunks(void) +{ + cCSLock Lock(m_CSLayers); + for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) + { + (*itr)->Save(); + } // for itr - m_Layers[] +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cChunkMap::cChunkLayer: + +cChunkMap::cChunkLayer::cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent) + : m_LayerX( a_LayerX ) + , m_LayerZ( a_LayerZ ) + , m_Parent( a_Parent ) + , m_NumChunksLoaded( 0 ) +{ + memset(m_Chunks, 0, sizeof(m_Chunks)); +} + + + + + +cChunkMap::cChunkLayer::~cChunkLayer() +{ + for (int i = 0; i < ARRAYCOUNT(m_Chunks); ++i) + { + delete m_Chunks[i]; + } // for i - m_Chunks[] +} + + + + + +cChunkPtr cChunkMap::cChunkLayer::GetChunk( int a_ChunkX, int a_ChunkY, int a_ChunkZ ) +{ + // Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check + + const int LocalX = a_ChunkX - m_LayerX * LAYER_SIZE; + const int LocalZ = a_ChunkZ - m_LayerZ * LAYER_SIZE; + + if (!((LocalX < LAYER_SIZE) && (LocalZ < LAYER_SIZE) && (LocalX > -1) && (LocalZ > -1))) + { + ASSERT(!"Asking a cChunkLayer for a chunk that doesn't belong to it!"); + return NULL; + } + + int Index = LocalX + LocalZ * LAYER_SIZE; + if (m_Chunks[Index] == NULL) + { + m_Chunks[Index] = new cChunk(a_ChunkX, 0, a_ChunkZ, m_Parent, m_Parent->GetWorld()); + } + return m_Chunks[Index]; +} + + + + + +void cChunkMap::cChunkLayer::Tick(float a_Dt, MTRand & a_TickRand) +{ + for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++) + { + // Only tick chunks that are valid and have clients: + if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid() && m_Chunks[i]->HasAnyClients()) + { + m_Chunks[i]->Tick(a_Dt, a_TickRand); + } + } // for i - m_Chunks[] +} + + + + + +void cChunkMap::cChunkLayer::RemoveClient(cClientHandle * a_Client) +{ + for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++) + { + if (m_Chunks[i] != NULL) + { + m_Chunks[i]->RemoveClient(a_Client); + } + } // for i - m_Chunks[] +} + + + + + +int cChunkMap::cChunkLayer::GetNumChunksLoaded(void) const +{ + int NumChunks = 0; + for ( int i = 0; i < ARRAYCOUNT(m_Chunks); ++i ) + { + if (m_Chunks[i] != NULL) + { + NumChunks++; + } + } // for i - m_Chunks[] + return NumChunks; +} + + + + + +void cChunkMap::cChunkLayer::GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty) const +{ + int NumValid = 0; + int NumDirty = 0; + for ( int i = 0; i < ARRAYCOUNT(m_Chunks); ++i ) + { + if (m_Chunks[i] == NULL) + { + continue; + } + NumValid++; + if (m_Chunks[i]->IsDirty()) + { + NumDirty++; + } + } // for i - m_Chunks[] + a_NumChunksValid = NumValid; + a_NumChunksDirty = NumDirty; +} + + + + + +void cChunkMap::cChunkLayer::Save(void) +{ + cWorld * World = m_Parent->GetWorld(); + for (int i = 0; i < ARRAYCOUNT(m_Chunks); ++i) + { + if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid() && m_Chunks[i]->IsDirty()) + { + World->GetStorage().QueueSaveChunk(m_Chunks[i]->GetPosX(), m_Chunks[i]->GetPosY(), m_Chunks[i]->GetPosZ()); + } + } // for i - m_Chunks[] +} + + + + + +void cChunkMap::cChunkLayer::UnloadUnusedChunks(void) +{ + for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++) + { + if ((m_Chunks[i] != NULL) && (m_Chunks[i]->CanUnload())) + { + // The cChunk destructor calls our GetChunk() while removing its entities + // so we still need to be able to return the chunk. Therefore we first delete, then NULLify + // Doing otherwise results in bug http://forum.mc-server.org/showthread.php?tid=355 + delete m_Chunks[i]; + m_Chunks[i] = NULL; + } + } // for i - m_Chunks[] +} + + + + + +int cChunkMap::GetNumChunks(void) +{ + cCSLock Lock(m_CSLayers); + int NumChunks = 0; + for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) + { + NumChunks += (*itr)->GetNumChunksLoaded(); + } + return NumChunks; +} + + + + + +void cChunkMap::ChunkValidated(void) +{ + m_evtChunkValid.Set(); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cChunkStay: + +cChunkStay::cChunkStay(cWorld * a_World) : + m_World(a_World), + m_IsEnabled(false) +{ +} + + + + + +cChunkStay::~cChunkStay() +{ + Clear(); +} + + + + + +void cChunkStay::Clear(void) +{ + if (m_IsEnabled) + { + Disable(); + } + m_Chunks.clear(); +} + + + + + +void cChunkStay::Add(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + ASSERT(!m_IsEnabled); + + for (cChunkCoordsList::const_iterator itr = m_Chunks.begin(); itr != m_Chunks.end(); ++itr) + { + if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ)) + { + // Already present + return; + } + } // for itr - Chunks[] + m_Chunks.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); +} + + + + + +void cChunkStay::Remove(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + ASSERT(!m_IsEnabled); + + for (cChunkCoordsList::iterator itr = m_Chunks.begin(); itr != m_Chunks.end(); ++itr) + { + if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ)) + { + // Found, un-"stay" + m_Chunks.erase(itr); + return; + } + } // for itr - m_Chunks[] +} + + + + + +void cChunkStay::Enable(void) +{ + ASSERT(!m_IsEnabled); + + m_World->ChunksStay(*this, true); + m_IsEnabled = true; +} + + + + + +void cChunkStay::Load(void) +{ + for (cChunkCoordsList::iterator itr = m_Chunks.begin(); itr != m_Chunks.end(); ++itr) + { + m_World->TouchChunk(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ); + } // for itr - m_Chunks[] +} + + + + + +void cChunkStay::Disable(void) +{ + ASSERT(m_IsEnabled); + + m_World->ChunksStay(*this, false); + m_IsEnabled = false; +} + + + + diff --git a/source/cChunkMap.h b/source/cChunkMap.h index 7ddb094c5..1d90c6aaa 100644 --- a/source/cChunkMap.h +++ b/source/cChunkMap.h @@ -1,281 +1,281 @@ - -// cChunkMap.h - -// Interfaces to the cChunkMap class representing the chunk storage for a single world - -#pragma once - -#include "ChunkDef.h" - - - - - -class cWorld; -class cItem; -class MTRand; -class cChunkStay; -class cChunk; -class cPacket; -class cPlayer; - -typedef std::list cClientHandleList; -typedef cChunk * cChunkPtr; - - - - - -class cChunkMap -{ -public: - - static const int LAYER_SIZE = 32; - - cChunkMap(cWorld* a_World ); - ~cChunkMap(); - - // Direct action methods: - /// Broadcast a_Packet to all clients in the chunk specified - void BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude = NULL); - - /// Broadcasts a_Packet to all clients in the chunk where block [x, y, z] is, except to client a_Exclude - void BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, const cPacket * a_Packet, cClientHandle * a_Exclude = NULL); - - /// a_Player rclked block entity at the coords specified, handle it - void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z); - - void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ); - void MarkChunkSaving (int a_ChunkX, int a_ChunkY, int a_ChunkZ); - void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ); - - /** Sets the chunk data as either loaded from the storage or generated. - a_BlockLight and a_BlockSkyLight are optional, if not present, chunk will be marked as unlighted. - a_BiomeMap is optional, if not present, biomes will be calculated by the generator - a_HeightMap is optional, if not present, will be calculated. - If a_MarkDirty is set, the chunk is set as dirty (used after generating) - */ - void SetChunkData( - int a_ChunkX, int a_ChunkY, int a_ChunkZ, - const BLOCKTYPE * a_BlockTypes, - const NIBBLETYPE * a_BlockMeta, - const NIBBLETYPE * a_BlockLight, - const NIBBLETYPE * a_BlockSkyLight, - const cChunkDef::HeightMap * a_HeightMap, - const cChunkDef::BiomeMap & a_BiomeMap, - cEntityList & a_Entities, - cBlockEntityList & a_BlockEntities, - bool a_MarkDirty - ); - - void ChunkLighted( - int a_ChunkX, int a_ChunkZ, - const cChunkDef::BlockNibbles & a_BlockLight, - const cChunkDef::BlockNibbles & a_SkyLight - ); - - bool GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback); - - /// Gets the chunk's blocks, only the block types - bool GetChunkBlockTypes (int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_Blocks); - - /// Gets the chunk's block data, the entire 4 arrays (Types, Meta, Light, SkyLight) - bool GetChunkBlockData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData); - - bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ); - bool HasChunkAnyClients (int a_ChunkX, int a_ChunkY, int a_ChunkZ); - int GetHeight (int a_BlockX, int a_BlockZ); - void FastSetBlocks (sSetBlockList & a_BlockList); - void CollectPickupsByPlayer(cPlayer * a_Player); - BLOCKTYPE GetBlock (int a_X, int a_Y, int a_Z); - BLOCKTYPE GetBlockMeta (int a_X, int a_Y, int a_Z); - BLOCKTYPE GetBlockSkyLight (int a_X, int a_Y, int a_Z); - void SetBlockMeta (int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockMeta); - void SetBlock (int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta); - void GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); - - /// Replaces world blocks with a_Blocks, if they are of type a_FilterBlockType - void ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType); - - /// Special function used for growing trees, replaces only blocks that tree may overwrite - void ReplaceTreeBlocks(const sSetBlockVector & a_Blocks); - - EMCSBiome GetBiomeAt (int a_BlockX, int a_BlockZ); - - /// Retrieves block types of the specified blocks. If a chunk is not loaded, doesn't modify the block. Returns true if all blocks were read. - bool GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure); - - bool DigBlock (int a_X, int a_Y, int a_Z); - void SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player); - - /// Compares clients of two chunks, calls the callback accordingly - void CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback); - - /// Adds client to a chunk, if not already present; returns true if added, false if present - bool AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); - - /// Removes the client from the chunk - void RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); - - /// Removes the client from all chunks it is present in - void RemoveClientFromChunks(cClientHandle * a_Client); - - /// Moves the entity from its current chunk to the new chunk specified - void MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ); - - /// Removes the entity from the chunk specified - void RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ); - - /// Touches the chunk, causing it to be loaded or generated - void TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); - - /// Loads the chunk, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before) - bool LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); - - /// Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid() - void LoadChunks(const cChunkCoordsList & a_Chunks); - - /// Marks the chunk as failed-to-load: - void ChunkLoadFailed(int a_ChunkX, int a_ChunkY, int a_ChunkZ); - - void UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); - - /// Marks (a_Stay == true) or unmarks (a_Stay == false) chunks as non-unloadable; to be used only by cChunkStay! - void ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay = true); - - /// Marks the chunk as being regenerated - all its clients want that chunk again (used by cWorld::RegenerateChunk() ) - void MarkChunkRegenerating(int a_ChunkX, int a_ChunkZ); - - bool IsChunkLighted(int a_ChunkX, int a_ChunkZ); - - /// Returns the number of valid chunks and the number of dirty chunks - void GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty); - - /// Grows a melon or a pumpkin next to the block specified (assumed to be the stem) - void GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, MTRand & a_Rand); - - /// Grows a sugarcane present at the block specified by the amount of blocks specified, up to the max height of 3 - void GrowSugarcane(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow); - - /// Grows a cactus present at the block specified by the amount of blocks specified, up to the max height of 3 - void GrowCactus(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow); - - /// Sets the blockticking to start at the specified block. Only one blocktick per chunk may be set, second call overwrites the first call - void SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ); - - void Tick( float a_Dt, MTRand & a_TickRand ); - - void UnloadUnusedChunks(); - void SaveAllChunks(); - - cWorld * GetWorld() { return m_World; } - - int GetNumChunks(void); - - void ChunkValidated(void); // Called by chunks that have become valid - -private: - - friend class cChunk; // The chunks can manipulate neighbors while in their Tick() method, using LockedGetBlock() and LockedSetBlock() - - class cChunkLayer - { - public: - cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent); - ~cChunkLayer(); - - /// Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check - cChunkPtr GetChunk( int a_ChunkX, int a_ChunkY, int a_ChunkZ ); - - int GetX(void) const {return m_LayerX; } - int GetZ(void) const {return m_LayerZ; } - - int GetNumChunksLoaded(void) const ; - - void GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty) const; - - void Save(void); - void UnloadUnusedChunks(void); - - void Tick( float a_Dt, MTRand & a_TickRand ); - - void RemoveClient(cClientHandle * a_Client); - - protected: - - cChunkPtr m_Chunks[LAYER_SIZE * LAYER_SIZE]; - int m_LayerX; - int m_LayerZ; - cChunkMap * m_Parent; - int m_NumChunksLoaded; - }; - - typedef std::list cChunkLayerList; - // TODO: Use smart pointers for cChunkLayerList as well, so that ticking and saving needn't lock the entire layerlist - // This however means that cChunkLayer needs to interlock its m_Chunks[] - - cChunkLayer * GetLayerForChunk( int a_ChunkX, int a_ChunkZ ); // Creates the layer if it doesn't already exist - cChunkLayer * GetLayer( int a_LayerX, int a_LayerZ ); // Creates the layer if it doesn't already exist - void RemoveLayer( cChunkLayer* a_Layer ); - - cCriticalSection m_CSLayers; - cChunkLayerList m_Layers; - cEvent m_evtChunkValid; // Set whenever any chunk becomes valid, via ChunkValidated() - - cWorld * m_World; - - cChunkPtr GetChunk (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading / generating if not valid - cChunkPtr GetChunkNoGen (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading if not valid; doesn't generate - cChunkPtr GetChunkNoLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Doesn't load, doesn't generate - - /// Gets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) - bool LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); - - /// Sets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) - bool LockedSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); - - /// Fast-sets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) - bool LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); -}; - - - - - -/** Makes chunks stay loaded until this object is cleared or destroyed -Works by setting internal flags in the cChunk that it should not be unloaded. -To optimize for speed, cChunkStay has an Enabled flag, it will "stay" the chunks only when enabled and it will refuse manipulations when enabled -The object itself is not made thread-safe, it's supposed to be used from a single thread only. -*/ -class cChunkStay -{ -public: - cChunkStay(cWorld * a_World); - ~cChunkStay(); - - void Clear(void); - - void Add(int a_ChunkX, int a_ChunkY, int a_ChunkZ); - void Remove(int a_ChunkX, int a_ChunkY, int a_ChunkZ); - - void Enable(void); - void Disable(void); - - /// Queues each chunk in m_Chunks[] for loading / generating - void Load(void); - - // Allow cChunkStay be passed to functions expecting a const cChunkCoordsList & - operator const cChunkCoordsList(void) const {return m_Chunks; } - -protected: - - cWorld * m_World; - - bool m_IsEnabled; - - cChunkCoordsList m_Chunks; -} ; - - - - + +// cChunkMap.h + +// Interfaces to the cChunkMap class representing the chunk storage for a single world + +#pragma once + +#include "ChunkDef.h" + + + + + +class cWorld; +class cItem; +class MTRand; +class cChunkStay; +class cChunk; +class cPacket; +class cPlayer; + +typedef std::list cClientHandleList; +typedef cChunk * cChunkPtr; + + + + + +class cChunkMap +{ +public: + + static const int LAYER_SIZE = 32; + + cChunkMap(cWorld* a_World ); + ~cChunkMap(); + + // Direct action methods: + /// Broadcast a_Packet to all clients in the chunk specified + void BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude = NULL); + + /// Broadcasts a_Packet to all clients in the chunk where block [x, y, z] is, except to client a_Exclude + void BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, const cPacket * a_Packet, cClientHandle * a_Exclude = NULL); + + /// a_Player rclked block entity at the coords specified, handle it + void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z); + + void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ); + void MarkChunkSaving (int a_ChunkX, int a_ChunkY, int a_ChunkZ); + void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /** Sets the chunk data as either loaded from the storage or generated. + a_BlockLight and a_BlockSkyLight are optional, if not present, chunk will be marked as unlighted. + a_BiomeMap is optional, if not present, biomes will be calculated by the generator + a_HeightMap is optional, if not present, will be calculated. + If a_MarkDirty is set, the chunk is set as dirty (used after generating) + */ + void SetChunkData( + int a_ChunkX, int a_ChunkY, int a_ChunkZ, + const BLOCKTYPE * a_BlockTypes, + const NIBBLETYPE * a_BlockMeta, + const NIBBLETYPE * a_BlockLight, + const NIBBLETYPE * a_BlockSkyLight, + const cChunkDef::HeightMap * a_HeightMap, + const cChunkDef::BiomeMap & a_BiomeMap, + cEntityList & a_Entities, + cBlockEntityList & a_BlockEntities, + bool a_MarkDirty + ); + + void ChunkLighted( + int a_ChunkX, int a_ChunkZ, + const cChunkDef::BlockNibbles & a_BlockLight, + const cChunkDef::BlockNibbles & a_SkyLight + ); + + bool GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback); + + /// Gets the chunk's blocks, only the block types + bool GetChunkBlockTypes (int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_Blocks); + + /// Gets the chunk's block data, the entire 4 arrays (Types, Meta, Light, SkyLight) + bool GetChunkBlockData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData); + + bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ); + bool HasChunkAnyClients (int a_ChunkX, int a_ChunkY, int a_ChunkZ); + int GetHeight (int a_BlockX, int a_BlockZ); + void FastSetBlocks (sSetBlockList & a_BlockList); + void CollectPickupsByPlayer(cPlayer * a_Player); + BLOCKTYPE GetBlock (int a_X, int a_Y, int a_Z); + BLOCKTYPE GetBlockMeta (int a_X, int a_Y, int a_Z); + BLOCKTYPE GetBlockSkyLight (int a_X, int a_Y, int a_Z); + void SetBlockMeta (int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockMeta); + void SetBlock (int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta); + void GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); + + /// Replaces world blocks with a_Blocks, if they are of type a_FilterBlockType + void ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType); + + /// Special function used for growing trees, replaces only blocks that tree may overwrite + void ReplaceTreeBlocks(const sSetBlockVector & a_Blocks); + + EMCSBiome GetBiomeAt (int a_BlockX, int a_BlockZ); + + /// Retrieves block types of the specified blocks. If a chunk is not loaded, doesn't modify the block. Returns true if all blocks were read. + bool GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure); + + bool DigBlock (int a_X, int a_Y, int a_Z); + void SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player); + + /// Compares clients of two chunks, calls the callback accordingly + void CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback); + + /// Adds client to a chunk, if not already present; returns true if added, false if present + bool AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); + + /// Removes the client from the chunk + void RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); + + /// Removes the client from all chunks it is present in + void RemoveClientFromChunks(cClientHandle * a_Client); + + /// Moves the entity from its current chunk to the new chunk specified + void MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Removes the entity from the chunk specified + void RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Touches the chunk, causing it to be loaded or generated + void TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Loads the chunk, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before) + bool LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid() + void LoadChunks(const cChunkCoordsList & a_Chunks); + + /// Marks the chunk as failed-to-load: + void ChunkLoadFailed(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + void UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); + + /// Marks (a_Stay == true) or unmarks (a_Stay == false) chunks as non-unloadable; to be used only by cChunkStay! + void ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay = true); + + /// Marks the chunk as being regenerated - all its clients want that chunk again (used by cWorld::RegenerateChunk() ) + void MarkChunkRegenerating(int a_ChunkX, int a_ChunkZ); + + bool IsChunkLighted(int a_ChunkX, int a_ChunkZ); + + /// Returns the number of valid chunks and the number of dirty chunks + void GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty); + + /// Grows a melon or a pumpkin next to the block specified (assumed to be the stem) + void GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, MTRand & a_Rand); + + /// Grows a sugarcane present at the block specified by the amount of blocks specified, up to the max height of 3 + void GrowSugarcane(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow); + + /// Grows a cactus present at the block specified by the amount of blocks specified, up to the max height of 3 + void GrowCactus(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow); + + /// Sets the blockticking to start at the specified block. Only one blocktick per chunk may be set, second call overwrites the first call + void SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ); + + void Tick( float a_Dt, MTRand & a_TickRand ); + + void UnloadUnusedChunks(); + void SaveAllChunks(); + + cWorld * GetWorld() { return m_World; } + + int GetNumChunks(void); + + void ChunkValidated(void); // Called by chunks that have become valid + +private: + + friend class cChunk; // The chunks can manipulate neighbors while in their Tick() method, using LockedGetBlock() and LockedSetBlock() + + class cChunkLayer + { + public: + cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent); + ~cChunkLayer(); + + /// Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check + cChunkPtr GetChunk( int a_ChunkX, int a_ChunkY, int a_ChunkZ ); + + int GetX(void) const {return m_LayerX; } + int GetZ(void) const {return m_LayerZ; } + + int GetNumChunksLoaded(void) const ; + + void GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty) const; + + void Save(void); + void UnloadUnusedChunks(void); + + void Tick( float a_Dt, MTRand & a_TickRand ); + + void RemoveClient(cClientHandle * a_Client); + + protected: + + cChunkPtr m_Chunks[LAYER_SIZE * LAYER_SIZE]; + int m_LayerX; + int m_LayerZ; + cChunkMap * m_Parent; + int m_NumChunksLoaded; + }; + + typedef std::list cChunkLayerList; + // TODO: Use smart pointers for cChunkLayerList as well, so that ticking and saving needn't lock the entire layerlist + // This however means that cChunkLayer needs to interlock its m_Chunks[] + + cChunkLayer * GetLayerForChunk( int a_ChunkX, int a_ChunkZ ); // Creates the layer if it doesn't already exist + cChunkLayer * GetLayer( int a_LayerX, int a_LayerZ ); // Creates the layer if it doesn't already exist + void RemoveLayer( cChunkLayer* a_Layer ); + + cCriticalSection m_CSLayers; + cChunkLayerList m_Layers; + cEvent m_evtChunkValid; // Set whenever any chunk becomes valid, via ChunkValidated() + + cWorld * m_World; + + cChunkPtr GetChunk (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading / generating if not valid + cChunkPtr GetChunkNoGen (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading if not valid; doesn't generate + cChunkPtr GetChunkNoLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Doesn't load, doesn't generate + + /// Gets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) + bool LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); + + /// Sets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) + bool LockedSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); + + /// Fast-sets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) + bool LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); +}; + + + + + +/** Makes chunks stay loaded until this object is cleared or destroyed +Works by setting internal flags in the cChunk that it should not be unloaded. +To optimize for speed, cChunkStay has an Enabled flag, it will "stay" the chunks only when enabled and it will refuse manipulations when enabled +The object itself is not made thread-safe, it's supposed to be used from a single thread only. +*/ +class cChunkStay +{ +public: + cChunkStay(cWorld * a_World); + ~cChunkStay(); + + void Clear(void); + + void Add(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + void Remove(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + void Enable(void); + void Disable(void); + + /// Queues each chunk in m_Chunks[] for loading / generating + void Load(void); + + // Allow cChunkStay be passed to functions expecting a const cChunkCoordsList & + operator const cChunkCoordsList(void) const {return m_Chunks; } + +protected: + + cWorld * m_World; + + bool m_IsEnabled; + + cChunkCoordsList m_Chunks; +} ; + + + + diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp index a005e8b25..58c344d4f 100644 --- a/source/cClientHandle.cpp +++ b/source/cClientHandle.cpp @@ -1,2084 +1,2084 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cClientHandle.h" -#include "cServer.h" -#include "cWorld.h" -#include "cPickup.h" -#include "cPluginManager.h" -#include "cPlayer.h" -#include "cInventory.h" -#include "cChestEntity.h" -#include "cSignEntity.h" -#include "cWindow.h" -#include "cCraftingWindow.h" -#include "cItem.h" -#include "cTorch.h" -#include "cStairs.h" -#include "cStep.h" -#include "cDoors.h" -#include "cLadder.h" -#include "cSign.h" -#include "cRedstone.h" -#include "cPiston.h" -#include "cBlockToPickup.h" -#include "cMonster.h" -#include "cChatColor.h" -#include "cSocket.h" -#include "cTimer.h" - -#include "cTracer.h" -#include "Vector3f.h" -#include "Vector3d.h" - -#include "cSleep.h" -#include "cRoot.h" - -#include "cBlockingTCPLink.h" -#include "cAuthenticator.h" -#include "MersenneTwister.h" - -#include "packets/cPacket_KeepAlive.h" -#include "packets/cPacket_Respawn.h" -#include "packets/cPacket_UpdateHealth.h" -#include "packets/cPacket_RelativeEntityMoveLook.h" -#include "packets/cPacket_Chat.h" -#include "packets/cPacket_Login.h" -#include "packets/cPacket_WindowClick.h" -#include "packets/cPacket_TimeUpdate.h" -#include "packets/cPacket_BlockDig.h" -#include "packets/cPacket_Handshake.h" -#include "packets/cPacket_ArmAnim.h" -#include "packets/cPacket_BlockPlace.h" -#include "packets/cPacket_Flying.h" -#include "packets/cPacket_Disconnect.h" -#include "packets/cPacket_PickupSpawn.h" -#include "packets/cPacket_ItemSwitch.h" -#include "packets/cPacket_EntityEquipment.h" -#include "packets/cPacket_CreativeInventoryAction.h" -#include "packets/cPacket_NewInvalidState.h" -#include "packets/cPacket_UseEntity.h" -#include "packets/cPacket_WindowClose.h" -#include "packets/cPacket_13.h" -#include "packets/cPacket_UpdateSign.h" -#include "packets/cPacket_Ping.h" -#include "packets/cPacket_NamedEntitySpawn.h" -#include "packets/cPacket_MapChunk.h" -#include "packets/cPacket_PreChunk.h" - -// DEBUG: -#include "packets/cPacket_BlockChange.h" -#include "packets/cPacket_MultiBlock.h" - - - - - -#define AddPistonDir(x, y, z, dir, amount) switch (dir) { case 0: (y)-=(amount); break; case 1: (y)+=(amount); break;\ - case 2: (z)-=(amount); break; case 3: (z)+=(amount); break;\ - case 4: (x)-=(amount); break; case 5: (x)+=(amount); break; } - - - - - -/// If the number of queued outgoing packets reaches this, the client will be kicked -#define MAX_OUTGOING_PACKETS 2000 - - - - - -#define RECI_RAND_MAX (1.f/RAND_MAX) -inline int fRadRand(MTRand & r1, int a_BlockCoord) -{ - return a_BlockCoord * 32 + (int)(16 * ((float)r1.rand() * RECI_RAND_MAX) * 16 - 8); -} - - - - - -int cClientHandle::s_ClientCount = 0; - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cClientHandle: - -cClientHandle::cClientHandle(const cSocket & a_Socket, int a_ViewDistance) - : m_ViewDistance(a_ViewDistance) - , m_ProtocolVersion(MCS_PROTOCOL_VERSION) - , m_Socket(a_Socket) - , m_bDestroyed(false) - , m_Player(NULL) - , m_bKicking(false) - , m_TimeLastPacket(cWorld::GetTime()) - , m_bKeepThreadGoing(true) - , m_Ping(1000) - , m_State(csConnected) - , m_LastStreamedChunkX(0x7fffffff) // bogus chunk coords to force streaming upon login - , m_LastStreamedChunkZ(0x7fffffff) - , m_UniqueID(0) -{ - s_ClientCount++; // Not protected by CS because clients are always constructed from the same thread - m_UniqueID = s_ClientCount; - - cTimer t1; - m_LastPingTime = t1.GetNowTime(); - - // All the packets that can be received from the client - for (int i = 0; i < ARRAYCOUNT(m_PacketMap); ++i) - { - m_PacketMap[i] = NULL; - } - m_PacketMap[E_KEEP_ALIVE] = new cPacket_KeepAlive; - m_PacketMap[E_HANDSHAKE] = new cPacket_Handshake; - m_PacketMap[E_LOGIN] = new cPacket_Login; - m_PacketMap[E_PLAYERPOS] = new cPacket_PlayerPosition; - m_PacketMap[E_PLAYERLOOK] = new cPacket_PlayerLook; - m_PacketMap[E_PLAYERMOVELOOK] = new cPacket_PlayerMoveLook; - m_PacketMap[E_PLAYER_ABILITIES] = new cPacket_PlayerAbilities; - m_PacketMap[E_CHAT] = new cPacket_Chat; - m_PacketMap[E_ANIMATION] = new cPacket_ArmAnim; - m_PacketMap[E_FLYING] = new cPacket_Flying; - m_PacketMap[E_BLOCK_DIG] = new cPacket_BlockDig; - m_PacketMap[E_BLOCK_PLACE] = new cPacket_BlockPlace; - m_PacketMap[E_DISCONNECT] = new cPacket_Disconnect; - m_PacketMap[E_ITEM_SWITCH] = new cPacket_ItemSwitch; - m_PacketMap[E_ENTITY_EQUIPMENT] = new cPacket_EntityEquipment; - m_PacketMap[E_CREATIVE_INVENTORY_ACTION] = new cPacket_CreativeInventoryAction; - m_PacketMap[E_NEW_INVALID_STATE] = new cPacket_NewInvalidState; - m_PacketMap[E_PICKUP_SPAWN] = new cPacket_PickupSpawn; - m_PacketMap[E_USE_ENTITY] = new cPacket_UseEntity; - m_PacketMap[E_WINDOW_CLOSE] = new cPacket_WindowClose; - m_PacketMap[E_WINDOW_CLICK] = new cPacket_WindowClick; - m_PacketMap[E_PACKET_13] = new cPacket_13; - m_PacketMap[E_UPDATE_SIGN] = new cPacket_UpdateSign; - m_PacketMap[E_RESPAWN] = new cPacket_Respawn; - m_PacketMap[E_PING] = new cPacket_Ping; - - LOG("New ClientHandle created at %p", this); -} - - - - - -cClientHandle::~cClientHandle() -{ - LOG("Deleting client \"%s\" at %p", GetUsername().c_str(), this); - - // Remove from cSocketThreads, we're not to be called anymore: - cRoot::Get()->GetServer()->ClientDestroying(this); - - { - cCSLock Lock(m_CSChunkLists); - m_LoadedChunks.clear(); - m_ChunksToSend.clear(); - } - - if (m_Player != NULL) - { - cWorld * World = m_Player->GetWorld(); - if (!m_Username.empty() && (World != NULL)) - { - // Send the Offline PlayerList packet: - AString NameColor = (m_Player ? m_Player->GetColor() : ""); - cPacket_PlayerListItem PlayerList(NameColor + GetUsername(), false, (short)9999); - World->Broadcast(PlayerList, this); - - // Send the Chat packet: - cPacket_Chat Left(m_Username + " left the game!"); - World->Broadcast(Left, this); - } - if (World != NULL) - { - World->RemovePlayer(m_Player); - } - } - - if (m_Socket.IsValid()) - { - cPacket_Disconnect Disconnect; - Disconnect.m_Reason = "Server shut down? Kthnxbai"; - m_Socket.Send(&Disconnect); - } - - if (m_Player != NULL) - { - m_Player->Destroy(); - m_Player = NULL; - } - for (int i = 0; i < ARRAYCOUNT(m_PacketMap); i++) - { - delete m_PacketMap[i]; - } - - // Queue all remaining outgoing packets to cSocketThreads: - { - cCSLock Lock(m_CSPackets); - for (PacketList::iterator itr = m_PendingNrmSendPackets.begin(); itr != m_PendingNrmSendPackets.end(); ++itr) - { - AString Data; - (*itr)->Serialize(Data); - cRoot::Get()->GetServer()->WriteToClient(&m_Socket, Data); - delete *itr; - } - m_PendingNrmSendPackets.clear(); - for (PacketList::iterator itr = m_PendingLowSendPackets.begin(); itr != m_PendingLowSendPackets.end(); ++itr) - { - AString Data; - (*itr)->Serialize(Data); - cRoot::Get()->GetServer()->WriteToClient(&m_Socket, Data); - delete *itr; - } - m_PendingLowSendPackets.clear(); - } - - // Queue the socket to close as soon as it sends all outgoing data: - cRoot::Get()->GetServer()->QueueClientClose(&m_Socket); - - // We need to remove the socket from SocketThreads because we own it and it gets destroyed after this destructor finishes - // TODO: The socket needs to stay alive, someone else has to own it - cRoot::Get()->GetServer()->RemoveClient(&m_Socket); - - LOG("ClientHandle at %p deleted", this); -} - - - - - -void cClientHandle::Destroy() -{ - // Setting m_bDestroyed was moved to the bottom of Destroy(), - // otherwise the destructor may be called within another thread before the client is removed from chunks - // http://forum.mc-server.org/showthread.php?tid=366 - - if ((m_Player != NULL) && (m_Player->GetWorld() != NULL)) - { - RemoveFromAllChunks(); - m_Player->GetWorld()->RemoveClientFromChunkSender(this); - } - - m_bDestroyed = true; -} - - - - - -void cClientHandle::Kick(const AString & a_Reason) -{ - if (m_State >= csAuthenticating) // Don't log pings - { - LOG("Kicking user \"%s\" for \"%s\"", m_Username.c_str(), a_Reason.c_str()); - } - Send(cPacket_Disconnect(a_Reason)); - m_bKicking = true; -} - - - - - -void cClientHandle::Authenticate(void) -{ - if (m_State != csAuthenticating) - { - return; - } - - ASSERT( m_Player == NULL ); - - // Spawn player (only serversided, so data is loaded) - m_Player = new cPlayer(this, GetUsername()); - - cWorld * World = cRoot::Get()->GetWorld(m_Player->GetLoadedWorldName()); - if (World == NULL) - { - World = cRoot::Get()->GetDefaultWorld(); - } - - m_Player->LoginSetGameMode (World->GetGameMode()); //set player's gamemode to server's gamemode at login. TODO: set to last player's gamemode at logout - - m_Player->SetIP (m_Socket.GetIPString()); - - cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_PLAYER_SPAWN, 1, m_Player); - - // Return a server login packet - cPacket_Login LoginResponse; - LoginResponse.m_ProtocolVersion = m_Player->GetUniqueID(); - //LoginResponse.m_Username = ""; - LoginResponse.m_ServerMode = m_Player->GetGameMode(); // set gamemode from player. - LoginResponse.m_Dimension = 0; - LoginResponse.m_MaxPlayers = (unsigned char)cRoot::Get()->GetDefaultWorld()->GetMaxPlayers(); - LoginResponse.m_Difficulty = 2; - Send(LoginResponse); - - // Send Weather if raining: - if ((World->GetWeather() == 1) || (World->GetWeather() == 2)) - { - cPacket_NewInvalidState RainPacket; - RainPacket.m_Reason = 1; //begin rain - Send(RainPacket); - } - - // Send time - Send(cPacket_TimeUpdate(World->GetWorldTime())); - - // Send inventory - m_Player->GetInventory().SendWholeInventory(this); - - // Send health - cPacket_UpdateHealth Health; - Health.m_Health = (short)m_Player->GetHealth(); - Health.m_Food = m_Player->GetFood(); - Health.m_Saturation = m_Player->GetFoodSaturation(); - Send(Health); - - m_Player->Initialize(World); - StreamChunks(); - m_State = csDownloadingWorld; -} - - - - - -void cClientHandle::StreamChunks(void) -{ - if (m_State < csAuthenticating) - { - return; - } - - ASSERT(m_Player != NULL); - - int ChunkPosX = FAST_FLOOR_DIV(m_Player->GetPosX(), cChunkDef::Width); - int ChunkPosZ = FAST_FLOOR_DIV(m_Player->GetPosZ(), cChunkDef::Width); - if ((ChunkPosX == m_LastStreamedChunkX) && (ChunkPosZ == m_LastStreamedChunkZ)) - { - // Already streamed for this position - return; - } - m_LastStreamedChunkX = ChunkPosX; - m_LastStreamedChunkZ = ChunkPosZ; - - LOGD("Streaming chunks centered on [%d, %d], view distance %d", ChunkPosX, ChunkPosZ, m_ViewDistance); - - cWorld * World = m_Player->GetWorld(); - ASSERT(World != NULL); - - // Remove all loaded chunks that are no longer in range; deferred to out-of-CS: - cChunkCoordsList RemoveChunks; - { - cCSLock Lock(m_CSChunkLists); - for (cChunkCoordsList::iterator itr = m_LoadedChunks.begin(); itr != m_LoadedChunks.end();) - { - int RelX = (*itr).m_ChunkX - ChunkPosX; - int RelZ = (*itr).m_ChunkZ - ChunkPosZ; - if ((RelX > m_ViewDistance) || (RelX < -m_ViewDistance) || (RelZ > m_ViewDistance) || (RelZ < -m_ViewDistance)) - { - RemoveChunks.push_back(*itr); - itr = m_LoadedChunks.erase(itr); - } - else - { - ++itr; - } - } // for itr - m_LoadedChunks[] - for (cChunkCoordsList::iterator itr = m_ChunksToSend.begin(); itr != m_ChunksToSend.end();) - { - int RelX = (*itr).m_ChunkX - ChunkPosX; - int RelZ = (*itr).m_ChunkZ - ChunkPosZ; - if ((RelX > m_ViewDistance) || (RelX < -m_ViewDistance) || (RelZ > m_ViewDistance) || (RelZ < -m_ViewDistance)) - { - itr = m_ChunksToSend.erase(itr); - } - else - { - ++itr; - } - } // for itr - m_ChunksToSend[] - } - for (cChunkCoordsList::iterator itr = RemoveChunks.begin(); itr != RemoveChunks.end(); ++itr) - { - World->RemoveChunkClient(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ, this); - Send(cPacket_PreChunk(itr->m_ChunkX, itr->m_ChunkZ, false)); - } // for itr - RemoveChunks[] - - // Add all chunks that are in range and not yet in m_LoadedChunks: - // Queue these smartly - from the center out to the edge - for (int d = 0; d <= m_ViewDistance; ++d) // cycle through (square) distance, from nearest to furthest - { - // For each distance add chunks in a hollow square centered around current position: - for (int i = -d; i <= d; ++i) - { - StreamChunk(ChunkPosX + d, ZERO_CHUNK_Y, ChunkPosZ + i); - StreamChunk(ChunkPosX - d, ZERO_CHUNK_Y, ChunkPosZ + i); - } // for i - for (int i = -d + 1; i < d; ++i) - { - StreamChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ + d); - StreamChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ - d); - } // for i - } // for d - - // Touch chunks GENERATEDISTANCE ahead to let them generate: - for (int d = m_ViewDistance + 1; d <= m_ViewDistance + GENERATEDISTANCE; ++d) // cycle through (square) distance, from nearest to furthest - { - // For each distance touch chunks in a hollow square centered around current position: - for (int i = -d; i <= d; ++i) - { - World->TouchChunk(ChunkPosX + d, ZERO_CHUNK_Y, ChunkPosZ + i); - World->TouchChunk(ChunkPosX - d, ZERO_CHUNK_Y, ChunkPosZ + i); - } // for i - for (int i = -d + 1; i < d; ++i) - { - World->TouchChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ + d); - World->TouchChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ - d); - } // for i - } // for d -} - - - - -void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - cWorld * World = m_Player->GetWorld(); - ASSERT(World != NULL); - - if (World->AddChunkClient(a_ChunkX, a_ChunkY, a_ChunkZ, this)) - { - { - cCSLock Lock(m_CSChunkLists); - m_LoadedChunks.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); - m_ChunksToSend.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); - } - World->SendChunkTo(a_ChunkX, a_ChunkY, a_ChunkZ, this); - } -} - - - - - -// Removes the client from all chunks. Used when switching worlds or destroying the player -void cClientHandle::RemoveFromAllChunks() -{ - cWorld * World = m_Player->GetWorld(); - if (World != NULL) - { - World->RemoveClientFromChunks(this); - } - - { - cCSLock Lock(m_CSChunkLists); - m_LoadedChunks.clear(); - m_ChunksToSend.clear(); - } -} - - - - - -void cClientHandle::HandlePacket(cPacket * a_Packet) -{ - m_TimeLastPacket = cWorld::GetTime(); - - // LOG("Recv packet 0x%02x from client \"%s\" (\"%s\")", a_Packet->m_PacketID, m_Socket.GetIPString().c_str(), m_Username.c_str()); - - if (m_bKicking) - { - return; - } - - switch (m_State) - { - case csConnected: - { - switch (a_Packet->m_PacketID) - { - case E_NEW_INVALID_STATE: // New/Invalid State packet received. I'm guessing the client only sends it when there's a problem with the bed? - { - LOGINFO("Got New Invalid State packet"); - break; - } - case E_PING: HandlePing (); break; - case E_HANDSHAKE: HandleHandshake(reinterpret_cast(a_Packet)); break; - case E_LOGIN: HandleLogin (reinterpret_cast (a_Packet)); break; - - // Ignored packets: - case E_PLAYERLOOK: - case E_CHAT: - case E_PLAYERMOVELOOK: - case E_PLAYERPOS: - case E_KEEP_ALIVE: break; - default: HandleUnexpectedPacket(a_Packet); break; - } // switch (PacketType) - break; - } // case csConnected - - case csAuthenticating: - { - // Waiting for external authentication, no packets are handled - switch (a_Packet->m_PacketID) - { - // Ignored packets: - case E_KEEP_ALIVE: - case E_CHAT: - case E_FLYING: - case E_PLAYERLOOK: - case E_PLAYERMOVELOOK: - case E_PLAYERPOS: break; - - default: HandleUnexpectedPacket(a_Packet); break; - } - break; - } - - case csDownloadingWorld: - { - // Waiting for chunks to stream to client, no packets are handled - switch (a_Packet->m_PacketID) - { - // Ignored packets: - case E_KEEP_ALIVE: - case E_CHAT: - case E_FLYING: - case E_PLAYERLOOK: - case E_PLAYERMOVELOOK: - case E_PLAYERPOS: break; - - default: HandleUnexpectedPacket(a_Packet); break; - } - break; - } - - case csConfirmingPos: - { - switch (a_Packet->m_PacketID) - { - // Ignored packets: - case E_KEEP_ALIVE: - case E_CHAT: - case E_FLYING: - case E_PLAYERLOOK: - case E_PLAYERPOS: break; - - case E_PLAYERMOVELOOK: HandleMoveLookConfirm(reinterpret_cast(a_Packet)); break; - - default: - { - HandleUnexpectedPacket(a_Packet); - break; - } - } // switch (PacketType) - break; - } // case csConfirmingPos - - case csPlaying: - { - switch (a_Packet->m_PacketID) - { - case E_CREATIVE_INVENTORY_ACTION: HandleCreativeInventory(reinterpret_cast(a_Packet)); break; - case E_PLAYERPOS: HandlePlayerPos (reinterpret_cast (a_Packet)); break; - case E_BLOCK_DIG: HandleBlockDig (reinterpret_cast (a_Packet)); break; - case E_BLOCK_PLACE: HandleBlockPlace (reinterpret_cast (a_Packet)); break; - case E_PICKUP_SPAWN: HandlePickupSpawn (reinterpret_cast (a_Packet)); break; - case E_CHAT: HandleChat (reinterpret_cast (a_Packet)); break; - case E_PLAYERLOOK: HandlePlayerLook (reinterpret_cast (a_Packet)); break; - case E_PLAYERMOVELOOK: HandlePlayerMoveLook (reinterpret_cast (a_Packet)); break; - case E_ANIMATION: HandleAnimation (reinterpret_cast (a_Packet)); break; - case E_ITEM_SWITCH: HandleItemSwitch (reinterpret_cast (a_Packet)); break; - case E_WINDOW_CLOSE: HandleWindowClose (reinterpret_cast (a_Packet)); break; - case E_WINDOW_CLICK: HandleWindowClick (reinterpret_cast (a_Packet)); break; - case E_UPDATE_SIGN: HandleUpdateSign (reinterpret_cast (a_Packet)); break; - case E_USE_ENTITY: HandleUseEntity (reinterpret_cast (a_Packet)); break; - case E_RESPAWN: HandleRespawn(); break; - case E_DISCONNECT: HandleDisconnect (reinterpret_cast (a_Packet)); break; - case E_KEEP_ALIVE: HandleKeepAlive (reinterpret_cast (a_Packet)); break; - } // switch (Packet type) - break; - } // case csPlaying - } // switch (m_State) -} - - - - - -void cClientHandle::HandlePing(void) -{ - // Somebody tries to retrieve information about the server - AString Reply; - Printf(Reply, "%s%s%i%s%i", - cRoot::Get()->GetDefaultWorld()->GetDescription().c_str(), - cChatColor::Delimiter.c_str(), - cRoot::Get()->GetDefaultWorld()->GetNumPlayers(), - cChatColor::Delimiter.c_str(), - cRoot::Get()->GetDefaultWorld()->GetMaxPlayers() - ); - Kick(Reply.c_str()); -} - - - - - -void cClientHandle::HandleHandshake(cPacket_Handshake * a_Packet) -{ - AStringVector UserData = StringSplit( a_Packet->m_Username, ";" ); // "FakeTruth;localhost:25565" - if( UserData.size() == 0 ) - { - Kick("Could not receive username"); - return; - } - m_Username = UserData[0]; - - LOG("HANDSHAKE %s", m_Username.c_str()); - - if (cRoot::Get()->GetDefaultWorld()->GetNumPlayers() >= cRoot::Get()->GetDefaultWorld()->GetMaxPlayers()) - { - Kick("The server is currently full :(-- Try again later"); - return; - } - cPacket_Chat Connecting(m_Username + " is connecting."); - cRoot::Get()->GetServer()->Broadcast(Connecting, this); - - cPacket_Handshake Handshake; - Handshake.m_Username = cRoot::Get()->GetServer()->GetServerID(); - Send(Handshake); - LOG("User \"%s\" was sent a handshake", m_Username.c_str()); -} - - - - - -void cClientHandle::HandleLogin(cPacket_Login * a_Packet) -{ - LOG("LOGIN %s", m_Username.c_str()); - if (a_Packet->m_ProtocolVersion < m_ProtocolVersion) - { - Kick("Your client is outdated!"); - return; - } - else if (a_Packet->m_ProtocolVersion > m_ProtocolVersion) - { - Kick("Your client version is higher than the server!"); - return; - } - if (m_Username.compare(a_Packet->m_Username) != 0) - { - LOGWARNING("Login Username (\"%s\") does not match Handshake username (\"%s\") for client \"%s\")", - a_Packet->m_Username.c_str(), - m_Username.c_str(), - m_Socket.GetIPString().c_str() - ); - Kick("Hacked client"); // Don't tell them why we don't want them - return; - } - - if (cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_LOGIN, 1, a_Packet)) - { - Destroy(); - return; - } - - // Schedule for authentication; until then, let them wait (but do not block) - m_State = csAuthenticating; - cRoot::Get()->GetAuthenticator().Authenticate(GetUniqueID(), GetUsername(), cRoot::Get()->GetServer()->GetServerID()); -} - - - - - -void cClientHandle::HandleUnexpectedPacket(cPacket * a_Packet) -{ - LOGWARNING( - "Invalid packet in state %d: 0x%02x from client \"%s\", username \"%s\"", - m_State, - a_Packet->m_PacketID, - m_Socket.GetIPString().c_str(), - m_Username.c_str() - ); - Kick("Hacked client"); // Don't tell them why we don't like them -} - - - - - -void cClientHandle::HandleMoveLookConfirm(cPacket_PlayerMoveLook * a_Packet) -{ - Vector3d ReceivedPosition = Vector3d(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); - - // Test the distance between points with a small/large enough value instead of comparing directly. Floating point inaccuracies might screw stuff up - double Dist = (ReceivedPosition - m_ConfirmPosition).SqrLength(); - if (Dist < 1.0) - { - // Test - if (ReceivedPosition.Equals(m_ConfirmPosition)) - { - LOGINFO("Exact position confirmed by client!"); - } - m_State = csPlaying; - } - else - { - LOGWARNING("Player \"%s\" sent a weird position confirmation %.2f blocks away, retrying", m_Username.c_str(), Dist); - m_ConfirmPosition = m_Player->GetPosition(); - Send(cPacket_PlayerMoveLook(m_Player)); - } -} - - - - - -void cClientHandle::HandleCreativeInventory(cPacket_CreativeInventoryAction * a_Packet) -{ - // This is for creative Inventory changes - if (m_Player->GetGameMode() == 1) - { - m_Player->GetInventory().Clicked(a_Packet); - } - else - { - LOGWARNING("Got a CreativeInventoryAction packet from user \"%s\" while not in creative mode. Ignoring.", m_Username.c_str()); - } -} - - - - - -void cClientHandle::HandlePlayerPos(cPacket_PlayerPosition * a_Packet) -{ - // LOG("recv player pos: %0.2f %0.2f %0.2f", PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ); - m_Player->MoveTo(Vector3d(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ)); - m_Player->SetStance(a_Packet->m_Stance); - m_Player->SetTouchGround(a_Packet->m_bFlying); -} - - - - - -void cClientHandle::HandleBlockDig(cPacket_BlockDig * a_Packet) -{ - if (!CheckBlockInteractionsRate()) - { - return; - } - - LOGD("OnBlockDig: {%i, %i, %i} Dir: %i Stat: %i", - a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, - a_Packet->m_Direction, a_Packet->m_Status - ); - - // Do we want plugins to disable tossing items? Probably no, so toss item before asking plugins for permission - if (a_Packet->m_Status == 0x04) // Drop held item - { - m_Player->TossItem(false); - return; - } - - cWorld* World = m_Player->GetWorld(); - BLOCKTYPE OldBlock = World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); - NIBBLETYPE OldMeta = World->GetBlockMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); - - if (cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_BLOCK_DIG, 4, a_Packet, m_Player, OldBlock, OldMeta)) - { - // The plugin doesn't agree with the digging, replace the block on the client and quit: - World->SendBlockTo(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, m_Player); - return; - } - - bool bBroken = ( - (a_Packet->m_Status == 0x02) || - (g_BlockOneHitDig[(int)OldBlock]) || - ((a_Packet->m_Status == 0x00) && (m_Player->GetGameMode() == 1)) - ); - - if ((OldBlock == E_BLOCK_WOODEN_DOOR) && !bBroken) - { - cDoors::ChangeDoor(m_Player->GetWorld(), a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); - } - - cItems PickupItems; - if (bBroken && !(m_Player->GetGameMode() == 1)) // broken - { - cBlockToPickup::ToPickup(OldBlock, OldMeta, m_Player->GetInventory().GetEquippedItem(), PickupItems); - - // Allow plugins to change the dropped objects: - cRoot::Get()->GetPluginManager()->CallHookBlockToPickup(OldBlock, OldMeta, m_Player, m_Player->GetInventory().GetEquippedItem(), PickupItems); - } - - int pX = a_Packet->m_PosX; - unsigned char pY = a_Packet->m_PosY; - int pZ = a_Packet->m_PosZ; - - AddDirection(pX, pY, pZ, a_Packet->m_Direction); - - char PossibleBlock = World->GetBlock(pX, pY, pZ); - - if (PossibleBlock == E_BLOCK_FIRE) - { - a_Packet->m_PosX = pX; - a_Packet->m_PosY = pY; - a_Packet->m_PosZ = pZ; - bBroken = true; - } - - if (!bBroken) - { - return; - } - - if (!World->DigBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ)) - { - return; - } - - World->SpawnItemPickups(PickupItems, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); - - switch (OldBlock) - { - case E_BLOCK_REDSTONE_TORCH_ON: - case E_BLOCK_REDSTONE_TORCH_OFF: - case E_BLOCK_REDSTONE_WIRE: - { - cRedstone Redstone(World); - Redstone.ChangeRedstone(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, false); - break; - } - } - - if ((OldBlock == E_BLOCK_PISTON) || (OldBlock == E_BLOCK_STICKY_PISTON)) - { - int newX = a_Packet->m_PosX; - int newY = a_Packet->m_PosY; - int newZ = a_Packet->m_PosZ; - AddPistonDir(newX, newY, newZ, OldMeta & ~(8), 1); - if (World->GetBlock(newX, newY, newZ) == E_BLOCK_PISTON_EXTENSION) - { - World->SetBlock(newX, newY, newZ, E_BLOCK_AIR, 0); - } - } - - if (cDoors::IsDoor(OldBlock)) - { - // Special actions for destroyed door (Destroy second part) - if (OldMeta & 8) - { - // Was upper part of door - if (cDoors::IsDoor(World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY - 1, a_Packet->m_PosZ))) - { - World->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY - 1, a_Packet->m_PosZ, E_BLOCK_AIR, 0); - } - } - else - { - // Was lower part - if (cDoors::IsDoor(World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ))) - { - World->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ, E_BLOCK_AIR, 0); - } - } - } - - m_Player->UseEquippedItem(); -} - - - - - -void cClientHandle::HandleBlockPlace(cPacket_BlockPlace * a_Packet) -{ - if (!CheckBlockInteractionsRate()) - { - return; - } - - cItem & Equipped = m_Player->GetInventory().GetEquippedItem(); - - if ((Equipped.m_ItemID != a_Packet->m_ItemType)) // Not valid - { - LOGWARN("Player %s tried to place a block that was not equipped (exp %d, got %d)", - m_Username.c_str(), Equipped.m_ItemID, a_Packet->m_ItemType - ); - // TODO: We should probably send the current world block to the client, so that it can immediately "let the user know" that they haven't placed the block - return; - } - - if (cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_BLOCK_PLACE, 2, a_Packet, m_Player)) - { - if (a_Packet->m_Direction > -1) - { - AddDirection(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_Direction); - m_Player->GetWorld()->SendBlockTo(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, m_Player); - } - return; - } - - //LOG("%i %i %i %i %i %i", a_Packet->m_Count, a_Packet->m_Direction, a_Packet->m_ItemType, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); - - //printf("Place Dir:%i %i %i %i : %i\n", a_Packet->m_Direction, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_ItemType); - // 'use' useable items instead of placing blocks - bool bPlaceBlock = true; - bool UpdateRedstone = false; - bool AddedCurrent = false; - - if (a_Packet->m_Direction >= 0) - { - cWorld * World = m_Player->GetWorld(); - BLOCKTYPE BlockType = 0; - NIBBLETYPE BlockMeta; - World->GetBlockTypeMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, BlockType, BlockMeta); - switch (BlockType) - { - case E_BLOCK_REDSTONE_REPEATER_ON: - case E_BLOCK_REDSTONE_REPEATER_OFF: - { - // no need to update redstone current with a repeater - // Find meta value of repeater and change it to one step more: - World->FastSetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, BlockType, ((BlockMeta + 0x04) & 0x0f)); - bPlaceBlock = false; - break; - } - - case E_BLOCK_WORKBENCH: - { - bPlaceBlock = false; - cWindow* Window = new cCraftingWindow(0, true); - m_Player->OpenWindow(Window); - break; - } - - case E_BLOCK_FURNACE: - case E_BLOCK_CHEST: - { - bPlaceBlock = false; - m_Player->GetWorld()->UseBlockEntity(m_Player, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); - break; - } - - case E_BLOCK_WOODEN_DOOR: - { - bPlaceBlock = false; - cDoors::ChangeDoor(m_Player->GetWorld(), a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); - break; - } - - default: - { - break; - } - } // switch (BlockID) - } // if (Direction >= 0) - - // Some checks to see if it's a placeable item :P - if (bPlaceBlock) - { - cItem Item; - Item.m_ItemID = Equipped.m_ItemID; - Item.m_ItemCount = 1; - LOGD("Placing item of type %i at {%d, %d, %d}", - (int)a_Packet->m_ItemType, - a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ - ); - - if (m_Player->EatItem(Item.m_ItemID)) - { - m_Player->GetInventory().RemoveItem(Item); - return; - } - - if (a_Packet->m_Direction < 0) - { - // clicked in air - return; - } - bool isDoor = false; - - //TODO: Wrong Blocks! - BLOCKTYPE ClickedBlock = m_Player->GetWorld()->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); - - if (ItemCategory::IsHoe(Item.m_ItemID)) - { - if ((ClickedBlock == E_BLOCK_DIRT) || (ClickedBlock == E_BLOCK_GRASS)) - { - m_Player->GetWorld()->FastSetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, E_BLOCK_FARMLAND, 0); - } - return; - } - - NIBBLETYPE MetaData = (NIBBLETYPE)Equipped.m_ItemHealth; // This generally works for logs & planks, others will override - bool LavaBucket = false; - bool WaterBucket = false; - bool bRemoveItem = true; - bool bIgnoreCollision = false; - - if (ClickedBlock == E_BLOCK_STEP) - { - // Only make double slab if meta values are the same and if player clicked either on top or on bottom of the block (direction either 0 or 1) - // TODO check if it works from beneath - if (MetaData == ( m_Player->GetWorld()->GetBlockMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ) & 0x7) && a_Packet->m_Direction <= 1) - //if (MetaData == m_Player->GetWorld()->GetBlockMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ) && a_Packet->m_Direction == 1) - { - a_Packet->m_ItemType = E_BLOCK_DOUBLE_STEP; - if(a_Packet->m_Direction == 1) - { - a_Packet->m_PosY--; - } - else - { - a_Packet->m_PosY++; - } - bIgnoreCollision = true; - } - } - - // Special handling for special items: - switch (a_Packet->m_ItemType) - { - case E_ITEM_BUCKET: - { - // TODO: Change this, it is just a small hack to get it working a little bit. seems like the Client sends the position from the first hitable block :s - ClickedBlock = (int)m_Player->GetWorld()->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ); - LOG("Bucket Clicked BlockID: %d", ClickedBlock); - switch (ClickedBlock) - { - case E_BLOCK_WATER: - case E_BLOCK_STATIONARY_WATER: - { - WaterBucket = true; - break; - } - case E_BLOCK_LAVA: - case E_BLOCK_STATIONARY_LAVA: - { - LavaBucket = true; - break; - } - } - break; - } // case E_ITEM_BUCKET - - case E_ITEM_LAVA_BUCKET: - { - if ((m_Player->GetGameMode() == 1) || (m_Player->GetInventory().RemoveItem(Item))) - { - a_Packet->m_ItemType = E_BLOCK_LAVA; - if (m_Player->GetGameMode() == 1) - { - break; //No new Bucket for creative players - } - - cItem NewItem; - NewItem.m_ItemID = E_ITEM_BUCKET; - NewItem.m_ItemCount = 1; - m_Player->GetInventory().AddItem(NewItem); - } - break; - } // case E_ITEM_LAVA_BUCKET - - case E_ITEM_WATER_BUCKET: - { - if ((m_Player->GetGameMode() == 1) || (m_Player->GetInventory().RemoveItem(Item))) - { - a_Packet->m_ItemType = E_BLOCK_WATER; - if (m_Player->GetGameMode() == 1) - { - break; //No new Bucket for creative players - } - cItem NewItem; - NewItem.m_ItemID = E_ITEM_BUCKET; - NewItem.m_ItemCount = 1; - m_Player->GetInventory().AddItem(NewItem); - } - break; - } - - case E_BLOCK_TORCH: - { - MetaData = cTorch::DirectionToMetaData(a_Packet->m_Direction); - break; - } - - case E_BLOCK_REDSTONE_TORCH_OFF: - { - MetaData = cTorch::DirectionToMetaData(a_Packet->m_Direction); - if (g_BlockTransparent[ (int)m_Player->GetWorld()->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY+2, a_Packet->m_PosZ) ] == true) - { - //if block above is transparent - //printf("transparent above me\n"); - } - else - { - //printf("transparent not above me\n"); - } - UpdateRedstone = true; - AddedCurrent = false; - break; - } - - case E_BLOCK_REDSTONE_TORCH_ON: - { - MetaData = cTorch::DirectionToMetaData(a_Packet->m_Direction); - UpdateRedstone = true; - AddedCurrent = true; - break; - } - - case E_ITEM_REDSTONE_DUST: - { - MetaData = 0; - a_Packet->m_ItemType = E_BLOCK_REDSTONE_WIRE; - UpdateRedstone = true; - AddedCurrent = false; - break; - } - - case E_ITEM_REDSTONE_REPEATER: - { - MetaData = cRedstone::RepeaterRotationToMetaData(m_Player->GetRotation()); - a_Packet->m_ItemType = E_BLOCK_REDSTONE_REPEATER_OFF; - UpdateRedstone = true; - AddedCurrent = false; - break; - } - - case E_BLOCK_PISTON: - case E_BLOCK_STICKY_PISTON: - { - MetaData = cPiston::RotationPitchToMetaData(m_Player->GetRotation(), m_Player->GetPitch()); - UpdateRedstone = true; - AddedCurrent = false; - break; - } - - case E_ITEM_IRON_DOOR: - { - a_Packet->m_ItemType = E_BLOCK_IRON_DOOR; - MetaData = cDoors::RotationToMetaData(m_Player->GetRotation()); - isDoor = true; - break; - } - - case E_ITEM_WOODEN_DOOR: - { - a_Packet->m_ItemType = E_BLOCK_WOODEN_DOOR; - MetaData = cDoors::RotationToMetaData(m_Player->GetRotation()); - isDoor = true; - break; - } - - case E_BLOCK_CHEST: - case E_BLOCK_FURNACE: - case E_BLOCK_DISPENSER: - { - MetaData = cPiston::RotationPitchToMetaData(m_Player->GetRotation(), 0); // Same orientation as pistons, just ignore pitch - break; - } - - case E_BLOCK_STEP: - { - MetaData += cStep::DirectionToMetaData( a_Packet->m_Direction ); - break; - } - - case E_BLOCK_COBBLESTONE_STAIRS: - case E_BLOCK_BRICK_STAIRS: - case E_BLOCK_STONE_BRICK_STAIRS: - case E_BLOCK_NETHER_BRICK_STAIRS: - case E_BLOCK_WOODEN_STAIRS: - { - MetaData = cStairs::RotationToMetaData(m_Player->GetRotation(), a_Packet->m_Direction); - break; - } - case E_BLOCK_LADDER: - { - MetaData = cLadder::DirectionToMetaData(a_Packet->m_Direction); - break; - } - case E_ITEM_SIGN: - { - LOGD("Sign Dir: %i", a_Packet->m_Direction); - if (a_Packet->m_Direction == 1) - { - LOGD("Player Rotation: %f", m_Player->GetRotation()); - MetaData = cSign::RotationToMetaData(m_Player->GetRotation()); - LOGD("Sign rotation %i", MetaData); - a_Packet->m_ItemType = E_BLOCK_SIGN_POST; - } - else - { - MetaData = cSign::DirectionToMetaData(a_Packet->m_Direction); - a_Packet->m_ItemType = E_BLOCK_WALLSIGN; - } - break; - } - - case E_ITEM_FLINT_AND_STEEL: - { - a_Packet->m_ItemType = E_ITEM_FIRE; - m_Player->UseEquippedItem(); - bRemoveItem = false; - break; - } - case E_ITEM_SEEDS: - { - if (ClickedBlock != E_BLOCK_FARMLAND) - { - return; - } - a_Packet->m_ItemType = E_BLOCK_CROPS; - break; - } - case E_ITEM_MELON_SEEDS: - { - if (ClickedBlock != E_BLOCK_FARMLAND) - { - return; - } - a_Packet->m_ItemType = E_BLOCK_MELON_STEM; - break; - } - case E_ITEM_PUMPKIN_SEEDS: - { - if (ClickedBlock != E_BLOCK_FARMLAND) - { - return; - } - a_Packet->m_ItemType = E_BLOCK_PUMPKIN_STEM; - break; - } - case E_ITEM_DYE: - { - // Handle bonemeal and dyes on sheep - if (HandleDyes(a_Packet)) - { - if (m_Player->GetGameMode() == eGameMode_Survival) - { - m_Player->GetInventory().RemoveItem(Item); - } - return; - } - break; - } - case E_ITEM_SUGARCANE: - { - a_Packet->m_ItemType = E_BLOCK_SUGARCANE; - break; - } - default: - { - break; - } - } // switch (a_Packet->m_ItemType) - - - if (LavaBucket) - { - if ((m_Player->GetGameMode() == 1) || (m_Player->GetInventory().RemoveItem(Item))) { - cItem NewItem; - NewItem.m_ItemID = E_ITEM_LAVA_BUCKET; - NewItem.m_ItemCount = 1; - m_Player->GetInventory().AddItem(NewItem); - m_Player->GetWorld()->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ, E_BLOCK_AIR, 0); - } - } - else if (WaterBucket) - { - if ((m_Player->GetGameMode() == 1) || (m_Player->GetInventory().RemoveItem(Item))) - { - cItem NewItem; - NewItem.m_ItemID = E_ITEM_WATER_BUCKET; - NewItem.m_ItemCount = 1; - m_Player->GetInventory().AddItem(NewItem); - m_Player->GetWorld()->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ, E_BLOCK_AIR, 0); - } - } - else if (IsValidBlock(a_Packet->m_ItemType)) - { - int X = a_Packet->m_PosX; - int Y = a_Packet->m_PosY; - int Z = a_Packet->m_PosZ; - AddDirection(X, Y, Z, a_Packet->m_Direction); - - int PlaceBlock = m_Player->GetWorld()->GetBlock(X, Y, Z); - if ( - (PlaceBlock != E_BLOCK_AIR) - && (PlaceBlock != E_BLOCK_WATER) - && (PlaceBlock != E_BLOCK_STATIONARY_WATER) - && (PlaceBlock != E_BLOCK_LAVA) - && (PlaceBlock != E_BLOCK_STATIONARY_LAVA) - && !bIgnoreCollision - ) - { - //tried to place a block *into* another? - return; // happens when you place a block aiming at side of block like torch or stem - } - - // Check whether selected item is allowed to be placed on specific surface - if (!m_Player->GetWorld()->IsPlacingItemLegal(a_Packet->m_ItemType, X, Y, Z)) - { - // If we don't send the block, MC is happy placing cacti underwater: - m_Player->GetWorld()->SendBlockTo(X, Y, Z, m_Player); - return; - } - - if (bRemoveItem) - { - if ((m_Player->GetGameMode() != 1) && !m_Player->GetInventory().RemoveItem(Item)) - { - return; - } - } - - - if (isDoor) - { - if ((m_Player->GetWorld()->GetBlock(X, Y + 1, Z) == E_BLOCK_AIR) || (m_Player->GetWorld()->GetBlock(X, Y + 1, Z) == E_BLOCK_AIR)) - { - m_Player->GetWorld()->SetBlock(X, Y + 1, Z, (char)a_Packet->m_ItemType, MetaData + 8); - m_Player->GetWorld()->SetBlock(X, Y, Z, (char)a_Packet->m_ItemType, MetaData); - } - } - else - { - m_Player->GetWorld()->SetBlock(X, Y, Z, (char)a_Packet->m_ItemType, MetaData); - } - - if (UpdateRedstone) - { - cRedstone Redstone(m_Player->GetWorld()); - Redstone.ChangeRedstone(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ, AddedCurrent); - } - } - } - - /* - // FakeTruth's "magic stick of removal" :D - // TODO: Turn this into a plugin - if (m_Username.compare("FakeTruth") == 0) - { - if (a_Packet->m_ItemType == 280) - { - cRoot::Get()->GetWorld()->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, 0, 0); - } - } - */ -} - - - - - -void cClientHandle::HandlePickupSpawn(cPacket_PickupSpawn * a_Packet) -{ - LOG("Received packet E_PICKUP_SPAWN"); - - cItem DroppedItem; - DroppedItem.m_ItemID = (ENUM_ITEM_ID)a_Packet->m_Item; - DroppedItem.m_ItemCount = a_Packet->m_Count; - DroppedItem.m_ItemHealth = 0x0; // TODO: Somehow figure out what item was dropped, and apply correct health - if (m_Player->GetInventory().RemoveItem(DroppedItem)) - { - cPickup * Pickup = new cPickup(a_Packet); - Pickup->Initialize(m_Player->GetWorld()); - } -} - - - - - -void cClientHandle::HandleChat(cPacket_Chat * a_Packet) -{ - if (!cRoot::Get()->GetServer()->Command(*this, a_Packet->m_Message.c_str())) - { - a_Packet->m_Message.insert(0, "<" + m_Player->GetColor() + m_Username + cChatColor::White + "> "); - cRoot::Get()->GetServer()->Broadcast(*a_Packet); - } -} - - - - - -void cClientHandle::HandlePlayerLook(cPacket_PlayerLook * a_Packet) -{ - m_Player->SetRotation (a_Packet->m_Rotation); - m_Player->SetPitch (a_Packet->m_Pitch); - m_Player->SetTouchGround(a_Packet->m_bFlying); - m_Player->WrapRotation(); -} - - - - - -void cClientHandle::HandlePlayerMoveLook(cPacket_PlayerMoveLook * a_Packet) -{ - m_Player->MoveTo(Vector3d(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ)); - m_Player->SetStance (a_Packet->m_Stance); - m_Player->SetTouchGround(a_Packet->m_bFlying); - m_Player->SetRotation (a_Packet->m_Rotation); - m_Player->SetPitch (a_Packet->m_Pitch); - m_Player->WrapRotation(); -} - - - - - -void cClientHandle::HandleAnimation(cPacket_ArmAnim * a_Packet) -{ - a_Packet->m_EntityID = m_Player->GetUniqueID(); - cRoot::Get()->GetServer()->Broadcast(*a_Packet, this); -} - - - - - -void cClientHandle::HandleItemSwitch(cPacket_ItemSwitch * a_Packet) -{ - m_Player->GetInventory().SetEquippedSlot(a_Packet->m_SlotNum); - - cPacket_EntityEquipment Equipment; - Equipment.m_ItemID = (short)m_Player->GetInventory().GetEquippedItem().m_ItemID; - Equipment.m_Slot = 0; - Equipment.m_UniqueID = m_Player->GetUniqueID(); - cRoot::Get()->GetServer()->Broadcast(Equipment, this); -} - - - - - -void cClientHandle::HandleWindowClose(cPacket_WindowClose * a_Packet) -{ - m_Player->CloseWindow(a_Packet->m_Close); -} - - - - - -void cClientHandle::HandleWindowClick(cPacket_WindowClick * a_Packet) -{ - if (a_Packet->m_WindowID == 0) - { - m_Player->GetInventory().Clicked(a_Packet); - return; - } - - cWindow * Window = m_Player->GetWindow(); - if (Window == NULL) - { - LOGWARNING("Player \"%s\" clicked in a non-existent window. Ignoring", m_Username.c_str()); - return; - } - - Window->Clicked(a_Packet, *m_Player); -} - - - - - -void cClientHandle::HandleUpdateSign(cPacket_UpdateSign * a_Packet) -{ - cWorld * World = m_Player->GetWorld(); - World->UpdateSign(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_Line1, a_Packet->m_Line2, a_Packet->m_Line3, a_Packet->m_Line4); -} - - - - - -void cClientHandle::HandleUseEntity(cPacket_UseEntity * a_Packet) -{ - if (!a_Packet->m_bLeftClick) - { - return; - } - - class cDamageEntity : public cEntityCallback - { - virtual bool Item(cEntity * a_Entity) override - { - if( a_Entity->IsA("cPawn") ) - { - reinterpret_cast< cPawn* >( a_Entity )->TakeDamage(Damage, Instigator ); - } - return true; - } - public: - int Damage; - cEntity * Instigator; - } Callback; - - Callback.Damage = 1; // TODO: Find proper damage from current item equipped - Callback.Instigator = m_Player; - - cWorld * World = m_Player->GetWorld(); - World->DoWithEntity( a_Packet->m_TargetID, Callback ); -} - - - - - -void cClientHandle::HandleRespawn(void) -{ - m_Player->Respawn(); -} - - - - - -void cClientHandle::HandleDisconnect(cPacket_Disconnect * a_Packet) -{ - LOG("Received d/c packet from \"%s\"", m_Username.c_str()); - if (!cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_DISCONNECT, 2, a_Packet->m_Reason.c_str(), m_Player)) - { - cPacket_Chat DisconnectMessage(m_Username + " disconnected: " + a_Packet->m_Reason); - cRoot::Get()->GetServer()->Broadcast(DisconnectMessage); - } - Destroy(); -} - - - - - -void cClientHandle::HandleKeepAlive(cPacket_KeepAlive * a_Packet) -{ - if (a_Packet->m_KeepAliveID == m_PingID) - { - cTimer t1; - m_Ping = (short)((t1.GetNowTime() - m_PingStartTime) / 2); - } -} - - - - - -bool cClientHandle::HandleDyes(cPacket_BlockPlace * a_Packet) -{ - cItem & Equipped = m_Player->GetInventory().GetEquippedItem(); - - // TODO: Handle coloring the sheep, too - - // Handle growing the plants: - if (Equipped.m_ItemHealth == E_META_DYE_WHITE) - { - cWorld * World = m_Player->GetWorld(); - return World->GrowPlant(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, true); - } - - return false; -} - - - - - -bool cClientHandle::CheckBlockInteractionsRate(void) -{ - ASSERT(m_Player != NULL); - ASSERT(m_Player->GetWorld() != NULL); - int LastActionCnt = m_Player->GetLastBlockActionCnt(); - if ((m_Player->GetWorld()->GetTime() - m_Player->GetLastBlockActionTime()) < 0.1) - { - // Limit the number of block interactions per tick - m_Player->SetLastBlockActionTime(); //Player tried to interact with a block. Reset last block interation time. - m_Player->SetLastBlockActionCnt(LastActionCnt + 1); - if (m_Player->GetLastBlockActionCnt() > MAXBLOCKCHANGEINTERACTIONS) - { - // Kick if more than MAXBLOCKCHANGEINTERACTIONS per tick - LOGWARN("Player %s tried to interact with a block too quickly! (could indicate bot) Was Kicked.", m_Username.c_str()); - Kick("You're a baaaaaad boy!"); - return false; - } - } - else - { - m_Player->SetLastBlockActionCnt(0); // Reset count - m_Player->SetLastBlockActionTime(); // Player tried to interact with a block. Reset last block interation time. - } - return true; -} - - - - - -void cClientHandle::Tick(float a_Dt) -{ - (void)a_Dt; - if (cWorld::GetTime() - m_TimeLastPacket > 30.f) // 30 seconds time-out - { - cPacket_Disconnect DC("Nooooo!! You timed out! D: Come back!"); - m_Socket.Send(&DC); - - // TODO: Cannot sleep in the tick thread! - cSleep::MilliSleep(1000); // Give packet some time to be received - - Destroy(); - } - - cTimer t1; - // Send ping packet - if (m_LastPingTime + cClientHandle::PING_TIME_MS <= t1.GetNowTime()) - { - m_PingID++; - cPacket_KeepAlive Ping(m_PingID); - m_PingStartTime = t1.GetNowTime(); - Send(Ping); - m_LastPingTime = m_PingStartTime; - } -} - - - - - -void cClientHandle::Send(const cPacket & a_Packet, ENUM_PRIORITY a_Priority /* = E_PRIORITY_NORMAL */) -{ - if (m_bKicking) return; // Don't add more packets if player is getting kicked anyway - - // If it is the packet spawning myself for myself, drop it silently: - if (a_Packet.m_PacketID == E_NAMED_ENTITY_SPAWN) - { - if (((cPacket_NamedEntitySpawn &)a_Packet).m_UniqueID == m_Player->GetUniqueID()) - { - return; - } - } - - // Filter out packets that don't belong to a csDownloadingWorld state: - if (m_State == csDownloadingWorld) - { - switch (a_Packet.m_PacketID) - { - case E_PLAYERMOVELOOK: - case E_KEEP_ALIVE: - case E_PRE_CHUNK: - case E_MAP_CHUNK: - { - // Allow - break; - } - default: return; - } - } - - // Filter out map chunks that the client doesn't want anymore: - if (a_Packet.m_PacketID == E_MAP_CHUNK) - { - // Check chunks being sent, erase them from m_ChunksToSend: - int ChunkX = ((cPacket_MapChunk &)a_Packet).m_PosX; - int ChunkZ = ((cPacket_MapChunk &)a_Packet).m_PosZ; - bool Found = false; - cCSLock Lock(m_CSChunkLists); - for (cChunkCoordsList::iterator itr = m_ChunksToSend.begin(); itr != m_ChunksToSend.end(); ++itr) - { - if ((itr->m_ChunkX == ChunkX) && (itr->m_ChunkZ == ChunkZ)) - { - m_ChunksToSend.erase(itr); - CheckIfWorldDownloaded(); - Found = true; - break; - } - } // for itr - m_ChunksToSend[] - if (!Found) - { - // This just sometimes happens. If you have a reliably replicatable situation for this, go ahead and fix it - // It's not a big issue anyway, just means that some chunks may be compressed several times - // LOGD("Refusing to send chunk [%d, %d] to client \"%s\" at [%d, %d].", ChunkX, ChunkZ, m_Username.c_str(), m_Player->GetChunkX(), m_Player->GetChunkZ()); - return; - } - } - - // Filter out pre chunks that the client doesn't want anymore: - if ((a_Packet.m_PacketID == E_PRE_CHUNK) && ((cPacket_PreChunk &)a_Packet).m_bLoad) - { - int ChunkX = ((cPacket_PreChunk &)a_Packet).m_PosX; - int ChunkZ = ((cPacket_PreChunk &)a_Packet).m_PosZ; - bool Found = false; - cCSLock Lock(m_CSChunkLists); - for (cChunkCoordsList::iterator itr = m_ChunksToSend.begin(); itr != m_ChunksToSend.end(); ++itr) - { - if ((itr->m_ChunkX == ChunkX) && (itr->m_ChunkZ == ChunkZ)) - { - Found = true; - break; - } - } // for itr - m_ChunksToSend[] - if (!Found) - { - // This just sometimes happens. If you have a reliably replicatable situation for this, go ahead and fix it - // It's not a big issue anyway, just means that some chunks may be compressed several times - // LOGD("Refusing to send PREchunk [%d, %d] to client \"%s\" at [%d, %d].", ChunkX, ChunkZ, m_Username.c_str(), m_Player->GetChunkX(), m_Player->GetChunkZ()); - return; - } - } - - // Optimize away multiple queued RelativeEntityMoveLook packets: - cCSLock Lock(m_CSPackets); - if (a_Priority == E_PRIORITY_NORMAL) - { - if (a_Packet.m_PacketID == E_REL_ENT_MOVE_LOOK) - { - PacketList & Packets = m_PendingNrmSendPackets; - const cPacket_RelativeEntityMoveLook & ThisPacketData = reinterpret_cast< const cPacket_RelativeEntityMoveLook &>(a_Packet); - for (PacketList::iterator itr = Packets.begin(); itr != Packets.end(); ++itr) - { - bool bBreak = false; - switch ((*itr)->m_PacketID) - { - case E_REL_ENT_MOVE_LOOK: - { - cPacket_RelativeEntityMoveLook * PacketData = reinterpret_cast< cPacket_RelativeEntityMoveLook *>(*itr); - if (ThisPacketData.m_UniqueID == PacketData->m_UniqueID) - { - Packets.erase(itr); - bBreak = true; - delete PacketData; - break; - } - break; - } // case E_REL_END_MOVE_LOOK - } // switch (*itr -> Packet type) - if (bBreak) - { - break; - } - } // for itr - Packets[] - } // if (E_REL_ENT_MOVE_LOOK - m_PendingNrmSendPackets.push_back(a_Packet.Clone()); - } - else if (a_Priority == E_PRIORITY_LOW) - { - m_PendingLowSendPackets.push_back(a_Packet.Clone()); - } - Lock.Unlock(); - - // Notify SocketThreads that we have something to write: - cRoot::Get()->GetServer()->NotifyClientWrite(this); -} - - - - - -void cClientHandle::CheckIfWorldDownloaded(void) -{ - if (m_State != csDownloadingWorld) - { - return; - } - cCSLock Lock(m_CSChunkLists); - if (m_ChunksToSend.empty()) - { - SendConfirmPosition(); - } -} - - - - - -void cClientHandle::SendConfirmPosition(void) -{ - LOG("Spawning player \"%s\" at {%.2f, %.2f, %.2f}", - m_Username.c_str(), m_Player->GetPosX(), m_Player->GetPosY(), m_Player->GetPosZ() - ); - - m_State = csConfirmingPos; - - if (!cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_PLAYER_JOIN, 1, m_Player)) - { - // Broadcast that this player has joined the game! Yay~ - cPacket_Chat Joined(m_Username + " joined the game!"); - cRoot::Get()->GetServer()->Broadcast(Joined, this); - } - - m_ConfirmPosition = m_Player->GetPosition(); - Send(cPacket_PlayerMoveLook(m_Player)); -} - - - - - -const AString & cClientHandle::GetUsername(void) const -{ - return m_Username; -} - - - - - -void cClientHandle::SetViewDistance(int a_ViewDistance) -{ - if (a_ViewDistance < MIN_VIEW_DISTANCE) - { - a_ViewDistance = MIN_VIEW_DISTANCE; - } - if (a_ViewDistance > MAX_VIEW_DISTANCE) - { - a_ViewDistance = MAX_VIEW_DISTANCE; - } - m_ViewDistance = a_ViewDistance; - - // Need to re-stream chunks for the change to become apparent: - StreamChunks(); -} - - - - - -bool cClientHandle::WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - cCSLock Lock(m_CSChunkLists); - return (std::find(m_ChunksToSend.begin(), m_ChunksToSend.end(), cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)) != m_ChunksToSend.end()); -} - - - - - -void cClientHandle::AddWantedChunk(int a_ChunkX, int a_ChunkZ) -{ - LOGD("Adding chunk [%d, %d] to wanted chunks for client %p", a_ChunkX, a_ChunkZ, this); - cCSLock Lock(m_CSChunkLists); - if (std::find(m_ChunksToSend.begin(), m_ChunksToSend.end(), cChunkCoords(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ)) == m_ChunksToSend.end()) - { - m_ChunksToSend.push_back(cChunkCoords(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ)); - } -} - - - - - -void cClientHandle::DataReceived(const char * a_Data, int a_Size) -{ - // Data is received from the client - - m_ReceivedData.append(a_Data, a_Size); - - // Parse and handle all complete packets in m_ReceivedData: - while (!m_ReceivedData.empty()) - { - cPacket* pPacket = m_PacketMap[(unsigned char)m_ReceivedData[0]]; - if (pPacket == NULL) - { - LOGERROR("Unknown packet type 0x%02x from client \"%s\"", (unsigned char)m_ReceivedData[0], m_Username.c_str()); - - AString Reason; - Printf(Reason, "[C->S] Unknown PacketID: 0x%02x", (unsigned char)m_ReceivedData[0]); - cPacket_Disconnect DC(Reason); - m_Socket.Send(&DC); - cSleep::MilliSleep(1000); // Give packet some time to be received - Destroy(); - return; - } - - int NumBytes = pPacket->Parse(m_ReceivedData.data() + 1, m_ReceivedData.size() - 1); - if (NumBytes == PACKET_ERROR) - { - LOGERROR("Protocol error while parsing packet type 0x%02x; disconnecting client \"%s\"", (unsigned char)m_ReceivedData[0], m_Username.c_str()); - cPacket_Disconnect DC("Protocol error"); - m_Socket.Send(&DC); - cSleep::MilliSleep(1000); // Give packet some time to be received - Destroy(); - return; - } - else if (NumBytes == PACKET_INCOMPLETE) - { - // Not a complete packet - break; - } - else - { - // Packet parsed successfully, add it to internal queue: - HandlePacket(pPacket); - // Erase the packet from the buffer: - ASSERT(m_ReceivedData.size() > (size_t)NumBytes); - m_ReceivedData.erase(0, NumBytes + 1); - } - } // while (!Received.empty()) -} - - - - - -void cClientHandle::GetOutgoingData(AString & a_Data) -{ - // Data can be sent to client - - cCSLock Lock(m_CSPackets); - if (m_PendingNrmSendPackets.size() + m_PendingLowSendPackets.size() > MAX_OUTGOING_PACKETS) - { - LOGERROR("ERROR: Too many packets in queue for player %s !!", m_Username.c_str()); - cPacket_Disconnect DC("Too many packets in queue."); - m_Socket.Send(DC); - - // DEBUG: Dump all outstanding packets' types to the log: - int Idx = 0; - int ChunkX = m_Player->GetChunkX(); - int ChunkZ = m_Player->GetChunkZ(); - for (PacketList::const_iterator itr = m_PendingNrmSendPackets.begin(); itr != m_PendingNrmSendPackets.end(); ++itr) - { - switch ((*itr)->m_PacketID) - { - case E_MAP_CHUNK: - { - int x = ((cPacket_MapChunk *)(*itr))->m_PosX; - int z = ((cPacket_MapChunk *)(*itr))->m_PosZ; - bool IsWanted = (abs(x - ChunkX) <= m_ViewDistance) && (abs(z - ChunkZ) <= m_ViewDistance); - LOG("Packet %4d: type %2x (MapChunk: %d, %d, %s)", - Idx++, (*itr)->m_PacketID, - x, z, - IsWanted ? "wanted" : "unwanted" - ); - break; - } - - case E_PRE_CHUNK: - { - int x = ((cPacket_PreChunk *)(*itr))->m_PosX; - int z = ((cPacket_PreChunk *)(*itr))->m_PosZ; - bool IsWanted = (abs(x - ChunkX) <= m_ViewDistance) && (abs(z - ChunkZ) <= m_ViewDistance); - bool Loading = ((cPacket_PreChunk *)(*itr))->m_bLoad; - LOG("Packet %4d: type %2x (PreChunk: %d, %d, %s, %s)", - Idx++, (*itr)->m_PacketID, - x, z, - Loading ? "loading" : "unloading", - IsWanted ? "wanted" : "unwanted" - ); - break; - } - - case E_BLOCK_CHANGE: - { - int x = ((cPacket_BlockChange *)(*itr))->m_PosX; - int z = ((cPacket_BlockChange *)(*itr))->m_PosZ; - char ToBlock = ((cPacket_BlockChange *)(*itr))->m_BlockType; - int y, cx, cz; - cChunkDef::AbsoluteToRelative(x, y, z, cx, cz); - bool IsWanted = (abs(cx - ChunkX) <= m_ViewDistance) && (abs(cz - ChunkZ) <= m_ViewDistance); - LOG("Packet %4d: type %2x (BlockChange: [%d, %d], %s chunk; to block %d)", - Idx++, (*itr)->m_PacketID, - cx, cz, - IsWanted ? "wanted" : "unwanted", - ToBlock - ); - break; - } - - case E_MULTI_BLOCK: - { - int cx = ((cPacket_MultiBlock *)(*itr))->m_ChunkX; - int cz = ((cPacket_MultiBlock *)(*itr))->m_ChunkZ; - int NumBlocks = ((cPacket_MultiBlock *)(*itr))->m_NumBlocks; - bool IsWanted = (abs(cx - ChunkX) <= m_ViewDistance) && (abs(cz - ChunkZ) <= m_ViewDistance); - LOG("Packet %4d: type %2x (MultiBlock: [%d, %d], %s chunk, %d blocks)", - Idx++, (*itr)->m_PacketID, - cx, cz, - IsWanted ? "wanted" : "unwanted", - NumBlocks - ); - break; - } - - default: - { - LOG("Packet %4d: type %2x", Idx++, (*itr)->m_PacketID); - break; - } - } - } - - Lock.Unlock(); - Destroy(); - return; - } - - if ((m_PendingNrmSendPackets.size() == 0) && (m_PendingLowSendPackets.size() == 0)) - { - return; - } - - if (m_PendingNrmSendPackets.size() > MAX_OUTGOING_PACKETS / 2) - { - LOGINFO("Suspiciously many pending packets: %i; client \"%s\", LastType: 0x%02x", m_PendingNrmSendPackets.size(), m_Username.c_str(), (*m_PendingNrmSendPackets.rbegin())->m_PacketID); - } - - AString Data; - Data.reserve(1100); - // Serialize normal-priority packets up to 1000 bytes - while (!m_PendingNrmSendPackets.empty() && (Data.size() < 1000)) - { - m_PendingNrmSendPackets.front()->Serialize(Data); - delete m_PendingNrmSendPackets.front(); - m_PendingNrmSendPackets.erase(m_PendingNrmSendPackets.begin()); - } - // Serialize one low-priority packet: - if (!m_PendingLowSendPackets.empty() && Data.empty()) - { - m_PendingLowSendPackets.front()->Serialize(Data); - delete m_PendingLowSendPackets.front(); - m_PendingLowSendPackets.erase(m_PendingLowSendPackets.begin()); - } - Lock.Unlock(); - - a_Data.append(Data); - - // Disconnect player after all packets have been sent - if (m_bKicking && (m_PendingNrmSendPackets.size() + m_PendingLowSendPackets.size() == 0)) - { - Destroy(); - } -} - - - - - -void cClientHandle::SocketClosed(void) -{ - // The socket has been closed for any reason - - // TODO - /* - self->Destroy(); - LOG("Client \"%s\" disconnected", GetLogName().c_str()); - */ -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cClientHandle.h" +#include "cServer.h" +#include "cWorld.h" +#include "cPickup.h" +#include "cPluginManager.h" +#include "cPlayer.h" +#include "cInventory.h" +#include "cChestEntity.h" +#include "cSignEntity.h" +#include "cWindow.h" +#include "cCraftingWindow.h" +#include "cItem.h" +#include "cTorch.h" +#include "cStairs.h" +#include "cStep.h" +#include "cDoors.h" +#include "cLadder.h" +#include "cSign.h" +#include "cRedstone.h" +#include "cPiston.h" +#include "cBlockToPickup.h" +#include "cMonster.h" +#include "cChatColor.h" +#include "cSocket.h" +#include "cTimer.h" + +#include "cTracer.h" +#include "Vector3f.h" +#include "Vector3d.h" + +#include "cSleep.h" +#include "cRoot.h" + +#include "cBlockingTCPLink.h" +#include "cAuthenticator.h" +#include "MersenneTwister.h" + +#include "packets/cPacket_KeepAlive.h" +#include "packets/cPacket_Respawn.h" +#include "packets/cPacket_UpdateHealth.h" +#include "packets/cPacket_RelativeEntityMoveLook.h" +#include "packets/cPacket_Chat.h" +#include "packets/cPacket_Login.h" +#include "packets/cPacket_WindowClick.h" +#include "packets/cPacket_TimeUpdate.h" +#include "packets/cPacket_BlockDig.h" +#include "packets/cPacket_Handshake.h" +#include "packets/cPacket_ArmAnim.h" +#include "packets/cPacket_BlockPlace.h" +#include "packets/cPacket_Flying.h" +#include "packets/cPacket_Disconnect.h" +#include "packets/cPacket_PickupSpawn.h" +#include "packets/cPacket_ItemSwitch.h" +#include "packets/cPacket_EntityEquipment.h" +#include "packets/cPacket_CreativeInventoryAction.h" +#include "packets/cPacket_NewInvalidState.h" +#include "packets/cPacket_UseEntity.h" +#include "packets/cPacket_WindowClose.h" +#include "packets/cPacket_13.h" +#include "packets/cPacket_UpdateSign.h" +#include "packets/cPacket_Ping.h" +#include "packets/cPacket_NamedEntitySpawn.h" +#include "packets/cPacket_MapChunk.h" +#include "packets/cPacket_PreChunk.h" + +// DEBUG: +#include "packets/cPacket_BlockChange.h" +#include "packets/cPacket_MultiBlock.h" + + + + + +#define AddPistonDir(x, y, z, dir, amount) switch (dir) { case 0: (y)-=(amount); break; case 1: (y)+=(amount); break;\ + case 2: (z)-=(amount); break; case 3: (z)+=(amount); break;\ + case 4: (x)-=(amount); break; case 5: (x)+=(amount); break; } + + + + + +/// If the number of queued outgoing packets reaches this, the client will be kicked +#define MAX_OUTGOING_PACKETS 2000 + + + + + +#define RECI_RAND_MAX (1.f/RAND_MAX) +inline int fRadRand(MTRand & r1, int a_BlockCoord) +{ + return a_BlockCoord * 32 + (int)(16 * ((float)r1.rand() * RECI_RAND_MAX) * 16 - 8); +} + + + + + +int cClientHandle::s_ClientCount = 0; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cClientHandle: + +cClientHandle::cClientHandle(const cSocket & a_Socket, int a_ViewDistance) + : m_ViewDistance(a_ViewDistance) + , m_ProtocolVersion(MCS_PROTOCOL_VERSION) + , m_Socket(a_Socket) + , m_bDestroyed(false) + , m_Player(NULL) + , m_bKicking(false) + , m_TimeLastPacket(cWorld::GetTime()) + , m_bKeepThreadGoing(true) + , m_Ping(1000) + , m_State(csConnected) + , m_LastStreamedChunkX(0x7fffffff) // bogus chunk coords to force streaming upon login + , m_LastStreamedChunkZ(0x7fffffff) + , m_UniqueID(0) +{ + s_ClientCount++; // Not protected by CS because clients are always constructed from the same thread + m_UniqueID = s_ClientCount; + + cTimer t1; + m_LastPingTime = t1.GetNowTime(); + + // All the packets that can be received from the client + for (int i = 0; i < ARRAYCOUNT(m_PacketMap); ++i) + { + m_PacketMap[i] = NULL; + } + m_PacketMap[E_KEEP_ALIVE] = new cPacket_KeepAlive; + m_PacketMap[E_HANDSHAKE] = new cPacket_Handshake; + m_PacketMap[E_LOGIN] = new cPacket_Login; + m_PacketMap[E_PLAYERPOS] = new cPacket_PlayerPosition; + m_PacketMap[E_PLAYERLOOK] = new cPacket_PlayerLook; + m_PacketMap[E_PLAYERMOVELOOK] = new cPacket_PlayerMoveLook; + m_PacketMap[E_PLAYER_ABILITIES] = new cPacket_PlayerAbilities; + m_PacketMap[E_CHAT] = new cPacket_Chat; + m_PacketMap[E_ANIMATION] = new cPacket_ArmAnim; + m_PacketMap[E_FLYING] = new cPacket_Flying; + m_PacketMap[E_BLOCK_DIG] = new cPacket_BlockDig; + m_PacketMap[E_BLOCK_PLACE] = new cPacket_BlockPlace; + m_PacketMap[E_DISCONNECT] = new cPacket_Disconnect; + m_PacketMap[E_ITEM_SWITCH] = new cPacket_ItemSwitch; + m_PacketMap[E_ENTITY_EQUIPMENT] = new cPacket_EntityEquipment; + m_PacketMap[E_CREATIVE_INVENTORY_ACTION] = new cPacket_CreativeInventoryAction; + m_PacketMap[E_NEW_INVALID_STATE] = new cPacket_NewInvalidState; + m_PacketMap[E_PICKUP_SPAWN] = new cPacket_PickupSpawn; + m_PacketMap[E_USE_ENTITY] = new cPacket_UseEntity; + m_PacketMap[E_WINDOW_CLOSE] = new cPacket_WindowClose; + m_PacketMap[E_WINDOW_CLICK] = new cPacket_WindowClick; + m_PacketMap[E_PACKET_13] = new cPacket_13; + m_PacketMap[E_UPDATE_SIGN] = new cPacket_UpdateSign; + m_PacketMap[E_RESPAWN] = new cPacket_Respawn; + m_PacketMap[E_PING] = new cPacket_Ping; + + LOG("New ClientHandle created at %p", this); +} + + + + + +cClientHandle::~cClientHandle() +{ + LOG("Deleting client \"%s\" at %p", GetUsername().c_str(), this); + + // Remove from cSocketThreads, we're not to be called anymore: + cRoot::Get()->GetServer()->ClientDestroying(this); + + { + cCSLock Lock(m_CSChunkLists); + m_LoadedChunks.clear(); + m_ChunksToSend.clear(); + } + + if (m_Player != NULL) + { + cWorld * World = m_Player->GetWorld(); + if (!m_Username.empty() && (World != NULL)) + { + // Send the Offline PlayerList packet: + AString NameColor = (m_Player ? m_Player->GetColor() : ""); + cPacket_PlayerListItem PlayerList(NameColor + GetUsername(), false, (short)9999); + World->Broadcast(PlayerList, this); + + // Send the Chat packet: + cPacket_Chat Left(m_Username + " left the game!"); + World->Broadcast(Left, this); + } + if (World != NULL) + { + World->RemovePlayer(m_Player); + } + } + + if (m_Socket.IsValid()) + { + cPacket_Disconnect Disconnect; + Disconnect.m_Reason = "Server shut down? Kthnxbai"; + m_Socket.Send(&Disconnect); + } + + if (m_Player != NULL) + { + m_Player->Destroy(); + m_Player = NULL; + } + for (int i = 0; i < ARRAYCOUNT(m_PacketMap); i++) + { + delete m_PacketMap[i]; + } + + // Queue all remaining outgoing packets to cSocketThreads: + { + cCSLock Lock(m_CSPackets); + for (PacketList::iterator itr = m_PendingNrmSendPackets.begin(); itr != m_PendingNrmSendPackets.end(); ++itr) + { + AString Data; + (*itr)->Serialize(Data); + cRoot::Get()->GetServer()->WriteToClient(&m_Socket, Data); + delete *itr; + } + m_PendingNrmSendPackets.clear(); + for (PacketList::iterator itr = m_PendingLowSendPackets.begin(); itr != m_PendingLowSendPackets.end(); ++itr) + { + AString Data; + (*itr)->Serialize(Data); + cRoot::Get()->GetServer()->WriteToClient(&m_Socket, Data); + delete *itr; + } + m_PendingLowSendPackets.clear(); + } + + // Queue the socket to close as soon as it sends all outgoing data: + cRoot::Get()->GetServer()->QueueClientClose(&m_Socket); + + // We need to remove the socket from SocketThreads because we own it and it gets destroyed after this destructor finishes + // TODO: The socket needs to stay alive, someone else has to own it + cRoot::Get()->GetServer()->RemoveClient(&m_Socket); + + LOG("ClientHandle at %p deleted", this); +} + + + + + +void cClientHandle::Destroy() +{ + // Setting m_bDestroyed was moved to the bottom of Destroy(), + // otherwise the destructor may be called within another thread before the client is removed from chunks + // http://forum.mc-server.org/showthread.php?tid=366 + + if ((m_Player != NULL) && (m_Player->GetWorld() != NULL)) + { + RemoveFromAllChunks(); + m_Player->GetWorld()->RemoveClientFromChunkSender(this); + } + + m_bDestroyed = true; +} + + + + + +void cClientHandle::Kick(const AString & a_Reason) +{ + if (m_State >= csAuthenticating) // Don't log pings + { + LOG("Kicking user \"%s\" for \"%s\"", m_Username.c_str(), a_Reason.c_str()); + } + Send(cPacket_Disconnect(a_Reason)); + m_bKicking = true; +} + + + + + +void cClientHandle::Authenticate(void) +{ + if (m_State != csAuthenticating) + { + return; + } + + ASSERT( m_Player == NULL ); + + // Spawn player (only serversided, so data is loaded) + m_Player = new cPlayer(this, GetUsername()); + + cWorld * World = cRoot::Get()->GetWorld(m_Player->GetLoadedWorldName()); + if (World == NULL) + { + World = cRoot::Get()->GetDefaultWorld(); + } + + m_Player->LoginSetGameMode (World->GetGameMode()); //set player's gamemode to server's gamemode at login. TODO: set to last player's gamemode at logout + + m_Player->SetIP (m_Socket.GetIPString()); + + cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_PLAYER_SPAWN, 1, m_Player); + + // Return a server login packet + cPacket_Login LoginResponse; + LoginResponse.m_ProtocolVersion = m_Player->GetUniqueID(); + //LoginResponse.m_Username = ""; + LoginResponse.m_ServerMode = m_Player->GetGameMode(); // set gamemode from player. + LoginResponse.m_Dimension = 0; + LoginResponse.m_MaxPlayers = (unsigned char)cRoot::Get()->GetDefaultWorld()->GetMaxPlayers(); + LoginResponse.m_Difficulty = 2; + Send(LoginResponse); + + // Send Weather if raining: + if ((World->GetWeather() == 1) || (World->GetWeather() == 2)) + { + cPacket_NewInvalidState RainPacket; + RainPacket.m_Reason = 1; //begin rain + Send(RainPacket); + } + + // Send time + Send(cPacket_TimeUpdate(World->GetWorldTime())); + + // Send inventory + m_Player->GetInventory().SendWholeInventory(this); + + // Send health + cPacket_UpdateHealth Health; + Health.m_Health = (short)m_Player->GetHealth(); + Health.m_Food = m_Player->GetFood(); + Health.m_Saturation = m_Player->GetFoodSaturation(); + Send(Health); + + m_Player->Initialize(World); + StreamChunks(); + m_State = csDownloadingWorld; +} + + + + + +void cClientHandle::StreamChunks(void) +{ + if (m_State < csAuthenticating) + { + return; + } + + ASSERT(m_Player != NULL); + + int ChunkPosX = FAST_FLOOR_DIV(m_Player->GetPosX(), cChunkDef::Width); + int ChunkPosZ = FAST_FLOOR_DIV(m_Player->GetPosZ(), cChunkDef::Width); + if ((ChunkPosX == m_LastStreamedChunkX) && (ChunkPosZ == m_LastStreamedChunkZ)) + { + // Already streamed for this position + return; + } + m_LastStreamedChunkX = ChunkPosX; + m_LastStreamedChunkZ = ChunkPosZ; + + LOGD("Streaming chunks centered on [%d, %d], view distance %d", ChunkPosX, ChunkPosZ, m_ViewDistance); + + cWorld * World = m_Player->GetWorld(); + ASSERT(World != NULL); + + // Remove all loaded chunks that are no longer in range; deferred to out-of-CS: + cChunkCoordsList RemoveChunks; + { + cCSLock Lock(m_CSChunkLists); + for (cChunkCoordsList::iterator itr = m_LoadedChunks.begin(); itr != m_LoadedChunks.end();) + { + int RelX = (*itr).m_ChunkX - ChunkPosX; + int RelZ = (*itr).m_ChunkZ - ChunkPosZ; + if ((RelX > m_ViewDistance) || (RelX < -m_ViewDistance) || (RelZ > m_ViewDistance) || (RelZ < -m_ViewDistance)) + { + RemoveChunks.push_back(*itr); + itr = m_LoadedChunks.erase(itr); + } + else + { + ++itr; + } + } // for itr - m_LoadedChunks[] + for (cChunkCoordsList::iterator itr = m_ChunksToSend.begin(); itr != m_ChunksToSend.end();) + { + int RelX = (*itr).m_ChunkX - ChunkPosX; + int RelZ = (*itr).m_ChunkZ - ChunkPosZ; + if ((RelX > m_ViewDistance) || (RelX < -m_ViewDistance) || (RelZ > m_ViewDistance) || (RelZ < -m_ViewDistance)) + { + itr = m_ChunksToSend.erase(itr); + } + else + { + ++itr; + } + } // for itr - m_ChunksToSend[] + } + for (cChunkCoordsList::iterator itr = RemoveChunks.begin(); itr != RemoveChunks.end(); ++itr) + { + World->RemoveChunkClient(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ, this); + Send(cPacket_PreChunk(itr->m_ChunkX, itr->m_ChunkZ, false)); + } // for itr - RemoveChunks[] + + // Add all chunks that are in range and not yet in m_LoadedChunks: + // Queue these smartly - from the center out to the edge + for (int d = 0; d <= m_ViewDistance; ++d) // cycle through (square) distance, from nearest to furthest + { + // For each distance add chunks in a hollow square centered around current position: + for (int i = -d; i <= d; ++i) + { + StreamChunk(ChunkPosX + d, ZERO_CHUNK_Y, ChunkPosZ + i); + StreamChunk(ChunkPosX - d, ZERO_CHUNK_Y, ChunkPosZ + i); + } // for i + for (int i = -d + 1; i < d; ++i) + { + StreamChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ + d); + StreamChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ - d); + } // for i + } // for d + + // Touch chunks GENERATEDISTANCE ahead to let them generate: + for (int d = m_ViewDistance + 1; d <= m_ViewDistance + GENERATEDISTANCE; ++d) // cycle through (square) distance, from nearest to furthest + { + // For each distance touch chunks in a hollow square centered around current position: + for (int i = -d; i <= d; ++i) + { + World->TouchChunk(ChunkPosX + d, ZERO_CHUNK_Y, ChunkPosZ + i); + World->TouchChunk(ChunkPosX - d, ZERO_CHUNK_Y, ChunkPosZ + i); + } // for i + for (int i = -d + 1; i < d; ++i) + { + World->TouchChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ + d); + World->TouchChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ - d); + } // for i + } // for d +} + + + + +void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cWorld * World = m_Player->GetWorld(); + ASSERT(World != NULL); + + if (World->AddChunkClient(a_ChunkX, a_ChunkY, a_ChunkZ, this)) + { + { + cCSLock Lock(m_CSChunkLists); + m_LoadedChunks.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); + m_ChunksToSend.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); + } + World->SendChunkTo(a_ChunkX, a_ChunkY, a_ChunkZ, this); + } +} + + + + + +// Removes the client from all chunks. Used when switching worlds or destroying the player +void cClientHandle::RemoveFromAllChunks() +{ + cWorld * World = m_Player->GetWorld(); + if (World != NULL) + { + World->RemoveClientFromChunks(this); + } + + { + cCSLock Lock(m_CSChunkLists); + m_LoadedChunks.clear(); + m_ChunksToSend.clear(); + } +} + + + + + +void cClientHandle::HandlePacket(cPacket * a_Packet) +{ + m_TimeLastPacket = cWorld::GetTime(); + + // LOG("Recv packet 0x%02x from client \"%s\" (\"%s\")", a_Packet->m_PacketID, m_Socket.GetIPString().c_str(), m_Username.c_str()); + + if (m_bKicking) + { + return; + } + + switch (m_State) + { + case csConnected: + { + switch (a_Packet->m_PacketID) + { + case E_NEW_INVALID_STATE: // New/Invalid State packet received. I'm guessing the client only sends it when there's a problem with the bed? + { + LOGINFO("Got New Invalid State packet"); + break; + } + case E_PING: HandlePing (); break; + case E_HANDSHAKE: HandleHandshake(reinterpret_cast(a_Packet)); break; + case E_LOGIN: HandleLogin (reinterpret_cast (a_Packet)); break; + + // Ignored packets: + case E_PLAYERLOOK: + case E_CHAT: + case E_PLAYERMOVELOOK: + case E_PLAYERPOS: + case E_KEEP_ALIVE: break; + default: HandleUnexpectedPacket(a_Packet); break; + } // switch (PacketType) + break; + } // case csConnected + + case csAuthenticating: + { + // Waiting for external authentication, no packets are handled + switch (a_Packet->m_PacketID) + { + // Ignored packets: + case E_KEEP_ALIVE: + case E_CHAT: + case E_FLYING: + case E_PLAYERLOOK: + case E_PLAYERMOVELOOK: + case E_PLAYERPOS: break; + + default: HandleUnexpectedPacket(a_Packet); break; + } + break; + } + + case csDownloadingWorld: + { + // Waiting for chunks to stream to client, no packets are handled + switch (a_Packet->m_PacketID) + { + // Ignored packets: + case E_KEEP_ALIVE: + case E_CHAT: + case E_FLYING: + case E_PLAYERLOOK: + case E_PLAYERMOVELOOK: + case E_PLAYERPOS: break; + + default: HandleUnexpectedPacket(a_Packet); break; + } + break; + } + + case csConfirmingPos: + { + switch (a_Packet->m_PacketID) + { + // Ignored packets: + case E_KEEP_ALIVE: + case E_CHAT: + case E_FLYING: + case E_PLAYERLOOK: + case E_PLAYERPOS: break; + + case E_PLAYERMOVELOOK: HandleMoveLookConfirm(reinterpret_cast(a_Packet)); break; + + default: + { + HandleUnexpectedPacket(a_Packet); + break; + } + } // switch (PacketType) + break; + } // case csConfirmingPos + + case csPlaying: + { + switch (a_Packet->m_PacketID) + { + case E_CREATIVE_INVENTORY_ACTION: HandleCreativeInventory(reinterpret_cast(a_Packet)); break; + case E_PLAYERPOS: HandlePlayerPos (reinterpret_cast (a_Packet)); break; + case E_BLOCK_DIG: HandleBlockDig (reinterpret_cast (a_Packet)); break; + case E_BLOCK_PLACE: HandleBlockPlace (reinterpret_cast (a_Packet)); break; + case E_PICKUP_SPAWN: HandlePickupSpawn (reinterpret_cast (a_Packet)); break; + case E_CHAT: HandleChat (reinterpret_cast (a_Packet)); break; + case E_PLAYERLOOK: HandlePlayerLook (reinterpret_cast (a_Packet)); break; + case E_PLAYERMOVELOOK: HandlePlayerMoveLook (reinterpret_cast (a_Packet)); break; + case E_ANIMATION: HandleAnimation (reinterpret_cast (a_Packet)); break; + case E_ITEM_SWITCH: HandleItemSwitch (reinterpret_cast (a_Packet)); break; + case E_WINDOW_CLOSE: HandleWindowClose (reinterpret_cast (a_Packet)); break; + case E_WINDOW_CLICK: HandleWindowClick (reinterpret_cast (a_Packet)); break; + case E_UPDATE_SIGN: HandleUpdateSign (reinterpret_cast (a_Packet)); break; + case E_USE_ENTITY: HandleUseEntity (reinterpret_cast (a_Packet)); break; + case E_RESPAWN: HandleRespawn(); break; + case E_DISCONNECT: HandleDisconnect (reinterpret_cast (a_Packet)); break; + case E_KEEP_ALIVE: HandleKeepAlive (reinterpret_cast (a_Packet)); break; + } // switch (Packet type) + break; + } // case csPlaying + } // switch (m_State) +} + + + + + +void cClientHandle::HandlePing(void) +{ + // Somebody tries to retrieve information about the server + AString Reply; + Printf(Reply, "%s%s%i%s%i", + cRoot::Get()->GetDefaultWorld()->GetDescription().c_str(), + cChatColor::Delimiter.c_str(), + cRoot::Get()->GetDefaultWorld()->GetNumPlayers(), + cChatColor::Delimiter.c_str(), + cRoot::Get()->GetDefaultWorld()->GetMaxPlayers() + ); + Kick(Reply.c_str()); +} + + + + + +void cClientHandle::HandleHandshake(cPacket_Handshake * a_Packet) +{ + AStringVector UserData = StringSplit( a_Packet->m_Username, ";" ); // "FakeTruth;localhost:25565" + if( UserData.size() == 0 ) + { + Kick("Could not receive username"); + return; + } + m_Username = UserData[0]; + + LOG("HANDSHAKE %s", m_Username.c_str()); + + if (cRoot::Get()->GetDefaultWorld()->GetNumPlayers() >= cRoot::Get()->GetDefaultWorld()->GetMaxPlayers()) + { + Kick("The server is currently full :(-- Try again later"); + return; + } + cPacket_Chat Connecting(m_Username + " is connecting."); + cRoot::Get()->GetServer()->Broadcast(Connecting, this); + + cPacket_Handshake Handshake; + Handshake.m_Username = cRoot::Get()->GetServer()->GetServerID(); + Send(Handshake); + LOG("User \"%s\" was sent a handshake", m_Username.c_str()); +} + + + + + +void cClientHandle::HandleLogin(cPacket_Login * a_Packet) +{ + LOG("LOGIN %s", m_Username.c_str()); + if (a_Packet->m_ProtocolVersion < m_ProtocolVersion) + { + Kick("Your client is outdated!"); + return; + } + else if (a_Packet->m_ProtocolVersion > m_ProtocolVersion) + { + Kick("Your client version is higher than the server!"); + return; + } + if (m_Username.compare(a_Packet->m_Username) != 0) + { + LOGWARNING("Login Username (\"%s\") does not match Handshake username (\"%s\") for client \"%s\")", + a_Packet->m_Username.c_str(), + m_Username.c_str(), + m_Socket.GetIPString().c_str() + ); + Kick("Hacked client"); // Don't tell them why we don't want them + return; + } + + if (cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_LOGIN, 1, a_Packet)) + { + Destroy(); + return; + } + + // Schedule for authentication; until then, let them wait (but do not block) + m_State = csAuthenticating; + cRoot::Get()->GetAuthenticator().Authenticate(GetUniqueID(), GetUsername(), cRoot::Get()->GetServer()->GetServerID()); +} + + + + + +void cClientHandle::HandleUnexpectedPacket(cPacket * a_Packet) +{ + LOGWARNING( + "Invalid packet in state %d: 0x%02x from client \"%s\", username \"%s\"", + m_State, + a_Packet->m_PacketID, + m_Socket.GetIPString().c_str(), + m_Username.c_str() + ); + Kick("Hacked client"); // Don't tell them why we don't like them +} + + + + + +void cClientHandle::HandleMoveLookConfirm(cPacket_PlayerMoveLook * a_Packet) +{ + Vector3d ReceivedPosition = Vector3d(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + + // Test the distance between points with a small/large enough value instead of comparing directly. Floating point inaccuracies might screw stuff up + double Dist = (ReceivedPosition - m_ConfirmPosition).SqrLength(); + if (Dist < 1.0) + { + // Test + if (ReceivedPosition.Equals(m_ConfirmPosition)) + { + LOGINFO("Exact position confirmed by client!"); + } + m_State = csPlaying; + } + else + { + LOGWARNING("Player \"%s\" sent a weird position confirmation %.2f blocks away, retrying", m_Username.c_str(), Dist); + m_ConfirmPosition = m_Player->GetPosition(); + Send(cPacket_PlayerMoveLook(m_Player)); + } +} + + + + + +void cClientHandle::HandleCreativeInventory(cPacket_CreativeInventoryAction * a_Packet) +{ + // This is for creative Inventory changes + if (m_Player->GetGameMode() == 1) + { + m_Player->GetInventory().Clicked(a_Packet); + } + else + { + LOGWARNING("Got a CreativeInventoryAction packet from user \"%s\" while not in creative mode. Ignoring.", m_Username.c_str()); + } +} + + + + + +void cClientHandle::HandlePlayerPos(cPacket_PlayerPosition * a_Packet) +{ + // LOG("recv player pos: %0.2f %0.2f %0.2f", PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ); + m_Player->MoveTo(Vector3d(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ)); + m_Player->SetStance(a_Packet->m_Stance); + m_Player->SetTouchGround(a_Packet->m_bFlying); +} + + + + + +void cClientHandle::HandleBlockDig(cPacket_BlockDig * a_Packet) +{ + if (!CheckBlockInteractionsRate()) + { + return; + } + + LOGD("OnBlockDig: {%i, %i, %i} Dir: %i Stat: %i", + a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, + a_Packet->m_Direction, a_Packet->m_Status + ); + + // Do we want plugins to disable tossing items? Probably no, so toss item before asking plugins for permission + if (a_Packet->m_Status == 0x04) // Drop held item + { + m_Player->TossItem(false); + return; + } + + cWorld* World = m_Player->GetWorld(); + BLOCKTYPE OldBlock = World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + NIBBLETYPE OldMeta = World->GetBlockMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + + if (cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_BLOCK_DIG, 4, a_Packet, m_Player, OldBlock, OldMeta)) + { + // The plugin doesn't agree with the digging, replace the block on the client and quit: + World->SendBlockTo(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, m_Player); + return; + } + + bool bBroken = ( + (a_Packet->m_Status == 0x02) || + (g_BlockOneHitDig[(int)OldBlock]) || + ((a_Packet->m_Status == 0x00) && (m_Player->GetGameMode() == 1)) + ); + + if ((OldBlock == E_BLOCK_WOODEN_DOOR) && !bBroken) + { + cDoors::ChangeDoor(m_Player->GetWorld(), a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + } + + cItems PickupItems; + if (bBroken && !(m_Player->GetGameMode() == 1)) // broken + { + cBlockToPickup::ToPickup(OldBlock, OldMeta, m_Player->GetInventory().GetEquippedItem(), PickupItems); + + // Allow plugins to change the dropped objects: + cRoot::Get()->GetPluginManager()->CallHookBlockToPickup(OldBlock, OldMeta, m_Player, m_Player->GetInventory().GetEquippedItem(), PickupItems); + } + + int pX = a_Packet->m_PosX; + unsigned char pY = a_Packet->m_PosY; + int pZ = a_Packet->m_PosZ; + + AddDirection(pX, pY, pZ, a_Packet->m_Direction); + + char PossibleBlock = World->GetBlock(pX, pY, pZ); + + if (PossibleBlock == E_BLOCK_FIRE) + { + a_Packet->m_PosX = pX; + a_Packet->m_PosY = pY; + a_Packet->m_PosZ = pZ; + bBroken = true; + } + + if (!bBroken) + { + return; + } + + if (!World->DigBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ)) + { + return; + } + + World->SpawnItemPickups(PickupItems, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + + switch (OldBlock) + { + case E_BLOCK_REDSTONE_TORCH_ON: + case E_BLOCK_REDSTONE_TORCH_OFF: + case E_BLOCK_REDSTONE_WIRE: + { + cRedstone Redstone(World); + Redstone.ChangeRedstone(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, false); + break; + } + } + + if ((OldBlock == E_BLOCK_PISTON) || (OldBlock == E_BLOCK_STICKY_PISTON)) + { + int newX = a_Packet->m_PosX; + int newY = a_Packet->m_PosY; + int newZ = a_Packet->m_PosZ; + AddPistonDir(newX, newY, newZ, OldMeta & ~(8), 1); + if (World->GetBlock(newX, newY, newZ) == E_BLOCK_PISTON_EXTENSION) + { + World->SetBlock(newX, newY, newZ, E_BLOCK_AIR, 0); + } + } + + if (cDoors::IsDoor(OldBlock)) + { + // Special actions for destroyed door (Destroy second part) + if (OldMeta & 8) + { + // Was upper part of door + if (cDoors::IsDoor(World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY - 1, a_Packet->m_PosZ))) + { + World->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY - 1, a_Packet->m_PosZ, E_BLOCK_AIR, 0); + } + } + else + { + // Was lower part + if (cDoors::IsDoor(World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ))) + { + World->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ, E_BLOCK_AIR, 0); + } + } + } + + m_Player->UseEquippedItem(); +} + + + + + +void cClientHandle::HandleBlockPlace(cPacket_BlockPlace * a_Packet) +{ + if (!CheckBlockInteractionsRate()) + { + return; + } + + cItem & Equipped = m_Player->GetInventory().GetEquippedItem(); + + if ((Equipped.m_ItemID != a_Packet->m_ItemType)) // Not valid + { + LOGWARN("Player %s tried to place a block that was not equipped (exp %d, got %d)", + m_Username.c_str(), Equipped.m_ItemID, a_Packet->m_ItemType + ); + // TODO: We should probably send the current world block to the client, so that it can immediately "let the user know" that they haven't placed the block + return; + } + + if (cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_BLOCK_PLACE, 2, a_Packet, m_Player)) + { + if (a_Packet->m_Direction > -1) + { + AddDirection(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_Direction); + m_Player->GetWorld()->SendBlockTo(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, m_Player); + } + return; + } + + //LOG("%i %i %i %i %i %i", a_Packet->m_Count, a_Packet->m_Direction, a_Packet->m_ItemType, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + + //printf("Place Dir:%i %i %i %i : %i\n", a_Packet->m_Direction, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_ItemType); + // 'use' useable items instead of placing blocks + bool bPlaceBlock = true; + bool UpdateRedstone = false; + bool AddedCurrent = false; + + if (a_Packet->m_Direction >= 0) + { + cWorld * World = m_Player->GetWorld(); + BLOCKTYPE BlockType = 0; + NIBBLETYPE BlockMeta; + World->GetBlockTypeMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, BlockType, BlockMeta); + switch (BlockType) + { + case E_BLOCK_REDSTONE_REPEATER_ON: + case E_BLOCK_REDSTONE_REPEATER_OFF: + { + // no need to update redstone current with a repeater + // Find meta value of repeater and change it to one step more: + World->FastSetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, BlockType, ((BlockMeta + 0x04) & 0x0f)); + bPlaceBlock = false; + break; + } + + case E_BLOCK_WORKBENCH: + { + bPlaceBlock = false; + cWindow* Window = new cCraftingWindow(0, true); + m_Player->OpenWindow(Window); + break; + } + + case E_BLOCK_FURNACE: + case E_BLOCK_CHEST: + { + bPlaceBlock = false; + m_Player->GetWorld()->UseBlockEntity(m_Player, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + break; + } + + case E_BLOCK_WOODEN_DOOR: + { + bPlaceBlock = false; + cDoors::ChangeDoor(m_Player->GetWorld(), a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + break; + } + + default: + { + break; + } + } // switch (BlockID) + } // if (Direction >= 0) + + // Some checks to see if it's a placeable item :P + if (bPlaceBlock) + { + cItem Item; + Item.m_ItemID = Equipped.m_ItemID; + Item.m_ItemCount = 1; + LOGD("Placing item of type %i at {%d, %d, %d}", + (int)a_Packet->m_ItemType, + a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ + ); + + if (m_Player->EatItem(Item.m_ItemID)) + { + m_Player->GetInventory().RemoveItem(Item); + return; + } + + if (a_Packet->m_Direction < 0) + { + // clicked in air + return; + } + bool isDoor = false; + + //TODO: Wrong Blocks! + BLOCKTYPE ClickedBlock = m_Player->GetWorld()->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + + if (ItemCategory::IsHoe(Item.m_ItemID)) + { + if ((ClickedBlock == E_BLOCK_DIRT) || (ClickedBlock == E_BLOCK_GRASS)) + { + m_Player->GetWorld()->FastSetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, E_BLOCK_FARMLAND, 0); + } + return; + } + + NIBBLETYPE MetaData = (NIBBLETYPE)Equipped.m_ItemHealth; // This generally works for logs & planks, others will override + bool LavaBucket = false; + bool WaterBucket = false; + bool bRemoveItem = true; + bool bIgnoreCollision = false; + + if (ClickedBlock == E_BLOCK_STEP) + { + // Only make double slab if meta values are the same and if player clicked either on top or on bottom of the block (direction either 0 or 1) + // TODO check if it works from beneath + if (MetaData == ( m_Player->GetWorld()->GetBlockMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ) & 0x7) && a_Packet->m_Direction <= 1) + //if (MetaData == m_Player->GetWorld()->GetBlockMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ) && a_Packet->m_Direction == 1) + { + a_Packet->m_ItemType = E_BLOCK_DOUBLE_STEP; + if(a_Packet->m_Direction == 1) + { + a_Packet->m_PosY--; + } + else + { + a_Packet->m_PosY++; + } + bIgnoreCollision = true; + } + } + + // Special handling for special items: + switch (a_Packet->m_ItemType) + { + case E_ITEM_BUCKET: + { + // TODO: Change this, it is just a small hack to get it working a little bit. seems like the Client sends the position from the first hitable block :s + ClickedBlock = (int)m_Player->GetWorld()->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ); + LOG("Bucket Clicked BlockID: %d", ClickedBlock); + switch (ClickedBlock) + { + case E_BLOCK_WATER: + case E_BLOCK_STATIONARY_WATER: + { + WaterBucket = true; + break; + } + case E_BLOCK_LAVA: + case E_BLOCK_STATIONARY_LAVA: + { + LavaBucket = true; + break; + } + } + break; + } // case E_ITEM_BUCKET + + case E_ITEM_LAVA_BUCKET: + { + if ((m_Player->GetGameMode() == 1) || (m_Player->GetInventory().RemoveItem(Item))) + { + a_Packet->m_ItemType = E_BLOCK_LAVA; + if (m_Player->GetGameMode() == 1) + { + break; //No new Bucket for creative players + } + + cItem NewItem; + NewItem.m_ItemID = E_ITEM_BUCKET; + NewItem.m_ItemCount = 1; + m_Player->GetInventory().AddItem(NewItem); + } + break; + } // case E_ITEM_LAVA_BUCKET + + case E_ITEM_WATER_BUCKET: + { + if ((m_Player->GetGameMode() == 1) || (m_Player->GetInventory().RemoveItem(Item))) + { + a_Packet->m_ItemType = E_BLOCK_WATER; + if (m_Player->GetGameMode() == 1) + { + break; //No new Bucket for creative players + } + cItem NewItem; + NewItem.m_ItemID = E_ITEM_BUCKET; + NewItem.m_ItemCount = 1; + m_Player->GetInventory().AddItem(NewItem); + } + break; + } + + case E_BLOCK_TORCH: + { + MetaData = cTorch::DirectionToMetaData(a_Packet->m_Direction); + break; + } + + case E_BLOCK_REDSTONE_TORCH_OFF: + { + MetaData = cTorch::DirectionToMetaData(a_Packet->m_Direction); + if (g_BlockTransparent[ (int)m_Player->GetWorld()->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY+2, a_Packet->m_PosZ) ] == true) + { + //if block above is transparent + //printf("transparent above me\n"); + } + else + { + //printf("transparent not above me\n"); + } + UpdateRedstone = true; + AddedCurrent = false; + break; + } + + case E_BLOCK_REDSTONE_TORCH_ON: + { + MetaData = cTorch::DirectionToMetaData(a_Packet->m_Direction); + UpdateRedstone = true; + AddedCurrent = true; + break; + } + + case E_ITEM_REDSTONE_DUST: + { + MetaData = 0; + a_Packet->m_ItemType = E_BLOCK_REDSTONE_WIRE; + UpdateRedstone = true; + AddedCurrent = false; + break; + } + + case E_ITEM_REDSTONE_REPEATER: + { + MetaData = cRedstone::RepeaterRotationToMetaData(m_Player->GetRotation()); + a_Packet->m_ItemType = E_BLOCK_REDSTONE_REPEATER_OFF; + UpdateRedstone = true; + AddedCurrent = false; + break; + } + + case E_BLOCK_PISTON: + case E_BLOCK_STICKY_PISTON: + { + MetaData = cPiston::RotationPitchToMetaData(m_Player->GetRotation(), m_Player->GetPitch()); + UpdateRedstone = true; + AddedCurrent = false; + break; + } + + case E_ITEM_IRON_DOOR: + { + a_Packet->m_ItemType = E_BLOCK_IRON_DOOR; + MetaData = cDoors::RotationToMetaData(m_Player->GetRotation()); + isDoor = true; + break; + } + + case E_ITEM_WOODEN_DOOR: + { + a_Packet->m_ItemType = E_BLOCK_WOODEN_DOOR; + MetaData = cDoors::RotationToMetaData(m_Player->GetRotation()); + isDoor = true; + break; + } + + case E_BLOCK_CHEST: + case E_BLOCK_FURNACE: + case E_BLOCK_DISPENSER: + { + MetaData = cPiston::RotationPitchToMetaData(m_Player->GetRotation(), 0); // Same orientation as pistons, just ignore pitch + break; + } + + case E_BLOCK_STEP: + { + MetaData += cStep::DirectionToMetaData( a_Packet->m_Direction ); + break; + } + + case E_BLOCK_COBBLESTONE_STAIRS: + case E_BLOCK_BRICK_STAIRS: + case E_BLOCK_STONE_BRICK_STAIRS: + case E_BLOCK_NETHER_BRICK_STAIRS: + case E_BLOCK_WOODEN_STAIRS: + { + MetaData = cStairs::RotationToMetaData(m_Player->GetRotation(), a_Packet->m_Direction); + break; + } + case E_BLOCK_LADDER: + { + MetaData = cLadder::DirectionToMetaData(a_Packet->m_Direction); + break; + } + case E_ITEM_SIGN: + { + LOGD("Sign Dir: %i", a_Packet->m_Direction); + if (a_Packet->m_Direction == 1) + { + LOGD("Player Rotation: %f", m_Player->GetRotation()); + MetaData = cSign::RotationToMetaData(m_Player->GetRotation()); + LOGD("Sign rotation %i", MetaData); + a_Packet->m_ItemType = E_BLOCK_SIGN_POST; + } + else + { + MetaData = cSign::DirectionToMetaData(a_Packet->m_Direction); + a_Packet->m_ItemType = E_BLOCK_WALLSIGN; + } + break; + } + + case E_ITEM_FLINT_AND_STEEL: + { + a_Packet->m_ItemType = E_ITEM_FIRE; + m_Player->UseEquippedItem(); + bRemoveItem = false; + break; + } + case E_ITEM_SEEDS: + { + if (ClickedBlock != E_BLOCK_FARMLAND) + { + return; + } + a_Packet->m_ItemType = E_BLOCK_CROPS; + break; + } + case E_ITEM_MELON_SEEDS: + { + if (ClickedBlock != E_BLOCK_FARMLAND) + { + return; + } + a_Packet->m_ItemType = E_BLOCK_MELON_STEM; + break; + } + case E_ITEM_PUMPKIN_SEEDS: + { + if (ClickedBlock != E_BLOCK_FARMLAND) + { + return; + } + a_Packet->m_ItemType = E_BLOCK_PUMPKIN_STEM; + break; + } + case E_ITEM_DYE: + { + // Handle bonemeal and dyes on sheep + if (HandleDyes(a_Packet)) + { + if (m_Player->GetGameMode() == eGameMode_Survival) + { + m_Player->GetInventory().RemoveItem(Item); + } + return; + } + break; + } + case E_ITEM_SUGARCANE: + { + a_Packet->m_ItemType = E_BLOCK_SUGARCANE; + break; + } + default: + { + break; + } + } // switch (a_Packet->m_ItemType) + + + if (LavaBucket) + { + if ((m_Player->GetGameMode() == 1) || (m_Player->GetInventory().RemoveItem(Item))) { + cItem NewItem; + NewItem.m_ItemID = E_ITEM_LAVA_BUCKET; + NewItem.m_ItemCount = 1; + m_Player->GetInventory().AddItem(NewItem); + m_Player->GetWorld()->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ, E_BLOCK_AIR, 0); + } + } + else if (WaterBucket) + { + if ((m_Player->GetGameMode() == 1) || (m_Player->GetInventory().RemoveItem(Item))) + { + cItem NewItem; + NewItem.m_ItemID = E_ITEM_WATER_BUCKET; + NewItem.m_ItemCount = 1; + m_Player->GetInventory().AddItem(NewItem); + m_Player->GetWorld()->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ, E_BLOCK_AIR, 0); + } + } + else if (IsValidBlock(a_Packet->m_ItemType)) + { + int X = a_Packet->m_PosX; + int Y = a_Packet->m_PosY; + int Z = a_Packet->m_PosZ; + AddDirection(X, Y, Z, a_Packet->m_Direction); + + int PlaceBlock = m_Player->GetWorld()->GetBlock(X, Y, Z); + if ( + (PlaceBlock != E_BLOCK_AIR) + && (PlaceBlock != E_BLOCK_WATER) + && (PlaceBlock != E_BLOCK_STATIONARY_WATER) + && (PlaceBlock != E_BLOCK_LAVA) + && (PlaceBlock != E_BLOCK_STATIONARY_LAVA) + && !bIgnoreCollision + ) + { + //tried to place a block *into* another? + return; // happens when you place a block aiming at side of block like torch or stem + } + + // Check whether selected item is allowed to be placed on specific surface + if (!m_Player->GetWorld()->IsPlacingItemLegal(a_Packet->m_ItemType, X, Y, Z)) + { + // If we don't send the block, MC is happy placing cacti underwater: + m_Player->GetWorld()->SendBlockTo(X, Y, Z, m_Player); + return; + } + + if (bRemoveItem) + { + if ((m_Player->GetGameMode() != 1) && !m_Player->GetInventory().RemoveItem(Item)) + { + return; + } + } + + + if (isDoor) + { + if ((m_Player->GetWorld()->GetBlock(X, Y + 1, Z) == E_BLOCK_AIR) || (m_Player->GetWorld()->GetBlock(X, Y + 1, Z) == E_BLOCK_AIR)) + { + m_Player->GetWorld()->SetBlock(X, Y + 1, Z, (char)a_Packet->m_ItemType, MetaData + 8); + m_Player->GetWorld()->SetBlock(X, Y, Z, (char)a_Packet->m_ItemType, MetaData); + } + } + else + { + m_Player->GetWorld()->SetBlock(X, Y, Z, (char)a_Packet->m_ItemType, MetaData); + } + + if (UpdateRedstone) + { + cRedstone Redstone(m_Player->GetWorld()); + Redstone.ChangeRedstone(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ, AddedCurrent); + } + } + } + + /* + // FakeTruth's "magic stick of removal" :D + // TODO: Turn this into a plugin + if (m_Username.compare("FakeTruth") == 0) + { + if (a_Packet->m_ItemType == 280) + { + cRoot::Get()->GetWorld()->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, 0, 0); + } + } + */ +} + + + + + +void cClientHandle::HandlePickupSpawn(cPacket_PickupSpawn * a_Packet) +{ + LOG("Received packet E_PICKUP_SPAWN"); + + cItem DroppedItem; + DroppedItem.m_ItemID = (ENUM_ITEM_ID)a_Packet->m_Item; + DroppedItem.m_ItemCount = a_Packet->m_Count; + DroppedItem.m_ItemHealth = 0x0; // TODO: Somehow figure out what item was dropped, and apply correct health + if (m_Player->GetInventory().RemoveItem(DroppedItem)) + { + cPickup * Pickup = new cPickup(a_Packet); + Pickup->Initialize(m_Player->GetWorld()); + } +} + + + + + +void cClientHandle::HandleChat(cPacket_Chat * a_Packet) +{ + if (!cRoot::Get()->GetServer()->Command(*this, a_Packet->m_Message.c_str())) + { + a_Packet->m_Message.insert(0, "<" + m_Player->GetColor() + m_Username + cChatColor::White + "> "); + cRoot::Get()->GetServer()->Broadcast(*a_Packet); + } +} + + + + + +void cClientHandle::HandlePlayerLook(cPacket_PlayerLook * a_Packet) +{ + m_Player->SetRotation (a_Packet->m_Rotation); + m_Player->SetPitch (a_Packet->m_Pitch); + m_Player->SetTouchGround(a_Packet->m_bFlying); + m_Player->WrapRotation(); +} + + + + + +void cClientHandle::HandlePlayerMoveLook(cPacket_PlayerMoveLook * a_Packet) +{ + m_Player->MoveTo(Vector3d(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ)); + m_Player->SetStance (a_Packet->m_Stance); + m_Player->SetTouchGround(a_Packet->m_bFlying); + m_Player->SetRotation (a_Packet->m_Rotation); + m_Player->SetPitch (a_Packet->m_Pitch); + m_Player->WrapRotation(); +} + + + + + +void cClientHandle::HandleAnimation(cPacket_ArmAnim * a_Packet) +{ + a_Packet->m_EntityID = m_Player->GetUniqueID(); + cRoot::Get()->GetServer()->Broadcast(*a_Packet, this); +} + + + + + +void cClientHandle::HandleItemSwitch(cPacket_ItemSwitch * a_Packet) +{ + m_Player->GetInventory().SetEquippedSlot(a_Packet->m_SlotNum); + + cPacket_EntityEquipment Equipment; + Equipment.m_ItemID = (short)m_Player->GetInventory().GetEquippedItem().m_ItemID; + Equipment.m_Slot = 0; + Equipment.m_UniqueID = m_Player->GetUniqueID(); + cRoot::Get()->GetServer()->Broadcast(Equipment, this); +} + + + + + +void cClientHandle::HandleWindowClose(cPacket_WindowClose * a_Packet) +{ + m_Player->CloseWindow(a_Packet->m_Close); +} + + + + + +void cClientHandle::HandleWindowClick(cPacket_WindowClick * a_Packet) +{ + if (a_Packet->m_WindowID == 0) + { + m_Player->GetInventory().Clicked(a_Packet); + return; + } + + cWindow * Window = m_Player->GetWindow(); + if (Window == NULL) + { + LOGWARNING("Player \"%s\" clicked in a non-existent window. Ignoring", m_Username.c_str()); + return; + } + + Window->Clicked(a_Packet, *m_Player); +} + + + + + +void cClientHandle::HandleUpdateSign(cPacket_UpdateSign * a_Packet) +{ + cWorld * World = m_Player->GetWorld(); + World->UpdateSign(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_Line1, a_Packet->m_Line2, a_Packet->m_Line3, a_Packet->m_Line4); +} + + + + + +void cClientHandle::HandleUseEntity(cPacket_UseEntity * a_Packet) +{ + if (!a_Packet->m_bLeftClick) + { + return; + } + + class cDamageEntity : public cEntityCallback + { + virtual bool Item(cEntity * a_Entity) override + { + if( a_Entity->IsA("cPawn") ) + { + reinterpret_cast< cPawn* >( a_Entity )->TakeDamage(Damage, Instigator ); + } + return true; + } + public: + int Damage; + cEntity * Instigator; + } Callback; + + Callback.Damage = 1; // TODO: Find proper damage from current item equipped + Callback.Instigator = m_Player; + + cWorld * World = m_Player->GetWorld(); + World->DoWithEntity( a_Packet->m_TargetID, Callback ); +} + + + + + +void cClientHandle::HandleRespawn(void) +{ + m_Player->Respawn(); +} + + + + + +void cClientHandle::HandleDisconnect(cPacket_Disconnect * a_Packet) +{ + LOG("Received d/c packet from \"%s\"", m_Username.c_str()); + if (!cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_DISCONNECT, 2, a_Packet->m_Reason.c_str(), m_Player)) + { + cPacket_Chat DisconnectMessage(m_Username + " disconnected: " + a_Packet->m_Reason); + cRoot::Get()->GetServer()->Broadcast(DisconnectMessage); + } + Destroy(); +} + + + + + +void cClientHandle::HandleKeepAlive(cPacket_KeepAlive * a_Packet) +{ + if (a_Packet->m_KeepAliveID == m_PingID) + { + cTimer t1; + m_Ping = (short)((t1.GetNowTime() - m_PingStartTime) / 2); + } +} + + + + + +bool cClientHandle::HandleDyes(cPacket_BlockPlace * a_Packet) +{ + cItem & Equipped = m_Player->GetInventory().GetEquippedItem(); + + // TODO: Handle coloring the sheep, too + + // Handle growing the plants: + if (Equipped.m_ItemHealth == E_META_DYE_WHITE) + { + cWorld * World = m_Player->GetWorld(); + return World->GrowPlant(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, true); + } + + return false; +} + + + + + +bool cClientHandle::CheckBlockInteractionsRate(void) +{ + ASSERT(m_Player != NULL); + ASSERT(m_Player->GetWorld() != NULL); + int LastActionCnt = m_Player->GetLastBlockActionCnt(); + if ((m_Player->GetWorld()->GetTime() - m_Player->GetLastBlockActionTime()) < 0.1) + { + // Limit the number of block interactions per tick + m_Player->SetLastBlockActionTime(); //Player tried to interact with a block. Reset last block interation time. + m_Player->SetLastBlockActionCnt(LastActionCnt + 1); + if (m_Player->GetLastBlockActionCnt() > MAXBLOCKCHANGEINTERACTIONS) + { + // Kick if more than MAXBLOCKCHANGEINTERACTIONS per tick + LOGWARN("Player %s tried to interact with a block too quickly! (could indicate bot) Was Kicked.", m_Username.c_str()); + Kick("You're a baaaaaad boy!"); + return false; + } + } + else + { + m_Player->SetLastBlockActionCnt(0); // Reset count + m_Player->SetLastBlockActionTime(); // Player tried to interact with a block. Reset last block interation time. + } + return true; +} + + + + + +void cClientHandle::Tick(float a_Dt) +{ + (void)a_Dt; + if (cWorld::GetTime() - m_TimeLastPacket > 30.f) // 30 seconds time-out + { + cPacket_Disconnect DC("Nooooo!! You timed out! D: Come back!"); + m_Socket.Send(&DC); + + // TODO: Cannot sleep in the tick thread! + cSleep::MilliSleep(1000); // Give packet some time to be received + + Destroy(); + } + + cTimer t1; + // Send ping packet + if (m_LastPingTime + cClientHandle::PING_TIME_MS <= t1.GetNowTime()) + { + m_PingID++; + cPacket_KeepAlive Ping(m_PingID); + m_PingStartTime = t1.GetNowTime(); + Send(Ping); + m_LastPingTime = m_PingStartTime; + } +} + + + + + +void cClientHandle::Send(const cPacket & a_Packet, ENUM_PRIORITY a_Priority /* = E_PRIORITY_NORMAL */) +{ + if (m_bKicking) return; // Don't add more packets if player is getting kicked anyway + + // If it is the packet spawning myself for myself, drop it silently: + if (a_Packet.m_PacketID == E_NAMED_ENTITY_SPAWN) + { + if (((cPacket_NamedEntitySpawn &)a_Packet).m_UniqueID == m_Player->GetUniqueID()) + { + return; + } + } + + // Filter out packets that don't belong to a csDownloadingWorld state: + if (m_State == csDownloadingWorld) + { + switch (a_Packet.m_PacketID) + { + case E_PLAYERMOVELOOK: + case E_KEEP_ALIVE: + case E_PRE_CHUNK: + case E_MAP_CHUNK: + { + // Allow + break; + } + default: return; + } + } + + // Filter out map chunks that the client doesn't want anymore: + if (a_Packet.m_PacketID == E_MAP_CHUNK) + { + // Check chunks being sent, erase them from m_ChunksToSend: + int ChunkX = ((cPacket_MapChunk &)a_Packet).m_PosX; + int ChunkZ = ((cPacket_MapChunk &)a_Packet).m_PosZ; + bool Found = false; + cCSLock Lock(m_CSChunkLists); + for (cChunkCoordsList::iterator itr = m_ChunksToSend.begin(); itr != m_ChunksToSend.end(); ++itr) + { + if ((itr->m_ChunkX == ChunkX) && (itr->m_ChunkZ == ChunkZ)) + { + m_ChunksToSend.erase(itr); + CheckIfWorldDownloaded(); + Found = true; + break; + } + } // for itr - m_ChunksToSend[] + if (!Found) + { + // This just sometimes happens. If you have a reliably replicatable situation for this, go ahead and fix it + // It's not a big issue anyway, just means that some chunks may be compressed several times + // LOGD("Refusing to send chunk [%d, %d] to client \"%s\" at [%d, %d].", ChunkX, ChunkZ, m_Username.c_str(), m_Player->GetChunkX(), m_Player->GetChunkZ()); + return; + } + } + + // Filter out pre chunks that the client doesn't want anymore: + if ((a_Packet.m_PacketID == E_PRE_CHUNK) && ((cPacket_PreChunk &)a_Packet).m_bLoad) + { + int ChunkX = ((cPacket_PreChunk &)a_Packet).m_PosX; + int ChunkZ = ((cPacket_PreChunk &)a_Packet).m_PosZ; + bool Found = false; + cCSLock Lock(m_CSChunkLists); + for (cChunkCoordsList::iterator itr = m_ChunksToSend.begin(); itr != m_ChunksToSend.end(); ++itr) + { + if ((itr->m_ChunkX == ChunkX) && (itr->m_ChunkZ == ChunkZ)) + { + Found = true; + break; + } + } // for itr - m_ChunksToSend[] + if (!Found) + { + // This just sometimes happens. If you have a reliably replicatable situation for this, go ahead and fix it + // It's not a big issue anyway, just means that some chunks may be compressed several times + // LOGD("Refusing to send PREchunk [%d, %d] to client \"%s\" at [%d, %d].", ChunkX, ChunkZ, m_Username.c_str(), m_Player->GetChunkX(), m_Player->GetChunkZ()); + return; + } + } + + // Optimize away multiple queued RelativeEntityMoveLook packets: + cCSLock Lock(m_CSPackets); + if (a_Priority == E_PRIORITY_NORMAL) + { + if (a_Packet.m_PacketID == E_REL_ENT_MOVE_LOOK) + { + PacketList & Packets = m_PendingNrmSendPackets; + const cPacket_RelativeEntityMoveLook & ThisPacketData = reinterpret_cast< const cPacket_RelativeEntityMoveLook &>(a_Packet); + for (PacketList::iterator itr = Packets.begin(); itr != Packets.end(); ++itr) + { + bool bBreak = false; + switch ((*itr)->m_PacketID) + { + case E_REL_ENT_MOVE_LOOK: + { + cPacket_RelativeEntityMoveLook * PacketData = reinterpret_cast< cPacket_RelativeEntityMoveLook *>(*itr); + if (ThisPacketData.m_UniqueID == PacketData->m_UniqueID) + { + Packets.erase(itr); + bBreak = true; + delete PacketData; + break; + } + break; + } // case E_REL_END_MOVE_LOOK + } // switch (*itr -> Packet type) + if (bBreak) + { + break; + } + } // for itr - Packets[] + } // if (E_REL_ENT_MOVE_LOOK + m_PendingNrmSendPackets.push_back(a_Packet.Clone()); + } + else if (a_Priority == E_PRIORITY_LOW) + { + m_PendingLowSendPackets.push_back(a_Packet.Clone()); + } + Lock.Unlock(); + + // Notify SocketThreads that we have something to write: + cRoot::Get()->GetServer()->NotifyClientWrite(this); +} + + + + + +void cClientHandle::CheckIfWorldDownloaded(void) +{ + if (m_State != csDownloadingWorld) + { + return; + } + cCSLock Lock(m_CSChunkLists); + if (m_ChunksToSend.empty()) + { + SendConfirmPosition(); + } +} + + + + + +void cClientHandle::SendConfirmPosition(void) +{ + LOG("Spawning player \"%s\" at {%.2f, %.2f, %.2f}", + m_Username.c_str(), m_Player->GetPosX(), m_Player->GetPosY(), m_Player->GetPosZ() + ); + + m_State = csConfirmingPos; + + if (!cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_PLAYER_JOIN, 1, m_Player)) + { + // Broadcast that this player has joined the game! Yay~ + cPacket_Chat Joined(m_Username + " joined the game!"); + cRoot::Get()->GetServer()->Broadcast(Joined, this); + } + + m_ConfirmPosition = m_Player->GetPosition(); + Send(cPacket_PlayerMoveLook(m_Player)); +} + + + + + +const AString & cClientHandle::GetUsername(void) const +{ + return m_Username; +} + + + + + +void cClientHandle::SetViewDistance(int a_ViewDistance) +{ + if (a_ViewDistance < MIN_VIEW_DISTANCE) + { + a_ViewDistance = MIN_VIEW_DISTANCE; + } + if (a_ViewDistance > MAX_VIEW_DISTANCE) + { + a_ViewDistance = MAX_VIEW_DISTANCE; + } + m_ViewDistance = a_ViewDistance; + + // Need to re-stream chunks for the change to become apparent: + StreamChunks(); +} + + + + + +bool cClientHandle::WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSChunkLists); + return (std::find(m_ChunksToSend.begin(), m_ChunksToSend.end(), cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)) != m_ChunksToSend.end()); +} + + + + + +void cClientHandle::AddWantedChunk(int a_ChunkX, int a_ChunkZ) +{ + LOGD("Adding chunk [%d, %d] to wanted chunks for client %p", a_ChunkX, a_ChunkZ, this); + cCSLock Lock(m_CSChunkLists); + if (std::find(m_ChunksToSend.begin(), m_ChunksToSend.end(), cChunkCoords(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ)) == m_ChunksToSend.end()) + { + m_ChunksToSend.push_back(cChunkCoords(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ)); + } +} + + + + + +void cClientHandle::DataReceived(const char * a_Data, int a_Size) +{ + // Data is received from the client + + m_ReceivedData.append(a_Data, a_Size); + + // Parse and handle all complete packets in m_ReceivedData: + while (!m_ReceivedData.empty()) + { + cPacket* pPacket = m_PacketMap[(unsigned char)m_ReceivedData[0]]; + if (pPacket == NULL) + { + LOGERROR("Unknown packet type 0x%02x from client \"%s\"", (unsigned char)m_ReceivedData[0], m_Username.c_str()); + + AString Reason; + Printf(Reason, "[C->S] Unknown PacketID: 0x%02x", (unsigned char)m_ReceivedData[0]); + cPacket_Disconnect DC(Reason); + m_Socket.Send(&DC); + cSleep::MilliSleep(1000); // Give packet some time to be received + Destroy(); + return; + } + + int NumBytes = pPacket->Parse(m_ReceivedData.data() + 1, m_ReceivedData.size() - 1); + if (NumBytes == PACKET_ERROR) + { + LOGERROR("Protocol error while parsing packet type 0x%02x; disconnecting client \"%s\"", (unsigned char)m_ReceivedData[0], m_Username.c_str()); + cPacket_Disconnect DC("Protocol error"); + m_Socket.Send(&DC); + cSleep::MilliSleep(1000); // Give packet some time to be received + Destroy(); + return; + } + else if (NumBytes == PACKET_INCOMPLETE) + { + // Not a complete packet + break; + } + else + { + // Packet parsed successfully, add it to internal queue: + HandlePacket(pPacket); + // Erase the packet from the buffer: + ASSERT(m_ReceivedData.size() > (size_t)NumBytes); + m_ReceivedData.erase(0, NumBytes + 1); + } + } // while (!Received.empty()) +} + + + + + +void cClientHandle::GetOutgoingData(AString & a_Data) +{ + // Data can be sent to client + + cCSLock Lock(m_CSPackets); + if (m_PendingNrmSendPackets.size() + m_PendingLowSendPackets.size() > MAX_OUTGOING_PACKETS) + { + LOGERROR("ERROR: Too many packets in queue for player %s !!", m_Username.c_str()); + cPacket_Disconnect DC("Too many packets in queue."); + m_Socket.Send(DC); + + // DEBUG: Dump all outstanding packets' types to the log: + int Idx = 0; + int ChunkX = m_Player->GetChunkX(); + int ChunkZ = m_Player->GetChunkZ(); + for (PacketList::const_iterator itr = m_PendingNrmSendPackets.begin(); itr != m_PendingNrmSendPackets.end(); ++itr) + { + switch ((*itr)->m_PacketID) + { + case E_MAP_CHUNK: + { + int x = ((cPacket_MapChunk *)(*itr))->m_PosX; + int z = ((cPacket_MapChunk *)(*itr))->m_PosZ; + bool IsWanted = (abs(x - ChunkX) <= m_ViewDistance) && (abs(z - ChunkZ) <= m_ViewDistance); + LOG("Packet %4d: type %2x (MapChunk: %d, %d, %s)", + Idx++, (*itr)->m_PacketID, + x, z, + IsWanted ? "wanted" : "unwanted" + ); + break; + } + + case E_PRE_CHUNK: + { + int x = ((cPacket_PreChunk *)(*itr))->m_PosX; + int z = ((cPacket_PreChunk *)(*itr))->m_PosZ; + bool IsWanted = (abs(x - ChunkX) <= m_ViewDistance) && (abs(z - ChunkZ) <= m_ViewDistance); + bool Loading = ((cPacket_PreChunk *)(*itr))->m_bLoad; + LOG("Packet %4d: type %2x (PreChunk: %d, %d, %s, %s)", + Idx++, (*itr)->m_PacketID, + x, z, + Loading ? "loading" : "unloading", + IsWanted ? "wanted" : "unwanted" + ); + break; + } + + case E_BLOCK_CHANGE: + { + int x = ((cPacket_BlockChange *)(*itr))->m_PosX; + int z = ((cPacket_BlockChange *)(*itr))->m_PosZ; + char ToBlock = ((cPacket_BlockChange *)(*itr))->m_BlockType; + int y, cx, cz; + cChunkDef::AbsoluteToRelative(x, y, z, cx, cz); + bool IsWanted = (abs(cx - ChunkX) <= m_ViewDistance) && (abs(cz - ChunkZ) <= m_ViewDistance); + LOG("Packet %4d: type %2x (BlockChange: [%d, %d], %s chunk; to block %d)", + Idx++, (*itr)->m_PacketID, + cx, cz, + IsWanted ? "wanted" : "unwanted", + ToBlock + ); + break; + } + + case E_MULTI_BLOCK: + { + int cx = ((cPacket_MultiBlock *)(*itr))->m_ChunkX; + int cz = ((cPacket_MultiBlock *)(*itr))->m_ChunkZ; + int NumBlocks = ((cPacket_MultiBlock *)(*itr))->m_NumBlocks; + bool IsWanted = (abs(cx - ChunkX) <= m_ViewDistance) && (abs(cz - ChunkZ) <= m_ViewDistance); + LOG("Packet %4d: type %2x (MultiBlock: [%d, %d], %s chunk, %d blocks)", + Idx++, (*itr)->m_PacketID, + cx, cz, + IsWanted ? "wanted" : "unwanted", + NumBlocks + ); + break; + } + + default: + { + LOG("Packet %4d: type %2x", Idx++, (*itr)->m_PacketID); + break; + } + } + } + + Lock.Unlock(); + Destroy(); + return; + } + + if ((m_PendingNrmSendPackets.size() == 0) && (m_PendingLowSendPackets.size() == 0)) + { + return; + } + + if (m_PendingNrmSendPackets.size() > MAX_OUTGOING_PACKETS / 2) + { + LOGINFO("Suspiciously many pending packets: %i; client \"%s\", LastType: 0x%02x", m_PendingNrmSendPackets.size(), m_Username.c_str(), (*m_PendingNrmSendPackets.rbegin())->m_PacketID); + } + + AString Data; + Data.reserve(1100); + // Serialize normal-priority packets up to 1000 bytes + while (!m_PendingNrmSendPackets.empty() && (Data.size() < 1000)) + { + m_PendingNrmSendPackets.front()->Serialize(Data); + delete m_PendingNrmSendPackets.front(); + m_PendingNrmSendPackets.erase(m_PendingNrmSendPackets.begin()); + } + // Serialize one low-priority packet: + if (!m_PendingLowSendPackets.empty() && Data.empty()) + { + m_PendingLowSendPackets.front()->Serialize(Data); + delete m_PendingLowSendPackets.front(); + m_PendingLowSendPackets.erase(m_PendingLowSendPackets.begin()); + } + Lock.Unlock(); + + a_Data.append(Data); + + // Disconnect player after all packets have been sent + if (m_bKicking && (m_PendingNrmSendPackets.size() + m_PendingLowSendPackets.size() == 0)) + { + Destroy(); + } +} + + + + + +void cClientHandle::SocketClosed(void) +{ + // The socket has been closed for any reason + + // TODO + /* + self->Destroy(); + LOG("Client \"%s\" disconnected", GetLogName().c_str()); + */ +} + + + + diff --git a/source/cClientHandle.h b/source/cClientHandle.h index a2a12573a..790bcc5b2 100644 --- a/source/cClientHandle.h +++ b/source/cClientHandle.h @@ -1,239 +1,239 @@ - -// cClientHandle.h - -// Interfaces to the cClientHandle class representing a client connected to this server. The client need not be a player yet - - - - - -#pragma once -#ifndef CCLIENTHANDLE_H_INCLUDED -#define CCLIENTHANDLE_H_INCLUDED - -#include "packets/cPacket.h" -#include "Vector3d.h" -#include "cSocketThreads.h" -#include "ChunkDef.h" - -#include "packets/cPacket_KeepAlive.h" -#include "packets/cPacket_Player.h" -#include "packets/cPacket_Respawn.h" -#include "packets/cPacket_RelativeEntityMoveLook.h" -#include "packets/cPacket_Chat.h" -#include "packets/cPacket_Login.h" -#include "packets/cPacket_WindowClick.h" -#include "packets/cPacket_TimeUpdate.h" -#include "packets/cPacket_BlockDig.h" -#include "packets/cPacket_Handshake.h" -#include "packets/cPacket_ArmAnim.h" -#include "packets/cPacket_BlockPlace.h" -#include "packets/cPacket_Flying.h" -#include "packets/cPacket_Disconnect.h" -#include "packets/cPacket_PickupSpawn.h" -#include "packets/cPacket_ItemSwitch.h" -#include "packets/cPacket_EntityEquipment.h" -#include "packets/cPacket_CreativeInventoryAction.h" -#include "packets/cPacket_NewInvalidState.h" -#include "packets/cPacket_UseEntity.h" -#include "packets/cPacket_WindowClose.h" -#include "packets/cPacket_UpdateSign.h" -#include "packets/cPacket_Ping.h" - - - - - -#define MCS_PROTOCOL_VERSION 29 // Synchronize this with MCS_CLIENT_VERSION below! -#define MCS_CLIENT_VERSION "1.2.4, 1.2.5" - - - - - -class cPlayer; -class cRedstone; - - - - - -class cClientHandle : // tolua_export - public cSocketThreads::cCallback -{ // tolua_export -public: - enum ENUM_PRIORITY - { - E_PRIORITY_LOW, - E_PRIORITY_NORMAL - }; - - static const int MAXBLOCKCHANGEINTERACTIONS = 20; // 5 didn't help, 10 still doesn't work in Creative, 20 seems to have done the trick - - static const int DEFAULT_VIEW_DISTANCE = 9; // The default ViewDistance (used when no value is set in Settings.ini) - static const int MAX_VIEW_DISTANCE = 10; - static const int MIN_VIEW_DISTANCE = 4; - - cClientHandle(const cSocket & a_Socket, int a_ViewDistance); - ~cClientHandle(); - - const cSocket & GetSocket(void) const {return m_Socket; } - cSocket & GetSocket(void) {return m_Socket; } - - cPlayer* GetPlayer() { return m_Player; } // tolua_export - - void Kick(const AString & a_Reason); //tolua_export - void Authenticate(void); // Called by cAuthenticator when the user passes authentication - - void StreamChunks(void); - - // Removes the client from all chunks. Used when switching worlds or destroying the player - void RemoveFromAllChunks(void); - - inline bool IsLoggedIn(void) const { return m_State >= csAuthenticating; } - - void Tick(float a_Dt); - - bool IsDestroyed() { return m_bDestroyed; } - void Destroy(); - - bool IsPlaying(void) const {return (m_State == csPlaying); } - - void Send(const cPacket & a_Packet, ENUM_PRIORITY a_Priority = E_PRIORITY_NORMAL); - - const AString & GetUsername(void) const; //tolua_export - - inline short GetPing() const { return m_Ping; } //tolua_export - - void SetViewDistance(int a_ViewDistance); //tolua_export - int GetViewDistance() { return m_ViewDistance; }//tolua_export - - int GetUniqueID() const { return m_UniqueID; } //tolua_export - - /// Returns true if the client wants the chunk specified to be sent (in m_ChunksToSend) - bool WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); - - /// Adds the chunk specified to the list of chunks wanted for sending (m_ChunksToSend) - void AddWantedChunk(int a_ChunkX, int a_ChunkZ); - -private: - - int m_ViewDistance; // Number of chunks the player can see in each direction; 4 is the minimum ( http://wiki.vg/Protocol_FAQ#.E2.80.A6all_connecting_clients_spasm_and_jerk_uncontrollably.21 ) - - static const int GENERATEDISTANCE = 2; // Server generates this many chunks AHEAD of player sight. 2 is the minimum, since foliage is generated 1 step behind chunk terrain generation - - int m_ProtocolVersion; - AString m_Username; - AString m_Password; - - AString m_ReceivedData; // Accumulator for the data received from the socket, waiting to be parsed; accessed from the cSocketThreads' thread only! - - cCriticalSection m_CSPackets; - PacketList m_PendingNrmSendPackets; - PacketList m_PendingLowSendPackets; - - cCriticalSection m_CSChunkLists; - cChunkCoordsList m_LoadedChunks; // Chunks that the player belongs to - cChunkCoordsList m_ChunksToSend; // Chunks that need to be sent to the player (queued because they weren't generated yet or there's not enough time to send them) - - cSocket m_Socket; - - cCriticalSection m_CriticalSection; - - Vector3d m_ConfirmPosition; - - cPacket * m_PacketMap[256]; - - bool m_bDestroyed; - cPlayer * m_Player; - bool m_bKicking; - - // Chunk position when the last StreamChunks() was called; used to avoid re-streaming while in the same chunk - int m_LastStreamedChunkX; - int m_LastStreamedChunkZ; - - float m_TimeLastPacket; - - short m_Ping; - int m_PingID; - long long m_PingStartTime; - long long m_LastPingTime; - static const unsigned short PING_TIME_MS = 1000; //minecraft sends 1 per 20 ticks (1 second or every 1000 ms) - - enum eState - { - csConnected, // The client has just connected, waiting for their handshake / login - csAuthenticating, // The client has logged in, waiting for external authentication - csDownloadingWorld, // The client is waiting for chunks, we're waiting for the loader to provide and send them - csConfirmingPos, // The client has been sent the position packet, waiting for them to repeat the position back - csPlaying, // Normal gameplay - - // TODO: Add Kicking and Destroyed here as well - } ; - - eState m_State; - - bool m_bKeepThreadGoing; - - void HandlePacket(cPacket * a_Packet); - - // Packets handled in csConnected: - void HandlePing (void); - void HandleHandshake (cPacket_Handshake * a_Packet); - void HandleLogin (cPacket_Login * a_Packet); - void HandleUnexpectedPacket(cPacket * a_Packet); // the default case -> kick - - // Packets handled while in csConfirmingPos: - void HandleMoveLookConfirm(cPacket_PlayerMoveLook * a_Packet); // While !m_bPositionConfirmed - - // Packets handled while in csPlaying: - void HandleCreativeInventory(cPacket_CreativeInventoryAction * a_Packet); - void HandlePlayerPos (cPacket_PlayerPosition * a_Packet); - void HandleBlockDig (cPacket_BlockDig * a_Packet); - void HandleBlockPlace (cPacket_BlockPlace * a_Packet); - void HandlePickupSpawn (cPacket_PickupSpawn * a_Packet); - void HandleChat (cPacket_Chat * a_Packet); - void HandlePlayerLook (cPacket_PlayerLook * a_Packet); - void HandlePlayerMoveLook (cPacket_PlayerMoveLook * a_Packet); // While m_bPositionConfirmed (normal gameplay) - void HandleAnimation (cPacket_ArmAnim * a_Packet); - void HandleItemSwitch (cPacket_ItemSwitch * a_Packet); - void HandleWindowClose (cPacket_WindowClose * a_Packet); - void HandleWindowClick (cPacket_WindowClick * a_Packet); - void HandleUpdateSign (cPacket_UpdateSign * a_Packet); - void HandleUseEntity (cPacket_UseEntity * a_Packet); - void HandleRespawn (void); - void HandleDisconnect (cPacket_Disconnect * a_Packet); - void HandleKeepAlive (cPacket_KeepAlive * a_Packet); - - /// Handles rclk with a dye; returns true if the dye is to be be consumed - bool HandleDyes(cPacket_BlockPlace * a_Packet); - - /// Returns true if the rate block interactions is within a reasonable limit (bot protection) - bool CheckBlockInteractionsRate(void); - - /// Checks whether all loaded chunks have been sent to the client; if so, sends the position to confirm - void CheckIfWorldDownloaded(void); - - /// Sends the PlayerMoveLook packet that the client needs to reply to for the game to start - void SendConfirmPosition(void); - - /// Adds a single chunk to be streamed to the client; used by StreamChunks() - void StreamChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); - - // cSocketThreads::cCallback overrides: - virtual void DataReceived (const char * a_Data, int a_Size) override; // Data is received from the client - virtual void GetOutgoingData(AString & a_Data) override; // Data can be sent to client - virtual void SocketClosed (void) override; // The socket has been closed for any reason - - static int s_ClientCount; - int m_UniqueID; -}; // tolua_export - - - - -#endif // CCLIENTHANDLE_H_INCLUDED - - - - + +// cClientHandle.h + +// Interfaces to the cClientHandle class representing a client connected to this server. The client need not be a player yet + + + + + +#pragma once +#ifndef CCLIENTHANDLE_H_INCLUDED +#define CCLIENTHANDLE_H_INCLUDED + +#include "packets/cPacket.h" +#include "Vector3d.h" +#include "cSocketThreads.h" +#include "ChunkDef.h" + +#include "packets/cPacket_KeepAlive.h" +#include "packets/cPacket_Player.h" +#include "packets/cPacket_Respawn.h" +#include "packets/cPacket_RelativeEntityMoveLook.h" +#include "packets/cPacket_Chat.h" +#include "packets/cPacket_Login.h" +#include "packets/cPacket_WindowClick.h" +#include "packets/cPacket_TimeUpdate.h" +#include "packets/cPacket_BlockDig.h" +#include "packets/cPacket_Handshake.h" +#include "packets/cPacket_ArmAnim.h" +#include "packets/cPacket_BlockPlace.h" +#include "packets/cPacket_Flying.h" +#include "packets/cPacket_Disconnect.h" +#include "packets/cPacket_PickupSpawn.h" +#include "packets/cPacket_ItemSwitch.h" +#include "packets/cPacket_EntityEquipment.h" +#include "packets/cPacket_CreativeInventoryAction.h" +#include "packets/cPacket_NewInvalidState.h" +#include "packets/cPacket_UseEntity.h" +#include "packets/cPacket_WindowClose.h" +#include "packets/cPacket_UpdateSign.h" +#include "packets/cPacket_Ping.h" + + + + + +#define MCS_PROTOCOL_VERSION 29 // Synchronize this with MCS_CLIENT_VERSION below! +#define MCS_CLIENT_VERSION "1.2.4, 1.2.5" + + + + + +class cPlayer; +class cRedstone; + + + + + +class cClientHandle : // tolua_export + public cSocketThreads::cCallback +{ // tolua_export +public: + enum ENUM_PRIORITY + { + E_PRIORITY_LOW, + E_PRIORITY_NORMAL + }; + + static const int MAXBLOCKCHANGEINTERACTIONS = 20; // 5 didn't help, 10 still doesn't work in Creative, 20 seems to have done the trick + + static const int DEFAULT_VIEW_DISTANCE = 9; // The default ViewDistance (used when no value is set in Settings.ini) + static const int MAX_VIEW_DISTANCE = 10; + static const int MIN_VIEW_DISTANCE = 4; + + cClientHandle(const cSocket & a_Socket, int a_ViewDistance); + ~cClientHandle(); + + const cSocket & GetSocket(void) const {return m_Socket; } + cSocket & GetSocket(void) {return m_Socket; } + + cPlayer* GetPlayer() { return m_Player; } // tolua_export + + void Kick(const AString & a_Reason); //tolua_export + void Authenticate(void); // Called by cAuthenticator when the user passes authentication + + void StreamChunks(void); + + // Removes the client from all chunks. Used when switching worlds or destroying the player + void RemoveFromAllChunks(void); + + inline bool IsLoggedIn(void) const { return m_State >= csAuthenticating; } + + void Tick(float a_Dt); + + bool IsDestroyed() { return m_bDestroyed; } + void Destroy(); + + bool IsPlaying(void) const {return (m_State == csPlaying); } + + void Send(const cPacket & a_Packet, ENUM_PRIORITY a_Priority = E_PRIORITY_NORMAL); + + const AString & GetUsername(void) const; //tolua_export + + inline short GetPing() const { return m_Ping; } //tolua_export + + void SetViewDistance(int a_ViewDistance); //tolua_export + int GetViewDistance() { return m_ViewDistance; }//tolua_export + + int GetUniqueID() const { return m_UniqueID; } //tolua_export + + /// Returns true if the client wants the chunk specified to be sent (in m_ChunksToSend) + bool WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Adds the chunk specified to the list of chunks wanted for sending (m_ChunksToSend) + void AddWantedChunk(int a_ChunkX, int a_ChunkZ); + +private: + + int m_ViewDistance; // Number of chunks the player can see in each direction; 4 is the minimum ( http://wiki.vg/Protocol_FAQ#.E2.80.A6all_connecting_clients_spasm_and_jerk_uncontrollably.21 ) + + static const int GENERATEDISTANCE = 2; // Server generates this many chunks AHEAD of player sight. 2 is the minimum, since foliage is generated 1 step behind chunk terrain generation + + int m_ProtocolVersion; + AString m_Username; + AString m_Password; + + AString m_ReceivedData; // Accumulator for the data received from the socket, waiting to be parsed; accessed from the cSocketThreads' thread only! + + cCriticalSection m_CSPackets; + PacketList m_PendingNrmSendPackets; + PacketList m_PendingLowSendPackets; + + cCriticalSection m_CSChunkLists; + cChunkCoordsList m_LoadedChunks; // Chunks that the player belongs to + cChunkCoordsList m_ChunksToSend; // Chunks that need to be sent to the player (queued because they weren't generated yet or there's not enough time to send them) + + cSocket m_Socket; + + cCriticalSection m_CriticalSection; + + Vector3d m_ConfirmPosition; + + cPacket * m_PacketMap[256]; + + bool m_bDestroyed; + cPlayer * m_Player; + bool m_bKicking; + + // Chunk position when the last StreamChunks() was called; used to avoid re-streaming while in the same chunk + int m_LastStreamedChunkX; + int m_LastStreamedChunkZ; + + float m_TimeLastPacket; + + short m_Ping; + int m_PingID; + long long m_PingStartTime; + long long m_LastPingTime; + static const unsigned short PING_TIME_MS = 1000; //minecraft sends 1 per 20 ticks (1 second or every 1000 ms) + + enum eState + { + csConnected, // The client has just connected, waiting for their handshake / login + csAuthenticating, // The client has logged in, waiting for external authentication + csDownloadingWorld, // The client is waiting for chunks, we're waiting for the loader to provide and send them + csConfirmingPos, // The client has been sent the position packet, waiting for them to repeat the position back + csPlaying, // Normal gameplay + + // TODO: Add Kicking and Destroyed here as well + } ; + + eState m_State; + + bool m_bKeepThreadGoing; + + void HandlePacket(cPacket * a_Packet); + + // Packets handled in csConnected: + void HandlePing (void); + void HandleHandshake (cPacket_Handshake * a_Packet); + void HandleLogin (cPacket_Login * a_Packet); + void HandleUnexpectedPacket(cPacket * a_Packet); // the default case -> kick + + // Packets handled while in csConfirmingPos: + void HandleMoveLookConfirm(cPacket_PlayerMoveLook * a_Packet); // While !m_bPositionConfirmed + + // Packets handled while in csPlaying: + void HandleCreativeInventory(cPacket_CreativeInventoryAction * a_Packet); + void HandlePlayerPos (cPacket_PlayerPosition * a_Packet); + void HandleBlockDig (cPacket_BlockDig * a_Packet); + void HandleBlockPlace (cPacket_BlockPlace * a_Packet); + void HandlePickupSpawn (cPacket_PickupSpawn * a_Packet); + void HandleChat (cPacket_Chat * a_Packet); + void HandlePlayerLook (cPacket_PlayerLook * a_Packet); + void HandlePlayerMoveLook (cPacket_PlayerMoveLook * a_Packet); // While m_bPositionConfirmed (normal gameplay) + void HandleAnimation (cPacket_ArmAnim * a_Packet); + void HandleItemSwitch (cPacket_ItemSwitch * a_Packet); + void HandleWindowClose (cPacket_WindowClose * a_Packet); + void HandleWindowClick (cPacket_WindowClick * a_Packet); + void HandleUpdateSign (cPacket_UpdateSign * a_Packet); + void HandleUseEntity (cPacket_UseEntity * a_Packet); + void HandleRespawn (void); + void HandleDisconnect (cPacket_Disconnect * a_Packet); + void HandleKeepAlive (cPacket_KeepAlive * a_Packet); + + /// Handles rclk with a dye; returns true if the dye is to be be consumed + bool HandleDyes(cPacket_BlockPlace * a_Packet); + + /// Returns true if the rate block interactions is within a reasonable limit (bot protection) + bool CheckBlockInteractionsRate(void); + + /// Checks whether all loaded chunks have been sent to the client; if so, sends the position to confirm + void CheckIfWorldDownloaded(void); + + /// Sends the PlayerMoveLook packet that the client needs to reply to for the game to start + void SendConfirmPosition(void); + + /// Adds a single chunk to be streamed to the client; used by StreamChunks() + void StreamChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + // cSocketThreads::cCallback overrides: + virtual void DataReceived (const char * a_Data, int a_Size) override; // Data is received from the client + virtual void GetOutgoingData(AString & a_Data) override; // Data can be sent to client + virtual void SocketClosed (void) override; // The socket has been closed for any reason + + static int s_ClientCount; + int m_UniqueID; +}; // tolua_export + + + + +#endif // CCLIENTHANDLE_H_INCLUDED + + + + diff --git a/source/cCow.cpp b/source/cCow.cpp index 18c78aeb1..c4f4ed523 100644 --- a/source/cCow.cpp +++ b/source/cCow.cpp @@ -1,56 +1,56 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cCow.h" - - - - - -// TODO: Milk Cow - - - - - -cCow::cCow() -{ - m_MobType = 92; - GetMonsterConfig("Cow"); -} - - - - - -cCow::~cCow() -{ -} - - - - - -bool cCow::IsA( const char* a_EntityType ) -{ - if( strcmp( a_EntityType, "cCow" ) == 0 ) return true; - return cMonster::IsA( a_EntityType ); -} - - - - - -void cCow::KilledBy( cEntity* a_Killer ) -{ - cItems Drops; - AddRandomDropItem(Drops, 0, 2, E_ITEM_LEATHER); - AddRandomDropItem(Drops, 1, 3, (GetMetaData() == BURNING) ? E_ITEM_STEAK : E_ITEM_RAW_BEEF); - m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); - - cMonster::KilledBy( a_Killer ); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cCow.h" + + + + + +// TODO: Milk Cow + + + + + +cCow::cCow() +{ + m_MobType = 92; + GetMonsterConfig("Cow"); +} + + + + + +cCow::~cCow() +{ +} + + + + + +bool cCow::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cCow" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cCow::KilledBy( cEntity* a_Killer ) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_LEATHER); + AddRandomDropItem(Drops, 1, 3, (GetMetaData() == BURNING) ? E_ITEM_STEAK : E_ITEM_RAW_BEEF); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cCraftingWindow.cpp b/source/cCraftingWindow.cpp index 570f1ed9a..9e6b565c6 100644 --- a/source/cCraftingWindow.cpp +++ b/source/cCraftingWindow.cpp @@ -1,131 +1,131 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cCraftingWindow.h" -#include "cItem.h" -#include "CraftingRecipes.h" -#include "cPlayer.h" -#include "cClientHandle.h" -#include "cInventory.h" -#include "cPickup.h" -#include "cRoot.h" -#include "cWorld.h" - -#include "packets/cPacket_WindowClick.h" -#include "packets/cPacket_InventorySlot.h" - - - - - -cCraftingWindow::cCraftingWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible ) - : cWindow( a_Owner, a_bInventoryVisible ) -{ - SetWindowID( 1 ); - SetWindowType( cWindow::Workbench ); // Workbench - - cItem* Slots = new cItem[10]; - SetSlots( Slots, 10 ); -} - - - - - -void cCraftingWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ) -{ - bool bDontCook = false; - // Override for craft result slot - if( a_ClickPacket->m_SlotNum == 0 ) - { - LOG("In craft slot: %i x %i !!", GetSlot(0)->m_ItemID, GetSlot(0)->m_ItemCount ); - cItem* DraggingItem = GetDraggingItem( &a_Player ); - if( DraggingItem->m_ItemID <= 0 ) - { - *DraggingItem = *GetSlot(0); - GetSlot(0)->Empty(); - } - else if( DraggingItem->Equals( *GetSlot(0) ) ) - { - if( DraggingItem->m_ItemCount + GetSlot(0)->m_ItemCount <= 64 ) - { - DraggingItem->m_ItemCount += GetSlot(0)->m_ItemCount; - GetSlot(0)->Empty(); - } - else - { - bDontCook = true; - } - } - else - { - bDontCook = true; - } - LOG("Dragging Dish %i", DraggingItem->m_ItemCount ); - } - else - { - cWindow::Clicked( a_ClickPacket, a_Player ); - } - - if ((a_ClickPacket->m_SlotNum >= 0) && (a_ClickPacket->m_SlotNum < 10)) - { - cCraftingGrid Grid(GetSlots() + 1, 3, 3); - cCraftingRecipe Recipe(Grid); - - cRoot::Get()->GetCraftingRecipes()->GetRecipe(&a_Player, Grid, Recipe); - - if ((a_ClickPacket->m_SlotNum == 0) && !bDontCook) - { - // Consume the items from the crafting grid: - Recipe.ConsumeIngredients(Grid); - - // Propagate grid back to m_Slots: - Grid.CopyToItems(GetSlots() + 1); - - // Get the recipe for the new grid contents: - cRoot::Get()->GetCraftingRecipes()->GetRecipe(&a_Player, Grid, Recipe); - } - *GetSlot(0) = Recipe.GetResult(); - LOGD("%s cooked: %i x %i !!", a_Player.GetName().c_str(), GetSlot(0)->m_ItemID, GetSlot(0)->m_ItemCount ); - } - SendWholeWindow( a_Player.GetClientHandle() ); - a_Player.GetInventory().SendWholeInventory( a_Player.GetClientHandle() ); - - // Separate packet for result =/ Don't know why - cPacket_InventorySlot Packet; - Packet.m_WindowID = (char)GetWindowID(); - Packet.m_SlotNum = 0; - Packet.m_ItemID = (short)GetSlot(0)->m_ItemID; - Packet.m_ItemCount = GetSlot(0)->m_ItemCount; - Packet.m_ItemUses = (char)GetSlot(0)->m_ItemHealth; - a_Player.GetClientHandle()->Send( Packet ); -} - - - - - -void cCraftingWindow::Close(cPlayer & a_Player) -{ - // Start from slot 1, don't drop what's in the result slot - cItems Drops; - for( int i = 1; i < GetNumSlots(); i++ ) - { - cItem * Item = GetSlot(i); - if (!Item->IsEmpty()) - { - Drops.push_back(*Item); - } - Item->Empty(); - } - float vX = 0, vY = 0, vZ = 0; - EulerToVector( -a_Player.GetRotation(), a_Player.GetPitch(), vZ, vX, vY); - vY = -vY*2 + 1.f; - a_Player.GetWorld()->SpawnItemPickups(Drops, a_Player.GetPosX(), a_Player.GetPosY() + 1.6f, a_Player.GetPosZ(), vX * 2, vY * 2, vZ * 2); - cWindow::Close(a_Player); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cCraftingWindow.h" +#include "cItem.h" +#include "CraftingRecipes.h" +#include "cPlayer.h" +#include "cClientHandle.h" +#include "cInventory.h" +#include "cPickup.h" +#include "cRoot.h" +#include "cWorld.h" + +#include "packets/cPacket_WindowClick.h" +#include "packets/cPacket_InventorySlot.h" + + + + + +cCraftingWindow::cCraftingWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible ) + : cWindow( a_Owner, a_bInventoryVisible ) +{ + SetWindowID( 1 ); + SetWindowType( cWindow::Workbench ); // Workbench + + cItem* Slots = new cItem[10]; + SetSlots( Slots, 10 ); +} + + + + + +void cCraftingWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ) +{ + bool bDontCook = false; + // Override for craft result slot + if( a_ClickPacket->m_SlotNum == 0 ) + { + LOG("In craft slot: %i x %i !!", GetSlot(0)->m_ItemID, GetSlot(0)->m_ItemCount ); + cItem* DraggingItem = GetDraggingItem( &a_Player ); + if( DraggingItem->m_ItemID <= 0 ) + { + *DraggingItem = *GetSlot(0); + GetSlot(0)->Empty(); + } + else if( DraggingItem->Equals( *GetSlot(0) ) ) + { + if( DraggingItem->m_ItemCount + GetSlot(0)->m_ItemCount <= 64 ) + { + DraggingItem->m_ItemCount += GetSlot(0)->m_ItemCount; + GetSlot(0)->Empty(); + } + else + { + bDontCook = true; + } + } + else + { + bDontCook = true; + } + LOG("Dragging Dish %i", DraggingItem->m_ItemCount ); + } + else + { + cWindow::Clicked( a_ClickPacket, a_Player ); + } + + if ((a_ClickPacket->m_SlotNum >= 0) && (a_ClickPacket->m_SlotNum < 10)) + { + cCraftingGrid Grid(GetSlots() + 1, 3, 3); + cCraftingRecipe Recipe(Grid); + + cRoot::Get()->GetCraftingRecipes()->GetRecipe(&a_Player, Grid, Recipe); + + if ((a_ClickPacket->m_SlotNum == 0) && !bDontCook) + { + // Consume the items from the crafting grid: + Recipe.ConsumeIngredients(Grid); + + // Propagate grid back to m_Slots: + Grid.CopyToItems(GetSlots() + 1); + + // Get the recipe for the new grid contents: + cRoot::Get()->GetCraftingRecipes()->GetRecipe(&a_Player, Grid, Recipe); + } + *GetSlot(0) = Recipe.GetResult(); + LOGD("%s cooked: %i x %i !!", a_Player.GetName().c_str(), GetSlot(0)->m_ItemID, GetSlot(0)->m_ItemCount ); + } + SendWholeWindow( a_Player.GetClientHandle() ); + a_Player.GetInventory().SendWholeInventory( a_Player.GetClientHandle() ); + + // Separate packet for result =/ Don't know why + cPacket_InventorySlot Packet; + Packet.m_WindowID = (char)GetWindowID(); + Packet.m_SlotNum = 0; + Packet.m_ItemID = (short)GetSlot(0)->m_ItemID; + Packet.m_ItemCount = GetSlot(0)->m_ItemCount; + Packet.m_ItemUses = (char)GetSlot(0)->m_ItemHealth; + a_Player.GetClientHandle()->Send( Packet ); +} + + + + + +void cCraftingWindow::Close(cPlayer & a_Player) +{ + // Start from slot 1, don't drop what's in the result slot + cItems Drops; + for( int i = 1; i < GetNumSlots(); i++ ) + { + cItem * Item = GetSlot(i); + if (!Item->IsEmpty()) + { + Drops.push_back(*Item); + } + Item->Empty(); + } + float vX = 0, vY = 0, vZ = 0; + EulerToVector( -a_Player.GetRotation(), a_Player.GetPitch(), vZ, vX, vY); + vY = -vY*2 + 1.f; + a_Player.GetWorld()->SpawnItemPickups(Drops, a_Player.GetPosX(), a_Player.GetPosY() + 1.6f, a_Player.GetPosZ(), vX * 2, vY * 2, vZ * 2); + cWindow::Close(a_Player); +} + + + + diff --git a/source/cCraftingWindow.h b/source/cCraftingWindow.h index df32bf74a..16fe3bb23 100644 --- a/source/cCraftingWindow.h +++ b/source/cCraftingWindow.h @@ -1,13 +1,13 @@ -#pragma once - -#include "cWindow.h" - -class cWindowOwner; -class cCraftingWindow : public cWindow -{ -public: - cCraftingWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible ); - - virtual void Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ); - virtual void Close( cPlayer & a_Player ); +#pragma once + +#include "cWindow.h" + +class cWindowOwner; +class cCraftingWindow : public cWindow +{ +public: + cCraftingWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible ); + + virtual void Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ); + virtual void Close( cPlayer & a_Player ); }; \ No newline at end of file diff --git a/source/cCreativeInventory.cpp b/source/cCreativeInventory.cpp index 51f4a26ed..7083adeb7 100644 --- a/source/cCreativeInventory.cpp +++ b/source/cCreativeInventory.cpp @@ -1,38 +1,38 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cCreativeInventory.h" -#include "cPlayer.h" -#include "cClientHandle.h" -#include "cWindow.h" -#include "cItem.h" -#include "cRoot.h" - -#include - -#include "packets/cPacket_CreativeInventoryAction.h" -#include "packets/cPacket_WholeInventory.h" -#include "packets/cPacket_InventorySlot.h" - -cCreativeInventory::~cCreativeInventory() -{ -} - -cCreativeInventory::cCreativeInventory(cPlayer* a_Owner) - : cInventory(a_Owner) -{ - -} - -void cCreativeInventory::Clicked( cPacket* a_ClickPacket ) -{ - cPacket_CreativeInventoryAction* Packet = reinterpret_cast(a_ClickPacket); - short Slot = Packet->m_Slot; - - cItem* SlotItem = &(this->m_Slots[Slot]); - - SlotItem->m_ItemID = (ENUM_ITEM_ID) Packet->m_ItemID; - SlotItem->m_ItemHealth = Packet->m_Damage; - SlotItem->m_ItemCount = Packet->m_Quantity; -} - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cCreativeInventory.h" +#include "cPlayer.h" +#include "cClientHandle.h" +#include "cWindow.h" +#include "cItem.h" +#include "cRoot.h" + +#include + +#include "packets/cPacket_CreativeInventoryAction.h" +#include "packets/cPacket_WholeInventory.h" +#include "packets/cPacket_InventorySlot.h" + +cCreativeInventory::~cCreativeInventory() +{ +} + +cCreativeInventory::cCreativeInventory(cPlayer* a_Owner) + : cInventory(a_Owner) +{ + +} + +void cCreativeInventory::Clicked( cPacket* a_ClickPacket ) +{ + cPacket_CreativeInventoryAction* Packet = reinterpret_cast(a_ClickPacket); + short Slot = Packet->m_Slot; + + cItem* SlotItem = &(this->m_Slots[Slot]); + + SlotItem->m_ItemID = (ENUM_ITEM_ID) Packet->m_ItemID; + SlotItem->m_ItemHealth = Packet->m_Damage; + SlotItem->m_ItemCount = Packet->m_Quantity; +} + diff --git a/source/cCreativeInventory.h b/source/cCreativeInventory.h index 996136a27..f38c02c6c 100644 --- a/source/cCreativeInventory.h +++ b/source/cCreativeInventory.h @@ -1,13 +1,13 @@ -#pragma once - -#include "cInventory.h" - -class cCreativeInventory //tolua_export - : public cInventory -{ //tolua_export -public: - cCreativeInventory(cPlayer* a_Owner); - ~cCreativeInventory(); - - virtual void Clicked( cPacket* a_ClickPacket ); -}; //tolua_export +#pragma once + +#include "cInventory.h" + +class cCreativeInventory //tolua_export + : public cInventory +{ //tolua_export +public: + cCreativeInventory(cPlayer* a_Owner); + ~cCreativeInventory(); + + virtual void Clicked( cPacket* a_ClickPacket ); +}; //tolua_export diff --git a/source/cCreeper.cpp b/source/cCreeper.cpp index 34573a9bf..208d51845 100644 --- a/source/cCreeper.cpp +++ b/source/cCreeper.cpp @@ -1,52 +1,52 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cCreeper.h" - - - - - -cCreeper::cCreeper() -{ - m_MobType = 50; - GetMonsterConfig("Creeper"); -} - - - - - -cCreeper::~cCreeper() -{ -} - - - - - -bool cCreeper::IsA( const char* a_EntityType ) -{ - if( strcmp( a_EntityType, "cCreeper" ) == 0 ) return true; - return cMonster::IsA( a_EntityType ); -} - - - - - -void cCreeper::KilledBy( cEntity* a_Killer ) -{ - cItems Drops; - AddRandomDropItem(Drops, 0, 2, E_ITEM_GUNPOWDER); - - // TODO Check if killed by a skeleton, then drop random music disk - - m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); - - cMonster::KilledBy( a_Killer ); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cCreeper.h" + + + + + +cCreeper::cCreeper() +{ + m_MobType = 50; + GetMonsterConfig("Creeper"); +} + + + + + +cCreeper::~cCreeper() +{ +} + + + + + +bool cCreeper::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cCreeper" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cCreeper::KilledBy( cEntity* a_Killer ) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_GUNPOWDER); + + // TODO Check if killed by a skeleton, then drop random music disk + + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cCriticalSection.cpp b/source/cCriticalSection.cpp index f66e6b878..e8d719a45 100644 --- a/source/cCriticalSection.cpp +++ b/source/cCriticalSection.cpp @@ -1,157 +1,157 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cCriticalSection: - -cCriticalSection::cCriticalSection() -{ -#ifdef _WIN32 - InitializeCriticalSection( &m_CriticalSection ); -#else - m_Attributes = new pthread_mutexattr_t; - pthread_mutexattr_init((pthread_mutexattr_t*)m_Attributes); - pthread_mutexattr_settype((pthread_mutexattr_t*)m_Attributes, PTHREAD_MUTEX_RECURSIVE); - - m_CriticalSectionPtr = new pthread_mutex_t; - if( pthread_mutex_init( (pthread_mutex_t*)m_CriticalSectionPtr, (pthread_mutexattr_t*)m_Attributes ) != 0 ) - { - LOG("ERROR: Could not initialize Critical Section!"); - } -#endif -} - - - - - -cCriticalSection::~cCriticalSection() -{ -#ifdef _WIN32 - DeleteCriticalSection( &m_CriticalSection ); -#else - if( pthread_mutex_destroy( (pthread_mutex_t*)m_CriticalSectionPtr ) != 0 ) - { - LOG("ERROR: Could not destroy Critical Section!"); - } - delete (pthread_mutex_t*)m_CriticalSectionPtr; - pthread_mutexattr_destroy( (pthread_mutexattr_t*)m_Attributes ); - delete (pthread_mutexattr_t*)m_Attributes; -#endif -} - - - - - -void cCriticalSection::Lock() -{ -#ifdef _WIN32 - EnterCriticalSection( &m_CriticalSection ); -#else - pthread_mutex_lock( (pthread_mutex_t*)m_CriticalSectionPtr ); -#endif -} - - - - - -void cCriticalSection::Unlock() -{ -#ifdef _WIN32 - LeaveCriticalSection( &m_CriticalSection ); -#else - pthread_mutex_unlock( (pthread_mutex_t*)m_CriticalSectionPtr ); -#endif -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cCSLock - -cCSLock::cCSLock(cCriticalSection * a_CS) - : m_CS(a_CS) - , m_IsLocked(false) -{ - Lock(); -} - - - - - -cCSLock::cCSLock(cCriticalSection & a_CS) - : m_CS(&a_CS) - , m_IsLocked(false) -{ - Lock(); -} - - - - - -cCSLock::~cCSLock() -{ - if (!m_IsLocked) - { - return; - } - Unlock(); -} - - - - - -void cCSLock::Lock(void) -{ - ASSERT(!m_IsLocked); - m_IsLocked = true; - m_CS->Lock(); -} - - - - - -void cCSLock::Unlock(void) -{ - ASSERT(m_IsLocked); - m_IsLocked = false; - m_CS->Unlock(); -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cCSUnlock: - -cCSUnlock::cCSUnlock(cCSLock & a_Lock) : - m_Lock(a_Lock) -{ - m_Lock.Unlock(); -} - - - - - -cCSUnlock::~cCSUnlock() -{ - m_Lock.Lock(); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCriticalSection: + +cCriticalSection::cCriticalSection() +{ +#ifdef _WIN32 + InitializeCriticalSection( &m_CriticalSection ); +#else + m_Attributes = new pthread_mutexattr_t; + pthread_mutexattr_init((pthread_mutexattr_t*)m_Attributes); + pthread_mutexattr_settype((pthread_mutexattr_t*)m_Attributes, PTHREAD_MUTEX_RECURSIVE); + + m_CriticalSectionPtr = new pthread_mutex_t; + if( pthread_mutex_init( (pthread_mutex_t*)m_CriticalSectionPtr, (pthread_mutexattr_t*)m_Attributes ) != 0 ) + { + LOG("ERROR: Could not initialize Critical Section!"); + } +#endif +} + + + + + +cCriticalSection::~cCriticalSection() +{ +#ifdef _WIN32 + DeleteCriticalSection( &m_CriticalSection ); +#else + if( pthread_mutex_destroy( (pthread_mutex_t*)m_CriticalSectionPtr ) != 0 ) + { + LOG("ERROR: Could not destroy Critical Section!"); + } + delete (pthread_mutex_t*)m_CriticalSectionPtr; + pthread_mutexattr_destroy( (pthread_mutexattr_t*)m_Attributes ); + delete (pthread_mutexattr_t*)m_Attributes; +#endif +} + + + + + +void cCriticalSection::Lock() +{ +#ifdef _WIN32 + EnterCriticalSection( &m_CriticalSection ); +#else + pthread_mutex_lock( (pthread_mutex_t*)m_CriticalSectionPtr ); +#endif +} + + + + + +void cCriticalSection::Unlock() +{ +#ifdef _WIN32 + LeaveCriticalSection( &m_CriticalSection ); +#else + pthread_mutex_unlock( (pthread_mutex_t*)m_CriticalSectionPtr ); +#endif +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCSLock + +cCSLock::cCSLock(cCriticalSection * a_CS) + : m_CS(a_CS) + , m_IsLocked(false) +{ + Lock(); +} + + + + + +cCSLock::cCSLock(cCriticalSection & a_CS) + : m_CS(&a_CS) + , m_IsLocked(false) +{ + Lock(); +} + + + + + +cCSLock::~cCSLock() +{ + if (!m_IsLocked) + { + return; + } + Unlock(); +} + + + + + +void cCSLock::Lock(void) +{ + ASSERT(!m_IsLocked); + m_IsLocked = true; + m_CS->Lock(); +} + + + + + +void cCSLock::Unlock(void) +{ + ASSERT(m_IsLocked); + m_IsLocked = false; + m_CS->Unlock(); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCSUnlock: + +cCSUnlock::cCSUnlock(cCSLock & a_Lock) : + m_Lock(a_Lock) +{ + m_Lock.Unlock(); +} + + + + + +cCSUnlock::~cCSUnlock() +{ + m_Lock.Lock(); +} + + + + diff --git a/source/cCriticalSection.h b/source/cCriticalSection.h index 0a149a95a..a8b475503 100644 --- a/source/cCriticalSection.h +++ b/source/cCriticalSection.h @@ -1,71 +1,71 @@ - -#pragma once - - - - - -class cCriticalSection -{ -public: - cCriticalSection(void); - ~cCriticalSection(); - - void Lock(void); - void Unlock(void); - -private: - - #ifdef _WIN32 - CRITICAL_SECTION m_CriticalSection; - #else // _WIN32 - void* m_CriticalSectionPtr ALIGN_8; // Pointer to a CRITICAL_SECTION object - void* m_Attributes ALIGN_8; - #endif // else _WIN32 -} ALIGN_8; - - - - -/// RAII for cCriticalSection - locks the CS on creation, unlocks on destruction -class cCSLock -{ - cCriticalSection * m_CS; - - // Unlike a cCriticalSection, this object should be used from a single thread, therefore access to m_IsLocked is not threadsafe - // In Windows, it is an error to call cCriticalSection::Unlock() multiple times if the lock is not held, - // therefore we need to check this value whether we are locked or not. - bool m_IsLocked; - -public: - cCSLock(cCriticalSection * a_CS); - cCSLock(cCriticalSection & a_CS); - ~cCSLock(); - - // Temporarily unlock or re-lock: - void Lock(void); - void Unlock(void); - -private: - DISALLOW_COPY_AND_ASSIGN(cCSLock); -} ; - - - - - -/// Temporary RAII unlock for a cCSLock. Useful for unlock-wait-relock scenarios -class cCSUnlock -{ - cCSLock & m_Lock; -public: - cCSUnlock(cCSLock & a_Lock); - ~cCSUnlock(); - -private: - DISALLOW_COPY_AND_ASSIGN(cCSUnlock); -} ; - - - - + +#pragma once + + + + + +class cCriticalSection +{ +public: + cCriticalSection(void); + ~cCriticalSection(); + + void Lock(void); + void Unlock(void); + +private: + + #ifdef _WIN32 + CRITICAL_SECTION m_CriticalSection; + #else // _WIN32 + void* m_CriticalSectionPtr ALIGN_8; // Pointer to a CRITICAL_SECTION object + void* m_Attributes ALIGN_8; + #endif // else _WIN32 +} ALIGN_8; + + + + +/// RAII for cCriticalSection - locks the CS on creation, unlocks on destruction +class cCSLock +{ + cCriticalSection * m_CS; + + // Unlike a cCriticalSection, this object should be used from a single thread, therefore access to m_IsLocked is not threadsafe + // In Windows, it is an error to call cCriticalSection::Unlock() multiple times if the lock is not held, + // therefore we need to check this value whether we are locked or not. + bool m_IsLocked; + +public: + cCSLock(cCriticalSection * a_CS); + cCSLock(cCriticalSection & a_CS); + ~cCSLock(); + + // Temporarily unlock or re-lock: + void Lock(void); + void Unlock(void); + +private: + DISALLOW_COPY_AND_ASSIGN(cCSLock); +} ; + + + + + +/// Temporary RAII unlock for a cCSLock. Useful for unlock-wait-relock scenarios +class cCSUnlock +{ + cCSLock & m_Lock; +public: + cCSUnlock(cCSLock & a_Lock); + ~cCSUnlock(); + +private: + DISALLOW_COPY_AND_ASSIGN(cCSUnlock); +} ; + + + + diff --git a/source/cCuboid.cpp b/source/cCuboid.cpp index ecd457549..86600f6b6 100644 --- a/source/cCuboid.cpp +++ b/source/cCuboid.cpp @@ -1,19 +1,19 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cCuboid.h" - - - - - -void cCuboid::Sort() -{ - if( p1.x > p2.x ) std::swap( p1.x, p2.x ); - if( p1.y > p2.y ) std::swap( p1.y, p2.y ); - if( p1.z > p2.z ) std::swap( p1.z, p2.z ); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cCuboid.h" + + + + + +void cCuboid::Sort() +{ + if( p1.x > p2.x ) std::swap( p1.x, p2.x ); + if( p1.y > p2.y ) std::swap( p1.y, p2.y ); + if( p1.z > p2.z ) std::swap( p1.z, p2.z ); +} + + + + diff --git a/source/cCuboid.h b/source/cCuboid.h index 28e222e41..a07d665fc 100644 --- a/source/cCuboid.h +++ b/source/cCuboid.h @@ -1,40 +1,40 @@ -#pragma once - -#include "Vector3i.h" -#include "Vector3d.h" - -class cCuboid //tolua_export -{ //tolua_export -public: //tolua_export - cCuboid() {} //tolua_export - cCuboid( const cCuboid & a_Cuboid ) : p1( a_Cuboid.p1 ), p2( a_Cuboid.p2 ) {} //tolua_export - cCuboid( const Vector3i & a_p1, const Vector3i & a_p2 ) : p1( a_p1 ), p2( a_p2 ) {} //tolua_export - - - Vector3i p1, p2; //tolua_export - - void Sort(); //tolua_export - - bool IsInside( const Vector3i & v ) const //tolua_export - { //tolua_export - if( v.x >= p1.x && v.x <= p2.x - && v.y >= p1.y && v.y <= p2.y - && v.z >= p1.z && v.z <= p2.z ) - { - return true; - } - return false; - } //tolua_export - - bool IsInside( const Vector3d & v ) const //tolua_export - { //tolua_export - if( v.x >= p1.x && v.x <= p2.x - && v.y >= p1.y && v.y <= p2.y - && v.z >= p1.z && v.z <= p2.z ) - { - return true; - } - return false; - } //tolua_export - +#pragma once + +#include "Vector3i.h" +#include "Vector3d.h" + +class cCuboid //tolua_export +{ //tolua_export +public: //tolua_export + cCuboid() {} //tolua_export + cCuboid( const cCuboid & a_Cuboid ) : p1( a_Cuboid.p1 ), p2( a_Cuboid.p2 ) {} //tolua_export + cCuboid( const Vector3i & a_p1, const Vector3i & a_p2 ) : p1( a_p1 ), p2( a_p2 ) {} //tolua_export + + + Vector3i p1, p2; //tolua_export + + void Sort(); //tolua_export + + bool IsInside( const Vector3i & v ) const //tolua_export + { //tolua_export + if( v.x >= p1.x && v.x <= p2.x + && v.y >= p1.y && v.y <= p2.y + && v.z >= p1.z && v.z <= p2.z ) + { + return true; + } + return false; + } //tolua_export + + bool IsInside( const Vector3d & v ) const //tolua_export + { //tolua_export + if( v.x >= p1.x && v.x <= p2.x + && v.y >= p1.y && v.y <= p2.y + && v.z >= p1.z && v.z <= p2.z ) + { + return true; + } + return false; + } //tolua_export + }; //tolua_export \ No newline at end of file diff --git a/source/cDoors.h b/source/cDoors.h index dc326104b..212e90062 100644 --- a/source/cDoors.h +++ b/source/cDoors.h @@ -1,62 +1,62 @@ -#pragma once -#include "cBlockToPickup.h" - - -class cDoors //tolua_export -{ //tolua_export -public: - static char RotationToMetaData( float a_Rotation ) //tolua_export - { //tolua_export - a_Rotation += 90 + 45; // So its not aligned with axis - if( a_Rotation > 360.f ) a_Rotation -= 360.f; - if( a_Rotation >= 0.f && a_Rotation < 90.f ) - return 0x0; - else if( a_Rotation >= 180 && a_Rotation < 270 ) - return 0x2; - else if( a_Rotation >= 90 && a_Rotation < 180 ) - return 0x1; - else - return 0x3; - } //tolua_export - - static char ChangeStateMetaData( char a_MetaData ) //tolua_export - { //tolua_export - - a_MetaData ^= 4; //XOR bit 2 aka 3. bit (Door open state) - - return a_MetaData; - } //tolua_export - - static void ChangeDoor(cWorld *a_World, int a_X, int a_Y, int a_Z) //tolua_export - { //tolua_export - char OldMetaData = a_World->GetBlockMeta(a_X, a_Y, a_Z); - - a_World->SetBlockMeta(a_X, a_Y, a_Z, ChangeStateMetaData ( OldMetaData ) ); - - - if (OldMetaData & 8) - { //current block is top of the door - char BottomBlock = a_World->GetBlock(a_X, a_Y - 1, a_Z); - char BottomMeta = a_World->GetBlockMeta(a_X, a_Y - 1, a_Z); - - if (IsDoor(BottomBlock) && !(BottomMeta & 8)) - { - a_World->SetBlockMeta(a_X, a_Y - 1, a_Z, ChangeStateMetaData ( BottomMeta ) ); - } - } else { //current block is bottom of the door - char TopBlock = a_World->GetBlock(a_X, a_Y + 1, a_Z); - char TopMeta = a_World->GetBlockMeta(a_X, a_Y + 1, a_Z); - - if (IsDoor(TopBlock) && (TopMeta & 8)) - { - a_World->SetBlockMeta(a_X, a_Y + 1, a_Z, ChangeStateMetaData ( TopMeta ) ); - } - } - } //tolua_export - - inline static bool IsDoor(char a_Block) - { - return (a_Block == E_BLOCK_WOODEN_DOOR || a_Block == E_BLOCK_IRON_DOOR); - } - +#pragma once +#include "cBlockToPickup.h" + + +class cDoors //tolua_export +{ //tolua_export +public: + static char RotationToMetaData( float a_Rotation ) //tolua_export + { //tolua_export + a_Rotation += 90 + 45; // So its not aligned with axis + if( a_Rotation > 360.f ) a_Rotation -= 360.f; + if( a_Rotation >= 0.f && a_Rotation < 90.f ) + return 0x0; + else if( a_Rotation >= 180 && a_Rotation < 270 ) + return 0x2; + else if( a_Rotation >= 90 && a_Rotation < 180 ) + return 0x1; + else + return 0x3; + } //tolua_export + + static char ChangeStateMetaData( char a_MetaData ) //tolua_export + { //tolua_export + + a_MetaData ^= 4; //XOR bit 2 aka 3. bit (Door open state) + + return a_MetaData; + } //tolua_export + + static void ChangeDoor(cWorld *a_World, int a_X, int a_Y, int a_Z) //tolua_export + { //tolua_export + char OldMetaData = a_World->GetBlockMeta(a_X, a_Y, a_Z); + + a_World->SetBlockMeta(a_X, a_Y, a_Z, ChangeStateMetaData ( OldMetaData ) ); + + + if (OldMetaData & 8) + { //current block is top of the door + char BottomBlock = a_World->GetBlock(a_X, a_Y - 1, a_Z); + char BottomMeta = a_World->GetBlockMeta(a_X, a_Y - 1, a_Z); + + if (IsDoor(BottomBlock) && !(BottomMeta & 8)) + { + a_World->SetBlockMeta(a_X, a_Y - 1, a_Z, ChangeStateMetaData ( BottomMeta ) ); + } + } else { //current block is bottom of the door + char TopBlock = a_World->GetBlock(a_X, a_Y + 1, a_Z); + char TopMeta = a_World->GetBlockMeta(a_X, a_Y + 1, a_Z); + + if (IsDoor(TopBlock) && (TopMeta & 8)) + { + a_World->SetBlockMeta(a_X, a_Y + 1, a_Z, ChangeStateMetaData ( TopMeta ) ); + } + } + } //tolua_export + + inline static bool IsDoor(char a_Block) + { + return (a_Block == E_BLOCK_WOODEN_DOOR || a_Block == E_BLOCK_IRON_DOOR); + } + }; //tolua_export \ No newline at end of file diff --git a/source/cEnderman.cpp b/source/cEnderman.cpp index 8fbad6a39..61bdfe06b 100644 --- a/source/cEnderman.cpp +++ b/source/cEnderman.cpp @@ -1,63 +1,63 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cEnderman.h" - - - - - -cEnderman::cEnderman() -{ - m_MobType = 58; - GetMonsterConfig("Enderman"); -} - - - - - -cEnderman::~cEnderman() -{ -} - - - - - -bool cEnderman::IsA( const char* a_EntityType ) -{ - if( strcmp( a_EntityType, "cEnderman" ) == 0 ) return true; - return cMonster::IsA( a_EntityType ); -} - - - - - -void cEnderman::Tick(float a_Dt) -{ - cMonster::Tick(a_Dt); - - //TODO Same as stated in cSkeleton - if (GetWorld()->GetWorldTime() < (12000 + 1000) && GetMetaData() != BURNING) { //if daylight - SetMetaData(BURNING); // BURN, BABY, BURN! >:D - } -} - - - - - -void cEnderman::KilledBy( cEntity* a_Killer ) -{ - cItems Drops; - AddRandomDropItem(Drops, 0, 1, E_ITEM_ENDER_PEARL); - m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); - - cMonster::KilledBy( a_Killer ); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cEnderman.h" + + + + + +cEnderman::cEnderman() +{ + m_MobType = 58; + GetMonsterConfig("Enderman"); +} + + + + + +cEnderman::~cEnderman() +{ +} + + + + + +bool cEnderman::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cEnderman" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cEnderman::Tick(float a_Dt) +{ + cMonster::Tick(a_Dt); + + //TODO Same as stated in cSkeleton + if (GetWorld()->GetWorldTime() < (12000 + 1000) && GetMetaData() != BURNING) { //if daylight + SetMetaData(BURNING); // BURN, BABY, BURN! >:D + } +} + + + + + +void cEnderman::KilledBy( cEntity* a_Killer ) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 1, E_ITEM_ENDER_PEARL); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cEnderman.h b/source/cEnderman.h index 75b1b22a8..d147cc4e7 100644 --- a/source/cEnderman.h +++ b/source/cEnderman.h @@ -1,15 +1,15 @@ -#pragma once - -#include "cPassiveAggressiveMonster.h" - -class cEnderman : public cPassiveAggressiveMonster -{ -public: - cEnderman(); - ~cEnderman(); - - virtual bool IsA( const char* a_EntityType ); - - virtual void Tick(float a_Dt); - virtual void KilledBy( cEntity* a_Killer ); -}; +#pragma once + +#include "cPassiveAggressiveMonster.h" + +class cEnderman : public cPassiveAggressiveMonster +{ +public: + cEnderman(); + ~cEnderman(); + + virtual bool IsA( const char* a_EntityType ); + + virtual void Tick(float a_Dt); + virtual void KilledBy( cEntity* a_Killer ); +}; diff --git a/source/cEntity.cpp b/source/cEntity.cpp index 40bef9cb9..3e0ed7190 100644 --- a/source/cEntity.cpp +++ b/source/cEntity.cpp @@ -1,382 +1,382 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cEntity.h" -#include "cWorld.h" -#include "cServer.h" -#include "cRoot.h" -#include "Vector3d.h" -#include "Vector3f.h" -#include "Matrix4f.h" -#include "cReferenceManager.h" -#include "cClientHandle.h" - -#include "packets/cPacket_DestroyEntity.h" - - - - - -int cEntity::m_EntityCount = 0; -cCriticalSection cEntity::m_CSCount; - - - - - -cEntity::cEntity(const double & a_X, const double & a_Y, const double & a_Z) - : m_UniqueID( 0 ) - , m_Referencers( new cReferenceManager( cReferenceManager::RFMNGR_REFERENCERS ) ) - , m_References( new cReferenceManager( cReferenceManager::RFMNGR_REFERENCES ) ) - , m_ChunkX( 0 ) - , m_ChunkY( 0 ) - , m_ChunkZ( 0 ) - , m_Pos( a_X, a_Y, a_Z ) - , m_bDirtyPosition( true ) - , m_bDirtyOrientation( true ) - , m_bDestroyed( false ) - , m_EntityType( eEntityType_Entity ) - , m_World( 0 ) - , m_bRemovedFromChunk( false ) -{ - cCSLock Lock(m_CSCount); - m_EntityCount++; - m_UniqueID = m_EntityCount; -} - - - - - -cEntity::~cEntity() -{ - LOG("Deleting entity %d at pos {%.2f, %.2f} ~ [%d, %d]; ptr %p", - m_UniqueID, - m_Pos.x, m_Pos.z, - (int)(m_Pos.x / cChunkDef::Width), (int)(m_Pos.z / cChunkDef::Width), - this - ); - - if( !m_bDestroyed || !m_bRemovedFromChunk ) - { - LOGERROR("ERROR: Entity deallocated without being destroyed %i or unlinked %i", m_bDestroyed, m_bRemovedFromChunk ); - ASSERT(!"Entity deallocated without being destroyed or unlinked"); - } - delete m_Referencers; - delete m_References; -} - - - - - -void cEntity::Initialize( cWorld* a_World ) -{ - m_World = a_World; - m_World->AddEntity( this ); - - MoveToCorrectChunk(true); -} - - - - - -void cEntity::WrapRotation() -{ - while (m_Rot.x > 180.f) m_Rot.x-=360.f; // Wrap it - while (m_Rot.x < -180.f) m_Rot.x+=360.f; - while (m_Rot.y > 180.f) m_Rot.y-=360.f; - while (m_Rot.y < -180.f) m_Rot.y+=360.f; -} - - - - - -void cEntity::MoveToCorrectChunk(bool a_bIgnoreOldChunk) -{ - ASSERT(m_World != NULL); // Entity needs a world to move to a chunk - if( !m_World ) return; - - int ChunkX = 0, ChunkY = 0, ChunkZ = 0; - cWorld::BlockToChunk( (int)m_Pos.x, (int)m_Pos.y, (int)m_Pos.z, ChunkX, ChunkY, ChunkZ ); - if (!a_bIgnoreOldChunk && (m_ChunkX == ChunkX) && (m_ChunkY == ChunkY) && (m_ChunkZ == ChunkZ)) - { - return; - } - - class cMover : - public cClientDiffCallback - { - virtual void Removed(cClientHandle * a_Client) override - { - if (m_IgnoreOldChunk) - { - return; - } - if (m_Destroy == NULL) - { - m_Destroy = new cPacket_DestroyEntity(m_Entity); - } - a_Client->Send(*m_Destroy); - } - - virtual void Added(cClientHandle * a_Client) override - { - if (m_Spawn == NULL) - { - m_Spawn = m_Entity->GetSpawnPacket(); // Only create the packet when needed - } - if (m_Spawn != NULL) - { - a_Client->Send(*m_Spawn); - } - } - - cPacket * m_Destroy; - cPacket * m_Spawn; - bool m_IgnoreOldChunk; - cEntity * m_Entity; - - public: - cMover(cEntity * a_Entity, bool a_IgnoreOldChunk) : - m_Destroy(NULL), - m_Spawn(NULL), - m_IgnoreOldChunk(a_IgnoreOldChunk), - m_Entity(a_Entity) - {} - - ~cMover() - { - delete m_Spawn; - delete m_Destroy; - } - } Mover(this, a_bIgnoreOldChunk); - - m_World->CompareChunkClients(m_ChunkX, m_ChunkY, m_ChunkZ, ChunkX, ChunkY, ChunkZ, Mover); - m_World->MoveEntityToChunk(this, ChunkX, ChunkY, ChunkZ); - - m_ChunkX = ChunkX; - m_ChunkY = ChunkY; - m_ChunkZ = ChunkZ; -} - - - - - -void cEntity::Destroy() -{ - if (m_bDestroyed) - { - return; - } - if (!m_bRemovedFromChunk) - { - RemoveFromChunk(); - } - - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, cPacket_DestroyEntity(this)); - - m_bDestroyed = true; - - Destroyed(); -} - - - - - -void cEntity::RemoveFromChunk(void) -{ - if (m_World == NULL) - { - return; - } - - m_World->RemoveEntityFromChunk(this, m_ChunkX, m_ChunkY, m_ChunkZ); - m_bRemovedFromChunk = true; -} - - - - - -void cEntity::SpawnOn(cClientHandle * a_Client) -{ - std::auto_ptr SpawnPacket(GetSpawnPacket()); - if (SpawnPacket.get() == NULL) - { - return; - } - - if (a_Client == NULL) - { - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, *SpawnPacket.get(), NULL); - } - else - { - a_Client->Send(*(SpawnPacket.get())); - } -} - - - - - -CLASS_DEF_GETCLASS( cEntity ); -bool cEntity::IsA( const char* a_EntityType ) -{ - //LOG("IsA( cEntity ) : %s", a_EntityType); - if( strcmp( a_EntityType, "cEntity" ) == 0 ) return true; - return false; -} - - - - - -////////////////////////////////////////////////////////////////////////// -// Set orientations -void cEntity::SetRot( const Vector3f & a_Rot ) -{ - m_Rot = a_Rot; - m_bDirtyOrientation = true; -} - - - - - -void cEntity::SetRotation( float a_Rotation ) -{ - m_Rot.x = a_Rotation; - m_bDirtyOrientation = true; -} - - - - - -void cEntity::SetPitch( float a_Pitch ) -{ - m_Rot.y = a_Pitch; - m_bDirtyOrientation = true; -} - - - - - -void cEntity::SetRoll( float a_Roll ) -{ - m_Rot.z = a_Roll; - m_bDirtyOrientation = true; -} - - - - - -////////////////////////////////////////////////////////////////////////// -// Get look vector (this is NOT a rotation!) -Vector3f cEntity::GetLookVector() -{ - Matrix4f m; - m.Init( Vector3f(), 0, m_Rot.x, -m_Rot.y ); - Vector3f Look = m.Transform( Vector3f(0, 0, 1) ); - LOG("Look: %0.1f %0.1f %0.1f", Look.x, Look.y, Look.z ); - return Look; -} - - - - - -////////////////////////////////////////////////////////////////////////// -// Set position -void cEntity::SetPosition( const Vector3d & a_Pos ) -{ - m_Pos = a_Pos; - MoveToCorrectChunk(); - m_bDirtyPosition = true; -} - - - - - -void cEntity::SetPosition( const double & a_PosX, const double & a_PosY, const double & a_PosZ ) -{ - m_Pos.Set( a_PosX, a_PosY, a_PosZ ); - MoveToCorrectChunk(); - m_bDirtyPosition = true; -} - - - - - -void cEntity::SetPosX( const double & a_PosX ) -{ - m_Pos.x = a_PosX; - MoveToCorrectChunk(); - m_bDirtyPosition = true; -} - - - - - -void cEntity::SetPosY( const double & a_PosY ) -{ - m_Pos.y = a_PosY; - MoveToCorrectChunk(); - m_bDirtyPosition = true; -} - - - - - -void cEntity::SetPosZ( const double & a_PosZ ) -{ - m_Pos.z = a_PosZ; - MoveToCorrectChunk(); - m_bDirtyPosition = true; -} - - - - - -////////////////////////////////////////////////////////////////////////// -// Reference stuffs -void cEntity::AddReference( cEntity*& a_EntityPtr ) -{ - m_References->AddReference( a_EntityPtr ); - a_EntityPtr->ReferencedBy( a_EntityPtr ); -} - - - - - -void cEntity::ReferencedBy( cEntity*& a_EntityPtr ) -{ - m_Referencers->AddReference( a_EntityPtr ); -} - - - - - -void cEntity::Dereference( cEntity*& a_EntityPtr ) -{ - m_Referencers->Dereference( a_EntityPtr ); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cEntity.h" +#include "cWorld.h" +#include "cServer.h" +#include "cRoot.h" +#include "Vector3d.h" +#include "Vector3f.h" +#include "Matrix4f.h" +#include "cReferenceManager.h" +#include "cClientHandle.h" + +#include "packets/cPacket_DestroyEntity.h" + + + + + +int cEntity::m_EntityCount = 0; +cCriticalSection cEntity::m_CSCount; + + + + + +cEntity::cEntity(const double & a_X, const double & a_Y, const double & a_Z) + : m_UniqueID( 0 ) + , m_Referencers( new cReferenceManager( cReferenceManager::RFMNGR_REFERENCERS ) ) + , m_References( new cReferenceManager( cReferenceManager::RFMNGR_REFERENCES ) ) + , m_ChunkX( 0 ) + , m_ChunkY( 0 ) + , m_ChunkZ( 0 ) + , m_Pos( a_X, a_Y, a_Z ) + , m_bDirtyPosition( true ) + , m_bDirtyOrientation( true ) + , m_bDestroyed( false ) + , m_EntityType( eEntityType_Entity ) + , m_World( 0 ) + , m_bRemovedFromChunk( false ) +{ + cCSLock Lock(m_CSCount); + m_EntityCount++; + m_UniqueID = m_EntityCount; +} + + + + + +cEntity::~cEntity() +{ + LOG("Deleting entity %d at pos {%.2f, %.2f} ~ [%d, %d]; ptr %p", + m_UniqueID, + m_Pos.x, m_Pos.z, + (int)(m_Pos.x / cChunkDef::Width), (int)(m_Pos.z / cChunkDef::Width), + this + ); + + if( !m_bDestroyed || !m_bRemovedFromChunk ) + { + LOGERROR("ERROR: Entity deallocated without being destroyed %i or unlinked %i", m_bDestroyed, m_bRemovedFromChunk ); + ASSERT(!"Entity deallocated without being destroyed or unlinked"); + } + delete m_Referencers; + delete m_References; +} + + + + + +void cEntity::Initialize( cWorld* a_World ) +{ + m_World = a_World; + m_World->AddEntity( this ); + + MoveToCorrectChunk(true); +} + + + + + +void cEntity::WrapRotation() +{ + while (m_Rot.x > 180.f) m_Rot.x-=360.f; // Wrap it + while (m_Rot.x < -180.f) m_Rot.x+=360.f; + while (m_Rot.y > 180.f) m_Rot.y-=360.f; + while (m_Rot.y < -180.f) m_Rot.y+=360.f; +} + + + + + +void cEntity::MoveToCorrectChunk(bool a_bIgnoreOldChunk) +{ + ASSERT(m_World != NULL); // Entity needs a world to move to a chunk + if( !m_World ) return; + + int ChunkX = 0, ChunkY = 0, ChunkZ = 0; + cWorld::BlockToChunk( (int)m_Pos.x, (int)m_Pos.y, (int)m_Pos.z, ChunkX, ChunkY, ChunkZ ); + if (!a_bIgnoreOldChunk && (m_ChunkX == ChunkX) && (m_ChunkY == ChunkY) && (m_ChunkZ == ChunkZ)) + { + return; + } + + class cMover : + public cClientDiffCallback + { + virtual void Removed(cClientHandle * a_Client) override + { + if (m_IgnoreOldChunk) + { + return; + } + if (m_Destroy == NULL) + { + m_Destroy = new cPacket_DestroyEntity(m_Entity); + } + a_Client->Send(*m_Destroy); + } + + virtual void Added(cClientHandle * a_Client) override + { + if (m_Spawn == NULL) + { + m_Spawn = m_Entity->GetSpawnPacket(); // Only create the packet when needed + } + if (m_Spawn != NULL) + { + a_Client->Send(*m_Spawn); + } + } + + cPacket * m_Destroy; + cPacket * m_Spawn; + bool m_IgnoreOldChunk; + cEntity * m_Entity; + + public: + cMover(cEntity * a_Entity, bool a_IgnoreOldChunk) : + m_Destroy(NULL), + m_Spawn(NULL), + m_IgnoreOldChunk(a_IgnoreOldChunk), + m_Entity(a_Entity) + {} + + ~cMover() + { + delete m_Spawn; + delete m_Destroy; + } + } Mover(this, a_bIgnoreOldChunk); + + m_World->CompareChunkClients(m_ChunkX, m_ChunkY, m_ChunkZ, ChunkX, ChunkY, ChunkZ, Mover); + m_World->MoveEntityToChunk(this, ChunkX, ChunkY, ChunkZ); + + m_ChunkX = ChunkX; + m_ChunkY = ChunkY; + m_ChunkZ = ChunkZ; +} + + + + + +void cEntity::Destroy() +{ + if (m_bDestroyed) + { + return; + } + if (!m_bRemovedFromChunk) + { + RemoveFromChunk(); + } + + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, cPacket_DestroyEntity(this)); + + m_bDestroyed = true; + + Destroyed(); +} + + + + + +void cEntity::RemoveFromChunk(void) +{ + if (m_World == NULL) + { + return; + } + + m_World->RemoveEntityFromChunk(this, m_ChunkX, m_ChunkY, m_ChunkZ); + m_bRemovedFromChunk = true; +} + + + + + +void cEntity::SpawnOn(cClientHandle * a_Client) +{ + std::auto_ptr SpawnPacket(GetSpawnPacket()); + if (SpawnPacket.get() == NULL) + { + return; + } + + if (a_Client == NULL) + { + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, *SpawnPacket.get(), NULL); + } + else + { + a_Client->Send(*(SpawnPacket.get())); + } +} + + + + + +CLASS_DEF_GETCLASS( cEntity ); +bool cEntity::IsA( const char* a_EntityType ) +{ + //LOG("IsA( cEntity ) : %s", a_EntityType); + if( strcmp( a_EntityType, "cEntity" ) == 0 ) return true; + return false; +} + + + + + +////////////////////////////////////////////////////////////////////////// +// Set orientations +void cEntity::SetRot( const Vector3f & a_Rot ) +{ + m_Rot = a_Rot; + m_bDirtyOrientation = true; +} + + + + + +void cEntity::SetRotation( float a_Rotation ) +{ + m_Rot.x = a_Rotation; + m_bDirtyOrientation = true; +} + + + + + +void cEntity::SetPitch( float a_Pitch ) +{ + m_Rot.y = a_Pitch; + m_bDirtyOrientation = true; +} + + + + + +void cEntity::SetRoll( float a_Roll ) +{ + m_Rot.z = a_Roll; + m_bDirtyOrientation = true; +} + + + + + +////////////////////////////////////////////////////////////////////////// +// Get look vector (this is NOT a rotation!) +Vector3f cEntity::GetLookVector() +{ + Matrix4f m; + m.Init( Vector3f(), 0, m_Rot.x, -m_Rot.y ); + Vector3f Look = m.Transform( Vector3f(0, 0, 1) ); + LOG("Look: %0.1f %0.1f %0.1f", Look.x, Look.y, Look.z ); + return Look; +} + + + + + +////////////////////////////////////////////////////////////////////////// +// Set position +void cEntity::SetPosition( const Vector3d & a_Pos ) +{ + m_Pos = a_Pos; + MoveToCorrectChunk(); + m_bDirtyPosition = true; +} + + + + + +void cEntity::SetPosition( const double & a_PosX, const double & a_PosY, const double & a_PosZ ) +{ + m_Pos.Set( a_PosX, a_PosY, a_PosZ ); + MoveToCorrectChunk(); + m_bDirtyPosition = true; +} + + + + + +void cEntity::SetPosX( const double & a_PosX ) +{ + m_Pos.x = a_PosX; + MoveToCorrectChunk(); + m_bDirtyPosition = true; +} + + + + + +void cEntity::SetPosY( const double & a_PosY ) +{ + m_Pos.y = a_PosY; + MoveToCorrectChunk(); + m_bDirtyPosition = true; +} + + + + + +void cEntity::SetPosZ( const double & a_PosZ ) +{ + m_Pos.z = a_PosZ; + MoveToCorrectChunk(); + m_bDirtyPosition = true; +} + + + + + +////////////////////////////////////////////////////////////////////////// +// Reference stuffs +void cEntity::AddReference( cEntity*& a_EntityPtr ) +{ + m_References->AddReference( a_EntityPtr ); + a_EntityPtr->ReferencedBy( a_EntityPtr ); +} + + + + + +void cEntity::ReferencedBy( cEntity*& a_EntityPtr ) +{ + m_Referencers->AddReference( a_EntityPtr ); +} + + + + + +void cEntity::Dereference( cEntity*& a_EntityPtr ) +{ + m_Referencers->Dereference( a_EntityPtr ); +} + + + + diff --git a/source/cEntity.h b/source/cEntity.h index 34c878abd..d5614eb84 100644 --- a/source/cEntity.h +++ b/source/cEntity.h @@ -1,148 +1,148 @@ - -#pragma once - - - - -#include "Vector3d.h" -#include "Vector3f.h" - - - - - -#define CLASS_PROT_ISA() virtual bool IsA( const char* a_EntityType ); -#define CLASS_PROT_GETCLASS() virtual const char* GetClass(); - -/* Can't use this (yet) because of tolua */ -#define CLASS_PROTOTYPE() \ - CLASS_PROT_ISA(); \ - CLASS_PROT_GETCLASS(); - -#define CLASS_DEF_ISA( classname, superclass ) \ - bool classname::IsA( const char* a_EntityType ) \ - { \ - if( strcmp( a_EntityType, #classname ) == 0 ) return true; \ - return superclass::IsA( a_EntityType ); \ - } - -#define CLASS_DEF_GETCLASS( classname ) \ - const char* classname::GetClass() \ - { \ - return #classname; \ - } - -#define CLASS_DEFINITION( classname, superclass ) \ - CLASS_DEF_ISA( classname, superclass ) \ - CLASS_DEF_GETCLASS( classname ) - - - - - -class cWorld; -class cReferenceManager; -class cClientHandle; -class cPacket; - - - - - -class cEntity //tolua_export -{ //tolua_export -public: //tolua_export - cEntity(const double & a_X, const double & a_Y, const double & a_Z); //tolua_export - virtual ~cEntity(); //tolua_export - - virtual void Initialize( cWorld* a_World ); //tolua_export - - enum eEntityType //tolua_export - { //tolua_export - eEntityType_Entity, //tolua_export - eEntityType_Player, //tolua_export - eEntityType_Pickup //tolua_export - }; //tolua_export - - virtual unsigned int GetEntityType() { return m_EntityType; } //tolua_export - virtual bool IsA( const char* a_EntityType ); //tolua_export - virtual const char* GetClass(); //tolua_export - - cWorld * GetWorld(void) const { return m_World; } //tolua_export - - const Vector3d & GetPosition(void) const {return m_Pos; } //tolua_export - const double & GetPosX (void) const {return m_Pos.x; } //tolua_export - const double & GetPosY (void) const {return m_Pos.y; } //tolua_export - const double & GetPosZ (void) const {return m_Pos.z; } //tolua_export - const Vector3f & GetRot (void) const {return m_Rot; } //tolua_export - float GetRotation(void) const {return m_Rot.x; } //tolua_export - float GetPitch (void) const {return m_Rot.y; } //tolua_export - float GetRoll (void) const {return m_Rot.z; } //tolua_export - Vector3f GetLookVector(); //tolua_export - - int GetChunkX(void) const {return m_ChunkX; } //tolua_export - int GetChunkY(void) const {return m_ChunkY; } //tolua_export - int GetChunkZ(void) const {return m_ChunkZ; } //tolua_export - - void SetPosX( const double & a_PosX ); //tolua_export - void SetPosY( const double & a_PosY ); //tolua_export - void SetPosZ( const double & a_PosZ ); //tolua_export - void SetPosition( const double & a_PosX, const double & a_PosY, const double & a_PosZ );//tolua_export - void SetPosition( const Vector3d & a_Pos ); //tolua_export - void SetRot( const Vector3f & a_Rot ); //tolua_export - void SetRotation( float a_Rotation ); //tolua_export - void SetPitch( float a_Pitch ); //tolua_export - void SetRoll( float a_Roll ); //tolua_export - - inline int GetUniqueID(void) const { return m_UniqueID; } //tolua_export - inline bool IsDestroyed(void) const { return m_bDestroyed; } //tolua_export - - void Destroy(); //tolua_export - void RemoveFromChunk(void); // for internal use in cChunk - - virtual void Tick(float a_Dt) = 0; //tolua_export - - virtual cPacket * GetSpawnPacket(void) const {ASSERT(!"GetSpawnedPacket unimplemented!"); return NULL; }; // _X: Needs to be implemented due to Lua bindings - void SpawnOn (cClientHandle * a_Client); // tolua_export - - void WrapRotation(); - -protected: - virtual void Destroyed() {} // Called after the entity has been destroyed - - void SetWorld( cWorld* a_World ) { m_World = a_World; } - void MoveToCorrectChunk(bool a_bIgnoreOldChunk = false); - - friend class cReferenceManager; - void AddReference( cEntity*& a_EntityPtr ); - void ReferencedBy( cEntity*& a_EntityPtr ); - void Dereference( cEntity*& a_EntityPtr ); - - static cCriticalSection m_CSCount; - static int m_EntityCount; - - int m_UniqueID; - - cReferenceManager* m_Referencers; - cReferenceManager* m_References; - - int m_ChunkX, m_ChunkY, m_ChunkZ; - Vector3d m_Pos; - bool m_bDirtyPosition; - - Vector3f m_Rot; - bool m_bDirtyOrientation; - - bool m_bDestroyed; - bool m_bRemovedFromChunk; - - eEntityType m_EntityType; - - cWorld* m_World; -}; //tolua_export - -typedef std::list cEntityList; - - - - + +#pragma once + + + + +#include "Vector3d.h" +#include "Vector3f.h" + + + + + +#define CLASS_PROT_ISA() virtual bool IsA( const char* a_EntityType ); +#define CLASS_PROT_GETCLASS() virtual const char* GetClass(); + +/* Can't use this (yet) because of tolua */ +#define CLASS_PROTOTYPE() \ + CLASS_PROT_ISA(); \ + CLASS_PROT_GETCLASS(); + +#define CLASS_DEF_ISA( classname, superclass ) \ + bool classname::IsA( const char* a_EntityType ) \ + { \ + if( strcmp( a_EntityType, #classname ) == 0 ) return true; \ + return superclass::IsA( a_EntityType ); \ + } + +#define CLASS_DEF_GETCLASS( classname ) \ + const char* classname::GetClass() \ + { \ + return #classname; \ + } + +#define CLASS_DEFINITION( classname, superclass ) \ + CLASS_DEF_ISA( classname, superclass ) \ + CLASS_DEF_GETCLASS( classname ) + + + + + +class cWorld; +class cReferenceManager; +class cClientHandle; +class cPacket; + + + + + +class cEntity //tolua_export +{ //tolua_export +public: //tolua_export + cEntity(const double & a_X, const double & a_Y, const double & a_Z); //tolua_export + virtual ~cEntity(); //tolua_export + + virtual void Initialize( cWorld* a_World ); //tolua_export + + enum eEntityType //tolua_export + { //tolua_export + eEntityType_Entity, //tolua_export + eEntityType_Player, //tolua_export + eEntityType_Pickup //tolua_export + }; //tolua_export + + virtual unsigned int GetEntityType() { return m_EntityType; } //tolua_export + virtual bool IsA( const char* a_EntityType ); //tolua_export + virtual const char* GetClass(); //tolua_export + + cWorld * GetWorld(void) const { return m_World; } //tolua_export + + const Vector3d & GetPosition(void) const {return m_Pos; } //tolua_export + const double & GetPosX (void) const {return m_Pos.x; } //tolua_export + const double & GetPosY (void) const {return m_Pos.y; } //tolua_export + const double & GetPosZ (void) const {return m_Pos.z; } //tolua_export + const Vector3f & GetRot (void) const {return m_Rot; } //tolua_export + float GetRotation(void) const {return m_Rot.x; } //tolua_export + float GetPitch (void) const {return m_Rot.y; } //tolua_export + float GetRoll (void) const {return m_Rot.z; } //tolua_export + Vector3f GetLookVector(); //tolua_export + + int GetChunkX(void) const {return m_ChunkX; } //tolua_export + int GetChunkY(void) const {return m_ChunkY; } //tolua_export + int GetChunkZ(void) const {return m_ChunkZ; } //tolua_export + + void SetPosX( const double & a_PosX ); //tolua_export + void SetPosY( const double & a_PosY ); //tolua_export + void SetPosZ( const double & a_PosZ ); //tolua_export + void SetPosition( const double & a_PosX, const double & a_PosY, const double & a_PosZ );//tolua_export + void SetPosition( const Vector3d & a_Pos ); //tolua_export + void SetRot( const Vector3f & a_Rot ); //tolua_export + void SetRotation( float a_Rotation ); //tolua_export + void SetPitch( float a_Pitch ); //tolua_export + void SetRoll( float a_Roll ); //tolua_export + + inline int GetUniqueID(void) const { return m_UniqueID; } //tolua_export + inline bool IsDestroyed(void) const { return m_bDestroyed; } //tolua_export + + void Destroy(); //tolua_export + void RemoveFromChunk(void); // for internal use in cChunk + + virtual void Tick(float a_Dt) = 0; //tolua_export + + virtual cPacket * GetSpawnPacket(void) const {ASSERT(!"GetSpawnedPacket unimplemented!"); return NULL; }; // _X: Needs to be implemented due to Lua bindings + void SpawnOn (cClientHandle * a_Client); // tolua_export + + void WrapRotation(); + +protected: + virtual void Destroyed() {} // Called after the entity has been destroyed + + void SetWorld( cWorld* a_World ) { m_World = a_World; } + void MoveToCorrectChunk(bool a_bIgnoreOldChunk = false); + + friend class cReferenceManager; + void AddReference( cEntity*& a_EntityPtr ); + void ReferencedBy( cEntity*& a_EntityPtr ); + void Dereference( cEntity*& a_EntityPtr ); + + static cCriticalSection m_CSCount; + static int m_EntityCount; + + int m_UniqueID; + + cReferenceManager* m_Referencers; + cReferenceManager* m_References; + + int m_ChunkX, m_ChunkY, m_ChunkZ; + Vector3d m_Pos; + bool m_bDirtyPosition; + + Vector3f m_Rot; + bool m_bDirtyOrientation; + + bool m_bDestroyed; + bool m_bRemovedFromChunk; + + eEntityType m_EntityType; + + cWorld* m_World; +}; //tolua_export + +typedef std::list cEntityList; + + + + diff --git a/source/cEvent.cpp b/source/cEvent.cpp index cc476400f..a94fa83bc 100644 --- a/source/cEvent.cpp +++ b/source/cEvent.cpp @@ -1,118 +1,118 @@ - -// cEvent.cpp - -// Implements the cEvent object representing an OS-specific synchronization primitive that can be waited-for -// Implemented as an Event on Win and as a 1-semaphore on *nix - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cEvent.h" - - - - - -cEvent::cEvent(void) -{ -#ifdef _WIN32 - m_Event = CreateEvent( 0, FALSE, FALSE, 0 ); - if (m_Event == NULL) - { - LOGERROR("cEvent: cannot create event, GLE = %d. Aborting server.", GetLastError()); - abort(); - } -#else // *nix - m_bIsNamed = false; - m_Event = new sem_t; - if (sem_init(m_Event, 0, 0)) - { - // This path is used by MacOS, because it doesn't support unnamed semaphores. - delete m_Event; - m_bIsNamed = true; - - AString EventName; - Printf(EventName, "cEvent%p", this); - m_Event = sem_open(EventName.c_str(), O_CREAT, 777, 0 ); - if (m_Event == SEM_FAILED) - { - LOGERROR("cEvent: Cannot create event, errno = %i. Aborting server.", errno); - abort(); - } - // Unlink the semaphore immediately - it will continue to function but will not pollute the namespace - // We don't store the name, so can't call this in the destructor - if (sem_unlink(EventName.c_str()) != 0) - { - LOGWARN("ERROR: Could not unlink cEvent. (%i)", errno); - } - } -#endif // *nix -} - - - - - -cEvent::~cEvent() -{ -#ifdef _WIN32 - CloseHandle(m_Event); -#else - if (m_bIsNamed) - { - if (sem_close(m_Event) != 0) - { - LOGERROR("ERROR: Could not close cEvent. (%i)", errno); - } - } - else - { - sem_destroy(m_Event); - delete m_Event; - } -#endif -} - - - - - -void cEvent::Wait(void) -{ -#ifdef _WIN32 - DWORD res = WaitForSingleObject(m_Event, INFINITE); - if (res != WAIT_OBJECT_0) - { - LOGWARN("cEvent: waiting for the event failed: %d, GLE = %d. Continuing, but server may be unstable.", res, GetLastError()); - } -#else - int res = sem_wait(m_Event); - if (res != 0 ) - { - LOGWARN("cEvent: waiting for the event failed: %i, errno = %i. Continuing, but server may be unstable.", res, errno); - } -#endif -} - - - - - -void cEvent::Set(void) -{ -#ifdef _WIN32 - if (!SetEvent(m_Event)) - { - LOGWARN("cEvent: Could not set cEvent: GLE = %d", GetLastError()); - } -#else - int res = sem_post(m_Event); - if (res != 0) - { - LOGWARN("cEvent: Could not set cEvent: %i, errno = %d", res, errno); - } -#endif -} - - - - + +// cEvent.cpp + +// Implements the cEvent object representing an OS-specific synchronization primitive that can be waited-for +// Implemented as an Event on Win and as a 1-semaphore on *nix + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cEvent.h" + + + + + +cEvent::cEvent(void) +{ +#ifdef _WIN32 + m_Event = CreateEvent( 0, FALSE, FALSE, 0 ); + if (m_Event == NULL) + { + LOGERROR("cEvent: cannot create event, GLE = %d. Aborting server.", GetLastError()); + abort(); + } +#else // *nix + m_bIsNamed = false; + m_Event = new sem_t; + if (sem_init(m_Event, 0, 0)) + { + // This path is used by MacOS, because it doesn't support unnamed semaphores. + delete m_Event; + m_bIsNamed = true; + + AString EventName; + Printf(EventName, "cEvent%p", this); + m_Event = sem_open(EventName.c_str(), O_CREAT, 777, 0 ); + if (m_Event == SEM_FAILED) + { + LOGERROR("cEvent: Cannot create event, errno = %i. Aborting server.", errno); + abort(); + } + // Unlink the semaphore immediately - it will continue to function but will not pollute the namespace + // We don't store the name, so can't call this in the destructor + if (sem_unlink(EventName.c_str()) != 0) + { + LOGWARN("ERROR: Could not unlink cEvent. (%i)", errno); + } + } +#endif // *nix +} + + + + + +cEvent::~cEvent() +{ +#ifdef _WIN32 + CloseHandle(m_Event); +#else + if (m_bIsNamed) + { + if (sem_close(m_Event) != 0) + { + LOGERROR("ERROR: Could not close cEvent. (%i)", errno); + } + } + else + { + sem_destroy(m_Event); + delete m_Event; + } +#endif +} + + + + + +void cEvent::Wait(void) +{ +#ifdef _WIN32 + DWORD res = WaitForSingleObject(m_Event, INFINITE); + if (res != WAIT_OBJECT_0) + { + LOGWARN("cEvent: waiting for the event failed: %d, GLE = %d. Continuing, but server may be unstable.", res, GetLastError()); + } +#else + int res = sem_wait(m_Event); + if (res != 0 ) + { + LOGWARN("cEvent: waiting for the event failed: %i, errno = %i. Continuing, but server may be unstable.", res, errno); + } +#endif +} + + + + + +void cEvent::Set(void) +{ +#ifdef _WIN32 + if (!SetEvent(m_Event)) + { + LOGWARN("cEvent: Could not set cEvent: GLE = %d", GetLastError()); + } +#else + int res = sem_post(m_Event); + if (res != 0) + { + LOGWARN("cEvent: Could not set cEvent: %i, errno = %d", res, errno); + } +#endif +} + + + + diff --git a/source/cEvent.h b/source/cEvent.h index 11b9d7098..bc1505a11 100644 --- a/source/cEvent.h +++ b/source/cEvent.h @@ -1,47 +1,47 @@ - -// cEvent.h - -// Interfaces to the cEvent object representing an OS-specific synchronization primitive that can be waited-for -// Implemented as an Event on Win and as a 1-semaphore on *nix - - - - - -#pragma once -#ifndef CEVENT_H_INCLUDED -#define CEVENT_H_INCLUDED - - - - - -class cEvent -{ -public: - cEvent(void); - ~cEvent(); - - void Wait(void); - void Set (void); - -private: - - #ifdef _WIN32 - HANDLE m_Event; - #else - sem_t * m_Event; - bool m_bIsNamed; - #endif -} ; - - - - - - -#endif // CEVENT_H_INCLUDED - - - - + +// cEvent.h + +// Interfaces to the cEvent object representing an OS-specific synchronization primitive that can be waited-for +// Implemented as an Event on Win and as a 1-semaphore on *nix + + + + + +#pragma once +#ifndef CEVENT_H_INCLUDED +#define CEVENT_H_INCLUDED + + + + + +class cEvent +{ +public: + cEvent(void); + ~cEvent(); + + void Wait(void); + void Set (void); + +private: + + #ifdef _WIN32 + HANDLE m_Event; + #else + sem_t * m_Event; + bool m_bIsNamed; + #endif +} ; + + + + + + +#endif // CEVENT_H_INCLUDED + + + + diff --git a/source/cFile.cpp b/source/cFile.cpp index cd61800e2..32de28fe0 100644 --- a/source/cFile.cpp +++ b/source/cFile.cpp @@ -1,271 +1,271 @@ - -// cFile.cpp - -// Implements the cFile class providing an OS-independent abstraction of a file. - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cFile.h" - - - - - - -/// Simple constructor - creates an unopened file object, use Open() to open / create a real file -cFile::cFile(void) : - #ifdef USE_STDIO_FILE - m_File(NULL) - #else - m_File(INVALID_HANDLE_VALUE) - #endif // USE_STDIO_FILE -{ - // Nothing needed yet -} - - - - - -/// Constructs and opens / creates the file specified, use IsOpen() to check for success -cFile::cFile(const AString & iFileName, EMode iMode) : - #ifdef USE_STDIO_FILE - m_File(NULL) - #else - m_File(INVALID_HANDLE_VALUE) - #endif // USE_STDIO_FILE -{ - Open(iFileName, iMode); -} - - - - - -/// Auto-closes the file, if open -cFile::~cFile() -{ - if (IsOpen()) - { - Close(); - } -} - - - - - -bool cFile::Open(const AString & iFileName, EMode iMode) -{ - ASSERT(!IsOpen()); // You should close the file before opening another one - - if (IsOpen()) - { - Close(); - } - - const char * Mode = NULL; - switch (iMode) - { - case fmRead: Mode = "rb"; break; - case fmWrite: Mode = "wb"; break; - case fmReadWrite: Mode = "rb+"; break; - default: - { - ASSERT(!"Unhandled file mode"); - return false; - } - } - m_File = fopen(iFileName.c_str(), Mode); - if ((m_File == NULL) && (iMode == fmReadWrite)) - { - // Fix for MS not following C spec, opening "a" mode files for writing at the end only - // The file open operation has been tried with "read update", fails if file not found - // So now we know either the file doesn't exist or we don't have rights, no need to worry about file contents. - // Simply re-open for read-writing, erasing existing contents: - m_File = fopen(iFileName.c_str(), "wb+"); - } - return (m_File != NULL); -} - - - - - -void cFile::Close(void) -{ - ASSERT(IsOpen()); // You should not close file objects that don't have an open file. - - if (!IsOpen()) - { - return; - } - - fclose(m_File); - m_File = NULL; -} - - - - - -bool cFile::IsOpen(void) const -{ - return (m_File != NULL); -} - - - - - -bool cFile::IsEOF(void) const -{ - ASSERT(IsOpen()); - - if (!IsOpen()) - { - // Unopened files behave as at EOF - return true; - } - - return (feof(m_File) != 0); -} - - - - - -/// Reads up to iNumBytes bytes into iBuffer, returns the number of bytes actually read, or -1 on failure; asserts if not open -int cFile::Read (void * iBuffer, int iNumBytes) -{ - ASSERT(IsOpen()); - - if (!IsOpen()) - { - return -1; - } - - return fread(iBuffer, 1, iNumBytes, m_File); // fread() returns the portion of Count parameter actually read, so we need to send iNumBytes as Count -} - - - - - -/// Writes up to iNumBytes bytes from iBuffer, returns the number of bytes actually written, or -1 on failure; asserts if not open -int cFile::Write(const void * iBuffer, int iNumBytes) -{ - ASSERT(IsOpen()); - - if (!IsOpen()) - { - return -1; - } - - int res = fwrite(iBuffer, 1, iNumBytes, m_File); // fwrite() returns the portion of Count parameter actually written, so we need to send iNumBytes as Count - return res; -} - - - - - -/// Seeks to iPosition bytes from file start, returns old position or -1 for failure -int cFile::Seek (int iPosition) -{ - ASSERT(IsOpen()); - - if (!IsOpen()) - { - return -1; - } - - if (fseek(m_File, iPosition, SEEK_SET) != 0) - { - return -1; - } - return ftell(m_File); -} - - - - - - -/// Returns the current position (bytes from file start) -int cFile::Tell (void) const -{ - ASSERT(IsOpen()); - - if (!IsOpen()) - { - return -1; - } - - return ftell(m_File); -} - - - - - -/// Returns the size of file, in bytes, or -1 for failure; asserts if not open -int cFile::GetSize(void) const -{ - ASSERT(IsOpen()); - - if (!IsOpen()) - { - return -1; - } - - int CurPos = ftell(m_File); - if (CurPos < 0) - { - return -1; - } - if (fseek(m_File, 0, SEEK_END) != 0) - { - return -1; - } - int res = ftell(m_File); - if (fseek(m_File, CurPos, SEEK_SET) != 0) - { - return -1; - } - return res; -} - - - - - -int cFile::ReadRestOfFile(AString & a_Contents) -{ - ASSERT(IsOpen()); - - if (!IsOpen()) - { - return -1; - } - - int DataSize = GetSize() - Tell(); - - // HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly - a_Contents.assign(DataSize, '\0'); - return Read((void *)a_Contents.data(), DataSize); -} - - - - - -bool cFile::Exists(const AString & a_FileName) -{ - cFile test(a_FileName, fmRead); - return test.IsOpen(); -} - - - - + +// cFile.cpp + +// Implements the cFile class providing an OS-independent abstraction of a file. + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cFile.h" + + + + + + +/// Simple constructor - creates an unopened file object, use Open() to open / create a real file +cFile::cFile(void) : + #ifdef USE_STDIO_FILE + m_File(NULL) + #else + m_File(INVALID_HANDLE_VALUE) + #endif // USE_STDIO_FILE +{ + // Nothing needed yet +} + + + + + +/// Constructs and opens / creates the file specified, use IsOpen() to check for success +cFile::cFile(const AString & iFileName, EMode iMode) : + #ifdef USE_STDIO_FILE + m_File(NULL) + #else + m_File(INVALID_HANDLE_VALUE) + #endif // USE_STDIO_FILE +{ + Open(iFileName, iMode); +} + + + + + +/// Auto-closes the file, if open +cFile::~cFile() +{ + if (IsOpen()) + { + Close(); + } +} + + + + + +bool cFile::Open(const AString & iFileName, EMode iMode) +{ + ASSERT(!IsOpen()); // You should close the file before opening another one + + if (IsOpen()) + { + Close(); + } + + const char * Mode = NULL; + switch (iMode) + { + case fmRead: Mode = "rb"; break; + case fmWrite: Mode = "wb"; break; + case fmReadWrite: Mode = "rb+"; break; + default: + { + ASSERT(!"Unhandled file mode"); + return false; + } + } + m_File = fopen(iFileName.c_str(), Mode); + if ((m_File == NULL) && (iMode == fmReadWrite)) + { + // Fix for MS not following C spec, opening "a" mode files for writing at the end only + // The file open operation has been tried with "read update", fails if file not found + // So now we know either the file doesn't exist or we don't have rights, no need to worry about file contents. + // Simply re-open for read-writing, erasing existing contents: + m_File = fopen(iFileName.c_str(), "wb+"); + } + return (m_File != NULL); +} + + + + + +void cFile::Close(void) +{ + ASSERT(IsOpen()); // You should not close file objects that don't have an open file. + + if (!IsOpen()) + { + return; + } + + fclose(m_File); + m_File = NULL; +} + + + + + +bool cFile::IsOpen(void) const +{ + return (m_File != NULL); +} + + + + + +bool cFile::IsEOF(void) const +{ + ASSERT(IsOpen()); + + if (!IsOpen()) + { + // Unopened files behave as at EOF + return true; + } + + return (feof(m_File) != 0); +} + + + + + +/// Reads up to iNumBytes bytes into iBuffer, returns the number of bytes actually read, or -1 on failure; asserts if not open +int cFile::Read (void * iBuffer, int iNumBytes) +{ + ASSERT(IsOpen()); + + if (!IsOpen()) + { + return -1; + } + + return fread(iBuffer, 1, iNumBytes, m_File); // fread() returns the portion of Count parameter actually read, so we need to send iNumBytes as Count +} + + + + + +/// Writes up to iNumBytes bytes from iBuffer, returns the number of bytes actually written, or -1 on failure; asserts if not open +int cFile::Write(const void * iBuffer, int iNumBytes) +{ + ASSERT(IsOpen()); + + if (!IsOpen()) + { + return -1; + } + + int res = fwrite(iBuffer, 1, iNumBytes, m_File); // fwrite() returns the portion of Count parameter actually written, so we need to send iNumBytes as Count + return res; +} + + + + + +/// Seeks to iPosition bytes from file start, returns old position or -1 for failure +int cFile::Seek (int iPosition) +{ + ASSERT(IsOpen()); + + if (!IsOpen()) + { + return -1; + } + + if (fseek(m_File, iPosition, SEEK_SET) != 0) + { + return -1; + } + return ftell(m_File); +} + + + + + + +/// Returns the current position (bytes from file start) +int cFile::Tell (void) const +{ + ASSERT(IsOpen()); + + if (!IsOpen()) + { + return -1; + } + + return ftell(m_File); +} + + + + + +/// Returns the size of file, in bytes, or -1 for failure; asserts if not open +int cFile::GetSize(void) const +{ + ASSERT(IsOpen()); + + if (!IsOpen()) + { + return -1; + } + + int CurPos = ftell(m_File); + if (CurPos < 0) + { + return -1; + } + if (fseek(m_File, 0, SEEK_END) != 0) + { + return -1; + } + int res = ftell(m_File); + if (fseek(m_File, CurPos, SEEK_SET) != 0) + { + return -1; + } + return res; +} + + + + + +int cFile::ReadRestOfFile(AString & a_Contents) +{ + ASSERT(IsOpen()); + + if (!IsOpen()) + { + return -1; + } + + int DataSize = GetSize() - Tell(); + + // HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly + a_Contents.assign(DataSize, '\0'); + return Read((void *)a_Contents.data(), DataSize); +} + + + + + +bool cFile::Exists(const AString & a_FileName) +{ + cFile test(a_FileName, fmRead); + return test.IsOpen(); +} + + + + diff --git a/source/cFile.h b/source/cFile.h index 567c98219..373d69958 100644 --- a/source/cFile.h +++ b/source/cFile.h @@ -1,108 +1,108 @@ - -// cFile.h - -// Interfaces to the cFile class providing an OS-independent abstraction of a file. - -/* -The object is optimized towards binary reads. -The object has no multithreading locks, don't use from multiple threads! -Usage: -1, Construct a cFile instance (no-param constructor) -2, Open a file using Open(), check return value for success -3, Read / write -4, Destroy the instance - --- OR -- - -1, Construct a cFile instance opening the file (filename-param constructor) -2, Check if the file was opened using IsOpen() -3, Read / write -4, Destroy the instance -*/ - - - - - -#pragma once -#ifndef CFILE_H_INCLUDED -#define CFILE_H_INCLUDED - - - - - -#ifndef _WIN32 - #define USE_STDIO_FILE -#endif // _WIN32 - -// DEBUG: -#define USE_STDIO_FILE - - - - - -class cFile -{ -public: - /// The mode in which to open the file - enum EMode - { - fmRead, // Read-only. If the file doesn't exist, object will not be valid - fmWrite, // Write-only. If the file already exists, it will be overwritten - fmReadWrite, // Read/write. If the file already exists, it will be left intact; writing will overwrite the data from the beginning - } ; - - /// Simple constructor - creates an unopened file object, use Open() to open / create a real file - cFile(void); - - /// Constructs and opens / creates the file specified, use IsOpen() to check for success - cFile(const AString & iFileName, EMode iMode); - - /// Auto-closes the file, if open - ~cFile(); - - bool Open(const AString & iFileName, EMode iMode); - void Close(void); - bool IsOpen(void) const; - bool IsEOF(void) const; - - /// Reads up to iNumBytes bytes into iBuffer, returns the number of bytes actually read, or -1 on failure; asserts if not open - int Read (void * iBuffer, int iNumBytes); - - /// Writes up to iNumBytes bytes from iBuffer, returns the number of bytes actually written, or -1 on failure; asserts if not open - int Write(const void * iBuffer, int iNumBytes); - - /// Seeks to iPosition bytes from file start, returns old position or -1 for failure; asserts if not open - int Seek (int iPosition); - - /// Returns the current position (bytes from file start) or -1 for failure; asserts if not open - int Tell (void) const; - - /// Returns the size of file, in bytes, or -1 for failure; asserts if not open - int GetSize(void) const; - - /// Reads the file from current position till EOF into an AString; returns the number of bytes read or -1 for error - int ReadRestOfFile(AString & a_Contents); - - /// Returns true if the file specified exists - static bool Exists(const AString & a_FileName); - -private: - #ifdef USE_STDIO_FILE - FILE * m_File; - #else - HANDLE m_File; - #endif -} ; - - - - - -#endif // CFILE_H_INCLUDED - - - - + +// cFile.h + +// Interfaces to the cFile class providing an OS-independent abstraction of a file. + +/* +The object is optimized towards binary reads. +The object has no multithreading locks, don't use from multiple threads! +Usage: +1, Construct a cFile instance (no-param constructor) +2, Open a file using Open(), check return value for success +3, Read / write +4, Destroy the instance + +-- OR -- + +1, Construct a cFile instance opening the file (filename-param constructor) +2, Check if the file was opened using IsOpen() +3, Read / write +4, Destroy the instance +*/ + + + + + +#pragma once +#ifndef CFILE_H_INCLUDED +#define CFILE_H_INCLUDED + + + + + +#ifndef _WIN32 + #define USE_STDIO_FILE +#endif // _WIN32 + +// DEBUG: +#define USE_STDIO_FILE + + + + + +class cFile +{ +public: + /// The mode in which to open the file + enum EMode + { + fmRead, // Read-only. If the file doesn't exist, object will not be valid + fmWrite, // Write-only. If the file already exists, it will be overwritten + fmReadWrite, // Read/write. If the file already exists, it will be left intact; writing will overwrite the data from the beginning + } ; + + /// Simple constructor - creates an unopened file object, use Open() to open / create a real file + cFile(void); + + /// Constructs and opens / creates the file specified, use IsOpen() to check for success + cFile(const AString & iFileName, EMode iMode); + + /// Auto-closes the file, if open + ~cFile(); + + bool Open(const AString & iFileName, EMode iMode); + void Close(void); + bool IsOpen(void) const; + bool IsEOF(void) const; + + /// Reads up to iNumBytes bytes into iBuffer, returns the number of bytes actually read, or -1 on failure; asserts if not open + int Read (void * iBuffer, int iNumBytes); + + /// Writes up to iNumBytes bytes from iBuffer, returns the number of bytes actually written, or -1 on failure; asserts if not open + int Write(const void * iBuffer, int iNumBytes); + + /// Seeks to iPosition bytes from file start, returns old position or -1 for failure; asserts if not open + int Seek (int iPosition); + + /// Returns the current position (bytes from file start) or -1 for failure; asserts if not open + int Tell (void) const; + + /// Returns the size of file, in bytes, or -1 for failure; asserts if not open + int GetSize(void) const; + + /// Reads the file from current position till EOF into an AString; returns the number of bytes read or -1 for error + int ReadRestOfFile(AString & a_Contents); + + /// Returns true if the file specified exists + static bool Exists(const AString & a_FileName); + +private: + #ifdef USE_STDIO_FILE + FILE * m_File; + #else + HANDLE m_File; + #endif +} ; + + + + + +#endif // CFILE_H_INCLUDED + + + + diff --git a/source/cFileFormatUpdater.cpp b/source/cFileFormatUpdater.cpp index b58239eb2..3991ede34 100644 --- a/source/cFileFormatUpdater.cpp +++ b/source/cFileFormatUpdater.cpp @@ -1,143 +1,143 @@ - -#include "Globals.h" - -#include "cFileFormatUpdater.h" -#include "Vector3d.h" -#include "Vector3f.h" - -#include "cItem.h" -#include - - - - - -void cFileFormatUpdater::UpdateFileFormat() -{ - UpdatePlayersOfWorld("world"); -} - - - - - -// Convert player .bin files to JSON -void cFileFormatUpdater::UpdatePlayersOfWorld( const char* a_WorldName ) -{ - AString PlayerDir = AString( a_WorldName ) + "/player/"; - - AStringList AllFiles = GetDirectoryContents( PlayerDir.c_str() ); - for (AStringList::iterator itr = AllFiles.begin(); itr != AllFiles.end(); ++itr ) - { - AString & FileName = *itr; - if (FileName.rfind(".bin") != AString::npos) // Get only the files ending in .bin - { - PlayerBINtoJSON( (PlayerDir + FileName).c_str() ); - } - } -} - - - - - -#define READ(File, Var) \ - if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \ - { \ - LOGERROR("ERROR READING \"%s\" FROM FILE \"%s\"", #Var, a_FileName); \ - return; \ - } - -// Converts player binary files to human readable JSON -void cFileFormatUpdater::PlayerBINtoJSON( const char* a_FileName ) -{ - Vector3d PlayerPos; - Vector3f PlayerRot; - short PlayerHealth = 0; - - const unsigned int NumInventorySlots = 45; // At this time the player inventory has/had 45 slots - cItem IventoryItems[ NumInventorySlots ]; - - cFile f; - if (!f.Open(a_FileName, cFile::fmRead)) - { - return; - } - - // First read player position, rotation and health - READ(f, PlayerPos.x); - READ(f, PlayerPos.y); - READ(f, PlayerPos.z); - READ(f, PlayerRot.x); - READ(f, PlayerRot.y); - READ(f, PlayerRot.z); - READ(f, PlayerHealth); - - - for(unsigned int i = 0; i < NumInventorySlots; i++) - { - cItem & Item = IventoryItems[i]; - READ(f, Item.m_ItemID); - READ(f, Item.m_ItemCount); - READ(f, Item.m_ItemHealth); - } - f.Close(); - - // Loaded all the data, now create the JSON data - Json::Value JSON_PlayerPosition; - JSON_PlayerPosition.append( Json::Value( PlayerPos.x ) ); - JSON_PlayerPosition.append( Json::Value( PlayerPos.y ) ); - JSON_PlayerPosition.append( Json::Value( PlayerPos.z ) ); - - Json::Value JSON_PlayerRotation; - JSON_PlayerRotation.append( Json::Value( PlayerRot.x ) ); - JSON_PlayerRotation.append( Json::Value( PlayerRot.y ) ); - JSON_PlayerRotation.append( Json::Value( PlayerRot.z ) ); - - Json::Value JSON_Inventory; - for(unsigned int i = 0; i < NumInventorySlots; i++) - { - Json::Value JSON_Item; - IventoryItems[i].GetJson( JSON_Item ); - JSON_Inventory.append( JSON_Item ); - } - - Json::Value root; - root["position"] = JSON_PlayerPosition; - root["rotation"] = JSON_PlayerRotation; - root["inventory"] = JSON_Inventory; - root["health"] = PlayerHealth; - - Json::StyledWriter writer; - std::string JsonData = writer.write( root ); - - // Get correct filename - std::string FileName = a_FileName; - std::string FileNameWithoutExt = FileName.substr(0, FileName.find_last_of(".") ); - std::string FileNameJson = FileNameWithoutExt + ".json"; - - // Write to file - if (!f.Open(FileNameJson.c_str(), cFile::fmWrite)) - { - return; - } - if (f.Write(JsonData.c_str(), JsonData.size()) != JsonData.size()) - { - LOGERROR("ERROR WRITING PLAYER JSON TO FILE \"%s\"", FileNameJson.c_str()); - return; - } - f.Close(); - - // Delete old format file, only do this when conversion has succeeded - if (std::remove(a_FileName) != 0) - { - LOGERROR("COULD NOT DELETE old format file \"%s\"", a_FileName); - return; - } - - LOGINFO("Successfully converted binary to Json \"%s\"", FileNameJson.c_str() ); -} - - - - + +#include "Globals.h" + +#include "cFileFormatUpdater.h" +#include "Vector3d.h" +#include "Vector3f.h" + +#include "cItem.h" +#include + + + + + +void cFileFormatUpdater::UpdateFileFormat() +{ + UpdatePlayersOfWorld("world"); +} + + + + + +// Convert player .bin files to JSON +void cFileFormatUpdater::UpdatePlayersOfWorld( const char* a_WorldName ) +{ + AString PlayerDir = AString( a_WorldName ) + "/player/"; + + AStringList AllFiles = GetDirectoryContents( PlayerDir.c_str() ); + for (AStringList::iterator itr = AllFiles.begin(); itr != AllFiles.end(); ++itr ) + { + AString & FileName = *itr; + if (FileName.rfind(".bin") != AString::npos) // Get only the files ending in .bin + { + PlayerBINtoJSON( (PlayerDir + FileName).c_str() ); + } + } +} + + + + + +#define READ(File, Var) \ + if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \ + { \ + LOGERROR("ERROR READING \"%s\" FROM FILE \"%s\"", #Var, a_FileName); \ + return; \ + } + +// Converts player binary files to human readable JSON +void cFileFormatUpdater::PlayerBINtoJSON( const char* a_FileName ) +{ + Vector3d PlayerPos; + Vector3f PlayerRot; + short PlayerHealth = 0; + + const unsigned int NumInventorySlots = 45; // At this time the player inventory has/had 45 slots + cItem IventoryItems[ NumInventorySlots ]; + + cFile f; + if (!f.Open(a_FileName, cFile::fmRead)) + { + return; + } + + // First read player position, rotation and health + READ(f, PlayerPos.x); + READ(f, PlayerPos.y); + READ(f, PlayerPos.z); + READ(f, PlayerRot.x); + READ(f, PlayerRot.y); + READ(f, PlayerRot.z); + READ(f, PlayerHealth); + + + for(unsigned int i = 0; i < NumInventorySlots; i++) + { + cItem & Item = IventoryItems[i]; + READ(f, Item.m_ItemID); + READ(f, Item.m_ItemCount); + READ(f, Item.m_ItemHealth); + } + f.Close(); + + // Loaded all the data, now create the JSON data + Json::Value JSON_PlayerPosition; + JSON_PlayerPosition.append( Json::Value( PlayerPos.x ) ); + JSON_PlayerPosition.append( Json::Value( PlayerPos.y ) ); + JSON_PlayerPosition.append( Json::Value( PlayerPos.z ) ); + + Json::Value JSON_PlayerRotation; + JSON_PlayerRotation.append( Json::Value( PlayerRot.x ) ); + JSON_PlayerRotation.append( Json::Value( PlayerRot.y ) ); + JSON_PlayerRotation.append( Json::Value( PlayerRot.z ) ); + + Json::Value JSON_Inventory; + for(unsigned int i = 0; i < NumInventorySlots; i++) + { + Json::Value JSON_Item; + IventoryItems[i].GetJson( JSON_Item ); + JSON_Inventory.append( JSON_Item ); + } + + Json::Value root; + root["position"] = JSON_PlayerPosition; + root["rotation"] = JSON_PlayerRotation; + root["inventory"] = JSON_Inventory; + root["health"] = PlayerHealth; + + Json::StyledWriter writer; + std::string JsonData = writer.write( root ); + + // Get correct filename + std::string FileName = a_FileName; + std::string FileNameWithoutExt = FileName.substr(0, FileName.find_last_of(".") ); + std::string FileNameJson = FileNameWithoutExt + ".json"; + + // Write to file + if (!f.Open(FileNameJson.c_str(), cFile::fmWrite)) + { + return; + } + if (f.Write(JsonData.c_str(), JsonData.size()) != JsonData.size()) + { + LOGERROR("ERROR WRITING PLAYER JSON TO FILE \"%s\"", FileNameJson.c_str()); + return; + } + f.Close(); + + // Delete old format file, only do this when conversion has succeeded + if (std::remove(a_FileName) != 0) + { + LOGERROR("COULD NOT DELETE old format file \"%s\"", a_FileName); + return; + } + + LOGINFO("Successfully converted binary to Json \"%s\"", FileNameJson.c_str() ); +} + + + + diff --git a/source/cFileFormatUpdater.h b/source/cFileFormatUpdater.h index fc6beed6e..91e2761fb 100644 --- a/source/cFileFormatUpdater.h +++ b/source/cFileFormatUpdater.h @@ -1,11 +1,11 @@ -#pragma once - -class cFileFormatUpdater -{ -public: - static void UpdateFileFormat(); -private: - static void UpdatePlayersOfWorld( const char* a_WorldName ); - - static void PlayerBINtoJSON( const char* a_FileName ); +#pragma once + +class cFileFormatUpdater +{ +public: + static void UpdateFileFormat(); +private: + static void UpdatePlayersOfWorld( const char* a_WorldName ); + + static void PlayerBINtoJSON( const char* a_FileName ); }; \ No newline at end of file diff --git a/source/cFireSimulator.cpp b/source/cFireSimulator.cpp index 0d6b59422..8b6710b74 100644 --- a/source/cFireSimulator.cpp +++ b/source/cFireSimulator.cpp @@ -1,132 +1,132 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cFireSimulator.h" -#include "cWorld.h" -#include "Vector3i.h" -#include "BlockID.h" -#include "Defines.h" - -cFireSimulator::cFireSimulator( cWorld* a_World ) - : cSimulator(a_World) - , m_Blocks(new BlockList) - , m_Buffer(new BlockList) - , m_BurningBlocks(new BlockList) -{ - -} - -cFireSimulator::~cFireSimulator() -{ - delete m_Buffer; - delete m_Blocks; - delete m_BurningBlocks; -} - -void cFireSimulator::Simulate( float a_Dt ) -{ - m_Buffer->clear(); - std::swap( m_Blocks, m_Buffer ); - - for( BlockList::iterator itr = m_Buffer->begin(); itr != m_Buffer->end(); ++itr ) - { - Vector3i Pos = *itr; - - char BlockID = m_World->GetBlock(Pos.x, Pos.y, Pos.z); - - if(!IsAllowedBlock(BlockID)) //Check wheather the block is still burning - continue; - - if(BurnBlockAround(Pos.x, Pos.y, Pos.z)) //Burn single block and if there was one -> next time again - _AddBlock(Pos.x, Pos.y, Pos.z); - else - if(!IsForeverBurnable(m_World->GetBlock(Pos.x, Pos.y - 1, Pos.z)) && !FiresForever(BlockID)) - m_World->SetBlock(Pos.x, Pos.y, Pos.z, E_BLOCK_AIR, 0); - - } - -} - - -bool cFireSimulator::IsAllowedBlock( char a_BlockID ) -{ - return a_BlockID == E_BLOCK_FIRE - || IsBlockLava(a_BlockID); -} - -void cFireSimulator::AddBlock(int a_X, int a_Y, int a_Z) -{ - char BlockID = m_World->GetBlock(a_X, a_Y, a_Z); - if(!IsAllowedBlock(BlockID)) //This should save very much time because it doesn´t have to iterate through all blocks - return; - - //check for duplicates - for( BlockList::iterator itr = m_Blocks->begin(); itr != m_Blocks->end(); ++itr ) - { - Vector3i Pos = *itr; - if( Pos.x == a_X && Pos.y == a_Y && Pos.z == a_Z ) - return; - } - - _AddBlock(a_X, a_Y, a_Z); - -} - -void cFireSimulator::_AddBlock(int a_X, int a_Y, int a_Z) -{ - m_Blocks->push_back( Vector3i(a_X, a_Y, a_Z) ); - -} - -bool cFireSimulator::IsForeverBurnable( char a_BlockID ) -{ - return a_BlockID == E_BLOCK_BLOODSTONE; -} - -bool cFireSimulator::IsBurnable( char a_BlockID ) -{ - return a_BlockID == E_BLOCK_PLANKS - || a_BlockID == E_BLOCK_LEAVES - || a_BlockID == E_BLOCK_LOG - || a_BlockID == E_BLOCK_WHITE_CLOTH - || a_BlockID == E_BLOCK_BOOKCASE - || a_BlockID == E_BLOCK_FENCE - || a_BlockID == E_BLOCK_TNT; -} - -bool cFireSimulator::FiresForever( char a_BlockID ) -{ - return a_BlockID != E_BLOCK_FIRE; -} - -bool cFireSimulator::BurnBlockAround(int a_X, int a_Y, int a_Z) -{ - return BurnBlock(a_X + 1, a_Y, a_Z) - || BurnBlock(a_X - 1, a_Y, a_Z) - || BurnBlock(a_X, a_Y + 1, a_Z) - || BurnBlock(a_X, a_Y - 1, a_Z) - || BurnBlock(a_X, a_Y, a_Z + 1) - || BurnBlock(a_X, a_Y, a_Z - 1); -} - -bool cFireSimulator::BurnBlock(int a_X, int a_Y, int a_Z) -{ - char BlockID = m_World->GetBlock(a_X, a_Y, a_Z); - if(IsBurnable(BlockID)) - { - m_World->SetBlock(a_X, a_Y, a_Z, E_BLOCK_FIRE, 0); - return true; - } - if(IsForeverBurnable(BlockID)) - { - char BlockAbove = m_World->GetBlock(a_X, a_Y + 1, a_Z); - if(BlockAbove == E_BLOCK_AIR) - { - m_World->SetBlock(a_X, a_Y + 1, a_Z, E_BLOCK_FIRE, 0); //Doesn´t notify the simulator so it won´t go off - return true; - } - return false; - } - - return false; + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cFireSimulator.h" +#include "cWorld.h" +#include "Vector3i.h" +#include "BlockID.h" +#include "Defines.h" + +cFireSimulator::cFireSimulator( cWorld* a_World ) + : cSimulator(a_World) + , m_Blocks(new BlockList) + , m_Buffer(new BlockList) + , m_BurningBlocks(new BlockList) +{ + +} + +cFireSimulator::~cFireSimulator() +{ + delete m_Buffer; + delete m_Blocks; + delete m_BurningBlocks; +} + +void cFireSimulator::Simulate( float a_Dt ) +{ + m_Buffer->clear(); + std::swap( m_Blocks, m_Buffer ); + + for( BlockList::iterator itr = m_Buffer->begin(); itr != m_Buffer->end(); ++itr ) + { + Vector3i Pos = *itr; + + char BlockID = m_World->GetBlock(Pos.x, Pos.y, Pos.z); + + if(!IsAllowedBlock(BlockID)) //Check wheather the block is still burning + continue; + + if(BurnBlockAround(Pos.x, Pos.y, Pos.z)) //Burn single block and if there was one -> next time again + _AddBlock(Pos.x, Pos.y, Pos.z); + else + if(!IsForeverBurnable(m_World->GetBlock(Pos.x, Pos.y - 1, Pos.z)) && !FiresForever(BlockID)) + m_World->SetBlock(Pos.x, Pos.y, Pos.z, E_BLOCK_AIR, 0); + + } + +} + + +bool cFireSimulator::IsAllowedBlock( char a_BlockID ) +{ + return a_BlockID == E_BLOCK_FIRE + || IsBlockLava(a_BlockID); +} + +void cFireSimulator::AddBlock(int a_X, int a_Y, int a_Z) +{ + char BlockID = m_World->GetBlock(a_X, a_Y, a_Z); + if(!IsAllowedBlock(BlockID)) //This should save very much time because it doesn´t have to iterate through all blocks + return; + + //check for duplicates + for( BlockList::iterator itr = m_Blocks->begin(); itr != m_Blocks->end(); ++itr ) + { + Vector3i Pos = *itr; + if( Pos.x == a_X && Pos.y == a_Y && Pos.z == a_Z ) + return; + } + + _AddBlock(a_X, a_Y, a_Z); + +} + +void cFireSimulator::_AddBlock(int a_X, int a_Y, int a_Z) +{ + m_Blocks->push_back( Vector3i(a_X, a_Y, a_Z) ); + +} + +bool cFireSimulator::IsForeverBurnable( char a_BlockID ) +{ + return a_BlockID == E_BLOCK_BLOODSTONE; +} + +bool cFireSimulator::IsBurnable( char a_BlockID ) +{ + return a_BlockID == E_BLOCK_PLANKS + || a_BlockID == E_BLOCK_LEAVES + || a_BlockID == E_BLOCK_LOG + || a_BlockID == E_BLOCK_WHITE_CLOTH + || a_BlockID == E_BLOCK_BOOKCASE + || a_BlockID == E_BLOCK_FENCE + || a_BlockID == E_BLOCK_TNT; +} + +bool cFireSimulator::FiresForever( char a_BlockID ) +{ + return a_BlockID != E_BLOCK_FIRE; +} + +bool cFireSimulator::BurnBlockAround(int a_X, int a_Y, int a_Z) +{ + return BurnBlock(a_X + 1, a_Y, a_Z) + || BurnBlock(a_X - 1, a_Y, a_Z) + || BurnBlock(a_X, a_Y + 1, a_Z) + || BurnBlock(a_X, a_Y - 1, a_Z) + || BurnBlock(a_X, a_Y, a_Z + 1) + || BurnBlock(a_X, a_Y, a_Z - 1); +} + +bool cFireSimulator::BurnBlock(int a_X, int a_Y, int a_Z) +{ + char BlockID = m_World->GetBlock(a_X, a_Y, a_Z); + if(IsBurnable(BlockID)) + { + m_World->SetBlock(a_X, a_Y, a_Z, E_BLOCK_FIRE, 0); + return true; + } + if(IsForeverBurnable(BlockID)) + { + char BlockAbove = m_World->GetBlock(a_X, a_Y + 1, a_Z); + if(BlockAbove == E_BLOCK_AIR) + { + m_World->SetBlock(a_X, a_Y + 1, a_Z, E_BLOCK_FIRE, 0); //Doesn´t notify the simulator so it won´t go off + return true; + } + return false; + } + + return false; } \ No newline at end of file diff --git a/source/cFireSimulator.h b/source/cFireSimulator.h index f66fb2019..5c6a3aeaa 100644 --- a/source/cFireSimulator.h +++ b/source/cFireSimulator.h @@ -1,47 +1,47 @@ - -#pragma once - -#include "cSimulator.h" -#include "cBlockEntity.h" - - - - - -class Vector3i; -class cWorld; - - - - - -class cFireSimulator : public cSimulator -{ -public: - cFireSimulator( cWorld* a_World ); - ~cFireSimulator(); - - virtual void Simulate( float a_Dt ); - - virtual bool IsAllowedBlock( char a_BlockID ); - - virtual bool IsBurnable( char a_BlockID ); - virtual bool IsForeverBurnable( char a_BlockID ); - virtual bool FiresForever( char a_BlockID ); - -protected: - virtual void AddBlock(int a_X, int a_Y, int a_Z); - virtual void _AddBlock(int a_X, int a_Y, int a_Z); - virtual bool BurnBlockAround(int a_X, int a_Y, int a_Z); - virtual bool BurnBlock(int a_X, int a_Y, int a_Z); - - typedef std::list BlockList; - BlockList *m_Blocks; - BlockList *m_Buffer; - - BlockList *m_BurningBlocks; -}; - - - - + +#pragma once + +#include "cSimulator.h" +#include "cBlockEntity.h" + + + + + +class Vector3i; +class cWorld; + + + + + +class cFireSimulator : public cSimulator +{ +public: + cFireSimulator( cWorld* a_World ); + ~cFireSimulator(); + + virtual void Simulate( float a_Dt ); + + virtual bool IsAllowedBlock( char a_BlockID ); + + virtual bool IsBurnable( char a_BlockID ); + virtual bool IsForeverBurnable( char a_BlockID ); + virtual bool FiresForever( char a_BlockID ); + +protected: + virtual void AddBlock(int a_X, int a_Y, int a_Z); + virtual void _AddBlock(int a_X, int a_Y, int a_Z); + virtual bool BurnBlockAround(int a_X, int a_Y, int a_Z); + virtual bool BurnBlock(int a_X, int a_Y, int a_Z); + + typedef std::list BlockList; + BlockList *m_Blocks; + BlockList *m_Buffer; + + BlockList *m_BurningBlocks; +}; + + + + diff --git a/source/cFluidSimulator.cpp b/source/cFluidSimulator.cpp index 38bf55d77..1301caa8c 100644 --- a/source/cFluidSimulator.cpp +++ b/source/cFluidSimulator.cpp @@ -1,688 +1,688 @@ -#include "Globals.h" - -#include -#include - -#include "cFluidSimulator.h" -#include "cWorld.h" -#include "Vector3i.h" -#include "BlockID.h" -#include "Defines.h" -#include "cItem.h" -#include "cBlockToPickup.h" - - - - - -//#define DEBUG_FLUID -#ifdef DEBUG_FLUID -#define LOG_FLUID(...) LOGWARN( __VA_ARGS__ ) -#else -#define LOG_FLUID(...) -#endif - - - - - -class cFluidSimulator::FluidData -{ -public: - FluidData( cWorld* a_World, cFluidSimulator *a_Simulator ) - : m_ActiveFluid( new std::set < Vector3i >() ) - , m_Simulator (a_Simulator) - , m_Buffer( new std::set< Vector3i >() ) - , m_World( a_World ) - {} - - ~FluidData() - { - delete m_Buffer; - delete m_ActiveFluid; - } - - void UpdateWave(Vector3i a_LeftCorner, Vector3i a_CurBlock) - { - Vector3i LevelPoints [] = { - Vector3i( a_CurBlock.x-1, a_CurBlock.y, a_CurBlock.z ), - Vector3i( a_CurBlock.x+1, a_CurBlock.y, a_CurBlock.z ), - Vector3i( a_CurBlock.x, a_CurBlock.y, a_CurBlock.z-1 ), - Vector3i( a_CurBlock.x, a_CurBlock.y, a_CurBlock.z+1 ), - }; - - for(int i=0; i<4; i++) - { - Vector3i cur = LevelPoints[i]; - switch(m_Relief[cur.x][cur.z]) - { - case E_HOLE: - { - m_StartSide[cur.x][cur.z] = m_StartSide[a_CurBlock.x][a_CurBlock.z]; - m_CurResult|=m_StartSide[cur.x][cur.z]; - m_NearestHole = m_WayLength[a_CurBlock.x][a_CurBlock.z] + 1; - LOG_FLUID("Hole found: %d \t curResult: %d", int(m_StartSide[cur.x][cur.z]), int(m_CurResult) ); - LOG_FLUID("Coordinates: (%d, %d)", cur.x, cur.z); - }break; - - case E_BLOCK: - {}break; - - case E_PLAIN: - { - if (m_WayLength[cur.x][cur.z] > m_WayLength[a_CurBlock.x][a_CurBlock.z] + 1) - { - m_WayLength[cur.x][cur.z] = m_WayLength[a_CurBlock.x][a_CurBlock.z] + 1; - m_StartSide[cur.x][cur.z] = m_StartSide[a_CurBlock.x][a_CurBlock.z]; - m_WaveQueue.push(cur); - } - else if(m_WayLength[cur.x][cur.z] == m_WayLength[a_CurBlock.x][a_CurBlock.z] + 1) - { - m_StartSide[cur.x][cur.z] |= m_StartSide[a_CurBlock.x][a_CurBlock.z]; - } - LOG_FLUID("Plain step: (%d, %d) from %d", cur.x, cur.z, m_StartSide[cur.x][cur.z]); - } - } - } - } - - std::vector< Vector3i > GetLowestPoints( int a_X, int a_Y, int a_Z ) - { - - std::vector< Vector3i > Points; //result - - Vector3i CornerGlobal(a_X - AREA_WIDTH/2, a_Y, a_Z - AREA_WIDTH/2); - - //TODO: rewrite without relief, get blocks directly in algorithm - for(int x=0; xGetBlock( CornerGlobal.x + x, CornerGlobal.y, CornerGlobal.z + z ); - char DownBlock = m_World->GetBlock( CornerGlobal.x + x, CornerGlobal.y-1, CornerGlobal.z + z ); - - if(m_Simulator->IsSolidBlock(UpperBlock)||(m_Simulator->IsStationaryBlock(UpperBlock))) - { - m_Relief[x][z] = E_BLOCK; - } - else if(m_Simulator->IsSolidBlock(DownBlock)) - { - m_Relief[x][z] = E_PLAIN; - } - else - { - m_Relief[x][z] = E_HOLE; - } - m_WayLength[x][z] = 255; - m_StartSide[x][z] = E_SIDE_NONE; - } - LOG_FLUID("%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t", m_Relief[x][0], m_Relief[x][1], m_Relief[x][2], m_Relief[x][3], m_Relief[x][4], m_Relief[x][5], m_Relief[x][6], m_Relief[x][7], m_Relief[x][8], m_Relief[x][9], m_Relief[x][10]); - } - - m_NearestHole = 5; - m_CurResult = 0; - while(!m_WaveQueue.empty()) m_WaveQueue.pop(); - - int left = AREA_WIDTH/2 - 1; - int right = AREA_WIDTH/2 + 1; - int center = AREA_WIDTH/2; - - Vector3i r(right, 0, center); //right block - Vector3i l(left, 0, center); //left block - Vector3i f(center, 0, right); //front block - Vector3i b(center, 0, left); //back block - Vector3i c(center, 0, center); //center block - - m_WayLength[c.x][c.z] = 0; - - Vector3i Nearest[] = {r, l, f, b}; - unsigned char Sides[] = {E_SIDE_RIGHT, E_SIDE_LEFT, E_SIDE_FRONT, E_SIDE_BACK}; - - for(int i=0; i<4; i++) - { - Vector3i cur = Nearest[i]; - switch(m_Relief[cur.x][cur.z]) - { - case E_HOLE: - { - m_StartSide[cur.x][cur.z] = Sides[i]; - m_CurResult |= m_StartSide[cur.x][cur.z]; - m_NearestHole = 1; - LOG_FLUID("Hole found: %d \t curResult: %d", int(Sides[i]), int(m_CurResult) ); - }break; - - case E_BLOCK: - {}break; - - case E_PLAIN: - { - m_WaveQueue.push(cur); - m_StartSide[cur.x][cur.z] = Sides[i]; - m_WayLength[cur.x][cur.z] = 1; - LOG_FLUID("Plain found: %d", int(Sides[i])); - } - } - } - - Vector3i curBlock; - - bool bContinue = !m_WaveQueue.empty(); - - if(!m_WaveQueue.empty()) - { - curBlock = m_WaveQueue.front(); - bContinue = (m_WayLength[curBlock.x][curBlock.z] < m_NearestHole); - } - - while(bContinue) - { - LOG_FLUID("while iteration" ); - curBlock = m_WaveQueue.front(); - UpdateWave(CornerGlobal, curBlock); - m_WaveQueue.pop(); - - bContinue = ( (!m_WaveQueue.empty()) && (m_WayLength[m_WaveQueue.front().x][m_WaveQueue.front().z] < m_NearestHole) ); - } - - - - if(m_CurResult & E_SIDE_LEFT) Points.push_back(Vector3i( a_X-1, a_Y, a_Z )); - if(m_CurResult & E_SIDE_RIGHT) Points.push_back(Vector3i( a_X+1, a_Y, a_Z )); - if(m_CurResult & E_SIDE_FRONT) Points.push_back(Vector3i( a_X, a_Y, a_Z+1 )); - if(m_CurResult & E_SIDE_BACK) Points.push_back(Vector3i( a_X, a_Y, a_Z-1 )); - - if(Points.empty()) - { - Vector3i LevelPoints [] = { - Vector3i( a_X-1, a_Y, a_Z ), - Vector3i( a_X+1, a_Y, a_Z ), - Vector3i( a_X, a_Y, a_Z-1 ), - Vector3i( a_X, a_Y, a_Z+1 ), - }; - for( int i = 0; i < 4; ++i ) - { - char Block = m_World->GetBlock( LevelPoints[i].x, a_Y, LevelPoints[i].z ); - if( m_Simulator->IsPassableForFluid(Block) ) - Points.push_back( LevelPoints[i] ); - } - } - - return Points; - } - - std::set< Vector3i >* m_ActiveFluid; - std::set< Vector3i >* m_Buffer; - cWorld* m_World; - cFluidSimulator *m_Simulator; - - const static int AREA_WIDTH = 11; - - const static unsigned char E_SIDE_RIGHT = 0x10; - const static unsigned char E_SIDE_LEFT = 0x20; - const static unsigned char E_SIDE_FRONT = 0x40; - const static unsigned char E_SIDE_BACK = 0x80; - const static unsigned char E_SIDE_NONE = 0x00; - - enum eRelief {E_HOLE = 0, E_PLAIN = 1, E_BLOCK = 2}; - - eRelief m_Relief[AREA_WIDTH][AREA_WIDTH]; - unsigned char m_WayLength[AREA_WIDTH][AREA_WIDTH]; - unsigned char m_StartSide[AREA_WIDTH][AREA_WIDTH]; - - std::queue m_WaveQueue; - - int m_NearestHole; - unsigned char m_CurResult; -}; - - - - - -cFluidSimulator::cFluidSimulator( cWorld* a_World ) - : cSimulator(a_World) - , m_Data(0) -{ - m_Data = new FluidData(a_World, this); -} - - - - - -cFluidSimulator::~cFluidSimulator() -{ - delete m_Data; -} - - - - - -void cFluidSimulator::AddBlock( int a_X, int a_Y, int a_Z ) -{ - char BlockType = m_World->GetBlock(a_X, a_Y, a_Z); - if (!IsAllowedBlock(BlockType)) //This should save very much time because it doesn´t have to iterate through all blocks - { - return; - } - - std::set< Vector3i > & ActiveFluid = *m_Data->m_ActiveFluid; - ActiveFluid.insert( Vector3i( a_X, a_Y, a_Z ) ); -} - - - - - -char cFluidSimulator::GetHighestLevelAround( int a_X, int a_Y, int a_Z ) -{ - char Max = m_MaxHeight + m_FlowReduction; - -#define __HIGHLEVEL_CHECK__( x, y, z ) \ - if( IsAllowedBlock( m_World->GetBlock( x, y, z ) ) ) \ - { \ - char Meta; \ - if( (Meta = m_World->GetBlockMeta( x, y, z ) ) < Max ) Max = Meta; \ - else if( Meta == m_MaxHeight + m_FlowReduction ) Max = 0; \ - if( Max == 0 ) return 0; \ - } - - __HIGHLEVEL_CHECK__( a_X-1, a_Y, a_Z ); - __HIGHLEVEL_CHECK__( a_X+1, a_Y, a_Z ); - __HIGHLEVEL_CHECK__( a_X, a_Y, a_Z-1 ); - __HIGHLEVEL_CHECK__( a_X, a_Y, a_Z+1 ); - - return Max; -} - - - - - -void cFluidSimulator::Simulate( float a_Dt ) -{ - m_Timer += a_Dt; - - if (m_Data->m_ActiveFluid->empty()) //Nothing to do if there is no active fluid ;) saves very little time ;D - { - return; - } - - std::swap( m_Data->m_ActiveFluid, m_Data->m_Buffer ); // Swap so blocks can be added to empty ActiveFluid array - m_Data->m_ActiveFluid->clear(); - - std::set< Vector3i > & FluidBlocks = *m_Data->m_Buffer; - for( std::set< Vector3i >::iterator itr = FluidBlocks.begin(); itr != FluidBlocks.end(); ++itr ) - { - const Vector3i & pos = *itr; - - if(UniqueSituation(pos)) - { - continue; - } - - char BlockID = m_World->GetBlock( pos.x, pos.y, pos.z ); - if( IsAllowedBlock( BlockID ) ) // only care about own fluid - { - bool bIsFed = false; - char Meta = m_World->GetBlockMeta( pos.x, pos.y, pos.z ); - char Feed = Meta; - if( BlockID == m_StationaryFluidBlock) Meta = 0; - if( Meta == 8 ) // Falling fluid - { - if( IsAllowedBlock( m_World->GetBlock(pos.x, pos.y+1, pos.z) ) ) // Block above is fluid - { - bIsFed = true; - Meta = 0; // Make it a full block - } - } - else if( Meta < m_FlowReduction ) // It's a full block, so it's always fed - { - bIsFed = true; - } - else - { - if( (Feed = GetHighestLevelAround( pos.x, pos.y, pos.z )) < Meta ) - bIsFed = true; - } - - - if( bIsFed ) - { - char DownID = m_World->GetBlock( pos.x, pos.y-1, pos.z ); - bool bWashedAwayItem = CanWashAway( DownID ); - if( (IsPassableForFluid(DownID) || bWashedAwayItem) && !IsStationaryBlock(DownID) ) // free for fluid - { - if( bWashedAwayItem ) - { - cItems Drops; - cBlockToPickup::ToPickup(DownID, m_World->GetBlockMeta(pos.x, pos.y - 1, pos.z), E_ITEM_EMPTY, Drops); - m_World->SpawnItemPickups(Drops, pos.x, pos.y - 1, pos.z); - } - if (pos.y > 0) - { - m_World->FastSetBlock( pos.x, pos.y-1, pos.z, m_FluidBlock, 8 ); // falling - AddBlock( pos.x, pos.y-1, pos.z ); - ApplyUniqueToNearest(pos - Vector3i(0, 1, 0)); - } - } - if(IsSolidBlock(DownID)||( BlockID == m_StationaryFluidBlock)) // Not falling - { - if( Feed + m_FlowReduction < Meta ) - { - m_World->FastSetBlock( pos.x, pos.y, pos.z, m_FluidBlock, Feed + m_FlowReduction ); - AddBlock( pos.x, pos.y, pos.z ); - ApplyUniqueToNearest(pos); - } - else if(( Meta < m_MaxHeight )||( BlockID == m_StationaryFluidBlock)) // max is the lowest, so it cannot spread - { - std::vector< Vector3i > Points = m_Data->GetLowestPoints( pos.x, pos.y, pos.z ); - for( std::vector< Vector3i >::iterator itr = Points.begin(); itr != Points.end(); ++itr ) - { - Vector3i & p = *itr; - char BlockID = m_World->GetBlock( p.x, p.y, p.z ); - bool bWashedAwayItem = CanWashAway( BlockID ); - - if (!IsPassableForFluid(BlockID)) continue; - - if (!IsAllowedBlock(BlockID)) - { - if (bWashedAwayItem) - { - cItems Drops; - cBlockToPickup::ToPickup(DownID, m_World->GetBlockMeta(p.x, p.y, p.z), E_ITEM_EMPTY, Drops); - m_World->SpawnItemPickups(Drops, p.x, p.y, p.z); - } - - if( p.y == pos.y ) - { - m_World->FastSetBlock(p.x, p.y, p.z, m_FluidBlock, Meta + m_FlowReduction); - } - else - { - m_World->FastSetBlock(p.x, p.y, p.z, m_FluidBlock, 8); - } - AddBlock( p.x, p.y, p.z ); - ApplyUniqueToNearest(p); - } - else // it's fluid - { - char PointMeta = m_World->GetBlockMeta( p.x, p.y, p.z ); - if( PointMeta > Meta + m_FlowReduction ) - { - AddBlock( p.x, p.y, p.z ); - ApplyUniqueToNearest(p); - } - } - } - } - } - } - else// not fed - { - m_World->FastSetBlock( pos.x, pos.y, pos.z, E_BLOCK_AIR, 0 ); - WakeUp( pos.x, pos.y, pos.z ); - } - } - } -} - - - - - -bool cFluidSimulator::IsPassableForFluid(char a_BlockID) -{ - return a_BlockID == E_BLOCK_AIR - || a_BlockID == E_BLOCK_FIRE - || IsAllowedBlock(a_BlockID) - || CanWashAway(a_BlockID); -} - - - - - -bool cFluidSimulator::IsStationaryBlock (char a_BlockID) -{ - return a_BlockID == m_StationaryFluidBlock; -} - - - - - -bool cFluidSimulator::CanWashAway( char a_BlockID ) -{ - switch( a_BlockID ) - { - case E_BLOCK_YELLOW_FLOWER: - case E_BLOCK_RED_ROSE: - case E_BLOCK_RED_MUSHROOM: - case E_BLOCK_BROWN_MUSHROOM: - case E_BLOCK_CACTUS: - return true; - default: - return false; - }; -} - - - - - -bool cFluidSimulator::IsSolidBlock( char a_BlockID ) -{ - return !(a_BlockID == E_BLOCK_AIR - || a_BlockID == E_BLOCK_FIRE - || IsBlockLava(a_BlockID) - || IsBlockWater(a_BlockID) - || CanWashAway(a_BlockID)); -} - - - - - -//TODO Not working very well yet :s -Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a_Over) -{ - char BlockID = m_World->GetBlock(a_X, a_Y, a_Z); - if(!IsAllowedBlock(BlockID)) //No Fluid -> No Flowing direction :D - return NONE; - - - /* - Disabled because of causing problems and beeing useless atm - char BlockBelow = m_World->GetBlock(a_X, a_Y - 1, a_Z); //If there is nothing or fluid below it -> dominating flow is down :D - if(BlockBelow == E_BLOCK_AIR || IsAllowedBlock(BlockBelow)) - return Y_MINUS; - */ - - char LowestPoint = m_World->GetBlockMeta(a_X, a_Y, a_Z); //Current Block Meta so only lower points will be counted - int X = 0, Y = 0, Z = 0; //Lowest Pos will be stored here - - if(IsAllowedBlock(m_World->GetBlock(a_X, a_Y + 1, a_Z)) && a_Over) //check for upper block to flow because this also affects the flowing direction - { - return GetFlowingDirection(a_X, a_Y + 1, a_Z, false); - } - - std::vector< Vector3i * > Points; - - Points.reserve(4); //Already allocate 4 places :D - - //add blocks around the checking pos - Points.push_back(new Vector3i(a_X - 1, a_Y, a_Z)); - Points.push_back(new Vector3i(a_X + 1, a_Y, a_Z)); - Points.push_back(new Vector3i(a_X, a_Y, a_Z + 1)); - Points.push_back(new Vector3i(a_X, a_Y, a_Z - 1)); - - for(std::vector::iterator it = Points.begin(); it < Points.end(); it++) - { - Vector3i *Pos = (*it); - char BlockID = m_World->GetBlock(Pos->x, Pos->y, Pos->z); - if(IsAllowedBlock(BlockID)) - { - char Meta = m_World->GetBlockMeta(Pos->x, Pos->y, Pos->z); - - if(Meta > LowestPoint) - { - LowestPoint = Meta; - X = Pos->x; - Y = Pos->y; - Z = Pos->z; - } - }else if(BlockID == E_BLOCK_AIR) - { - LowestPoint = 9; //This always dominates - X = Pos->x; - Y = Pos->y; - Z = Pos->z; - - } - delete Pos; - } - - if(LowestPoint == m_World->GetBlockMeta(a_X, a_Y, a_Z)) - return NONE; - - if(a_X - X > 0) - { - return X_MINUS; - } - - if(a_X - X < 0) - { - return X_PLUS; - } - - if(a_Z - Z > 0) - { - return Z_MINUS; - } - - if(a_Z - Z < 0) - { - return Z_PLUS; - } - - return NONE; -} - - - - - -bool cFluidSimulator::UniqueSituation(Vector3i a_Pos) -{ - bool result = false; - - char BlockId = m_World->GetBlock( a_Pos.x, a_Pos.y, a_Pos.z ); - char Meta = m_World->GetBlockMeta( a_Pos.x, a_Pos.y, a_Pos.z ); - - if(IsBlockWater(BlockId)) - { - - char UpperBlock = m_World->GetBlock( a_Pos.x, a_Pos.y + 1, a_Pos.z ); - if(IsBlockLava(UpperBlock)) - { - m_World->SetBlock(a_Pos.x, a_Pos.y, a_Pos.z, E_BLOCK_STONE, 0); - } - - - if(BlockId != E_BLOCK_STATIONARY_WATER) - { - char DownBlockId = m_World->GetBlock( a_Pos.x, a_Pos.y-1, a_Pos.z ); - if(IsSolidBlock(DownBlockId)) - { - Vector3i LevelPoints [] = { - Vector3i( a_Pos.x-1, a_Pos.y, a_Pos.z ), - Vector3i( a_Pos.x+1, a_Pos.y, a_Pos.z ), - Vector3i( a_Pos.x, a_Pos.y, a_Pos.z-1 ), - Vector3i( a_Pos.x, a_Pos.y, a_Pos.z+1 ), - }; - int SourceBlocksCount = 0; - for(int i=0; i<4; i++) - { - if (m_World->GetBlock(LevelPoints[i].x, LevelPoints[i].y, LevelPoints[i].z)==E_BLOCK_STATIONARY_WATER) - { - SourceBlocksCount++; - } - } - if(SourceBlocksCount>=2) - { - m_World->SetBlock(a_Pos.x, a_Pos.y, a_Pos.z, E_BLOCK_STATIONARY_WATER, 0); - } - } - - } - } - - if(IsBlockLava(BlockId)) - { - bool bWater = false; - - char UpperBlock = m_World->GetBlock( a_Pos.x, a_Pos.y + 1, a_Pos.z ); - if (IsBlockWater(UpperBlock)) - { - bWater = true; - } - else - { - Vector3i LevelPoints [] = { - Vector3i( a_Pos.x-1, a_Pos.y, a_Pos.z ), - Vector3i( a_Pos.x+1, a_Pos.y, a_Pos.z ), - Vector3i( a_Pos.x, a_Pos.y, a_Pos.z-1 ), - Vector3i( a_Pos.x, a_Pos.y, a_Pos.z+1 ), - }; - - for(int i=0; i<4; i++) - { - if (IsBlockWater(m_World->GetBlock(LevelPoints[i].x, LevelPoints[i].y, LevelPoints[i].z))) - { - bWater = true; - } - } - } - - - if(bWater) - { - if(BlockId == E_BLOCK_STATIONARY_LAVA) - { - m_World->SetBlock(a_Pos.x, a_Pos.y, a_Pos.z, E_BLOCK_OBSIDIAN, 0); - } - else if (MetaSetBlock(a_Pos.x, a_Pos.y, a_Pos.z, E_BLOCK_COBBLESTONE, 0); - } - } - } - - return result; -} - - - - - -void cFluidSimulator::ApplyUniqueToNearest(Vector3i a_Pos) -{ - Vector3i NearPoints [] = { - Vector3i( a_Pos.x-1, a_Pos.y, a_Pos.z ), - Vector3i( a_Pos.x+1, a_Pos.y, a_Pos.z ), - Vector3i( a_Pos.x, a_Pos.y, a_Pos.z-1 ), - Vector3i( a_Pos.x, a_Pos.y, a_Pos.z+1 ), - Vector3i( a_Pos.x, a_Pos.y-1, a_Pos.z ) - }; - - for(int i=0; i<5; i++) - { - UniqueSituation(NearPoints[i]); - } -} - - - - +#include "Globals.h" + +#include +#include + +#include "cFluidSimulator.h" +#include "cWorld.h" +#include "Vector3i.h" +#include "BlockID.h" +#include "Defines.h" +#include "cItem.h" +#include "cBlockToPickup.h" + + + + + +//#define DEBUG_FLUID +#ifdef DEBUG_FLUID +#define LOG_FLUID(...) LOGWARN( __VA_ARGS__ ) +#else +#define LOG_FLUID(...) +#endif + + + + + +class cFluidSimulator::FluidData +{ +public: + FluidData( cWorld* a_World, cFluidSimulator *a_Simulator ) + : m_ActiveFluid( new std::set < Vector3i >() ) + , m_Simulator (a_Simulator) + , m_Buffer( new std::set< Vector3i >() ) + , m_World( a_World ) + {} + + ~FluidData() + { + delete m_Buffer; + delete m_ActiveFluid; + } + + void UpdateWave(Vector3i a_LeftCorner, Vector3i a_CurBlock) + { + Vector3i LevelPoints [] = { + Vector3i( a_CurBlock.x-1, a_CurBlock.y, a_CurBlock.z ), + Vector3i( a_CurBlock.x+1, a_CurBlock.y, a_CurBlock.z ), + Vector3i( a_CurBlock.x, a_CurBlock.y, a_CurBlock.z-1 ), + Vector3i( a_CurBlock.x, a_CurBlock.y, a_CurBlock.z+1 ), + }; + + for(int i=0; i<4; i++) + { + Vector3i cur = LevelPoints[i]; + switch(m_Relief[cur.x][cur.z]) + { + case E_HOLE: + { + m_StartSide[cur.x][cur.z] = m_StartSide[a_CurBlock.x][a_CurBlock.z]; + m_CurResult|=m_StartSide[cur.x][cur.z]; + m_NearestHole = m_WayLength[a_CurBlock.x][a_CurBlock.z] + 1; + LOG_FLUID("Hole found: %d \t curResult: %d", int(m_StartSide[cur.x][cur.z]), int(m_CurResult) ); + LOG_FLUID("Coordinates: (%d, %d)", cur.x, cur.z); + }break; + + case E_BLOCK: + {}break; + + case E_PLAIN: + { + if (m_WayLength[cur.x][cur.z] > m_WayLength[a_CurBlock.x][a_CurBlock.z] + 1) + { + m_WayLength[cur.x][cur.z] = m_WayLength[a_CurBlock.x][a_CurBlock.z] + 1; + m_StartSide[cur.x][cur.z] = m_StartSide[a_CurBlock.x][a_CurBlock.z]; + m_WaveQueue.push(cur); + } + else if(m_WayLength[cur.x][cur.z] == m_WayLength[a_CurBlock.x][a_CurBlock.z] + 1) + { + m_StartSide[cur.x][cur.z] |= m_StartSide[a_CurBlock.x][a_CurBlock.z]; + } + LOG_FLUID("Plain step: (%d, %d) from %d", cur.x, cur.z, m_StartSide[cur.x][cur.z]); + } + } + } + } + + std::vector< Vector3i > GetLowestPoints( int a_X, int a_Y, int a_Z ) + { + + std::vector< Vector3i > Points; //result + + Vector3i CornerGlobal(a_X - AREA_WIDTH/2, a_Y, a_Z - AREA_WIDTH/2); + + //TODO: rewrite without relief, get blocks directly in algorithm + for(int x=0; xGetBlock( CornerGlobal.x + x, CornerGlobal.y, CornerGlobal.z + z ); + char DownBlock = m_World->GetBlock( CornerGlobal.x + x, CornerGlobal.y-1, CornerGlobal.z + z ); + + if(m_Simulator->IsSolidBlock(UpperBlock)||(m_Simulator->IsStationaryBlock(UpperBlock))) + { + m_Relief[x][z] = E_BLOCK; + } + else if(m_Simulator->IsSolidBlock(DownBlock)) + { + m_Relief[x][z] = E_PLAIN; + } + else + { + m_Relief[x][z] = E_HOLE; + } + m_WayLength[x][z] = 255; + m_StartSide[x][z] = E_SIDE_NONE; + } + LOG_FLUID("%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t", m_Relief[x][0], m_Relief[x][1], m_Relief[x][2], m_Relief[x][3], m_Relief[x][4], m_Relief[x][5], m_Relief[x][6], m_Relief[x][7], m_Relief[x][8], m_Relief[x][9], m_Relief[x][10]); + } + + m_NearestHole = 5; + m_CurResult = 0; + while(!m_WaveQueue.empty()) m_WaveQueue.pop(); + + int left = AREA_WIDTH/2 - 1; + int right = AREA_WIDTH/2 + 1; + int center = AREA_WIDTH/2; + + Vector3i r(right, 0, center); //right block + Vector3i l(left, 0, center); //left block + Vector3i f(center, 0, right); //front block + Vector3i b(center, 0, left); //back block + Vector3i c(center, 0, center); //center block + + m_WayLength[c.x][c.z] = 0; + + Vector3i Nearest[] = {r, l, f, b}; + unsigned char Sides[] = {E_SIDE_RIGHT, E_SIDE_LEFT, E_SIDE_FRONT, E_SIDE_BACK}; + + for(int i=0; i<4; i++) + { + Vector3i cur = Nearest[i]; + switch(m_Relief[cur.x][cur.z]) + { + case E_HOLE: + { + m_StartSide[cur.x][cur.z] = Sides[i]; + m_CurResult |= m_StartSide[cur.x][cur.z]; + m_NearestHole = 1; + LOG_FLUID("Hole found: %d \t curResult: %d", int(Sides[i]), int(m_CurResult) ); + }break; + + case E_BLOCK: + {}break; + + case E_PLAIN: + { + m_WaveQueue.push(cur); + m_StartSide[cur.x][cur.z] = Sides[i]; + m_WayLength[cur.x][cur.z] = 1; + LOG_FLUID("Plain found: %d", int(Sides[i])); + } + } + } + + Vector3i curBlock; + + bool bContinue = !m_WaveQueue.empty(); + + if(!m_WaveQueue.empty()) + { + curBlock = m_WaveQueue.front(); + bContinue = (m_WayLength[curBlock.x][curBlock.z] < m_NearestHole); + } + + while(bContinue) + { + LOG_FLUID("while iteration" ); + curBlock = m_WaveQueue.front(); + UpdateWave(CornerGlobal, curBlock); + m_WaveQueue.pop(); + + bContinue = ( (!m_WaveQueue.empty()) && (m_WayLength[m_WaveQueue.front().x][m_WaveQueue.front().z] < m_NearestHole) ); + } + + + + if(m_CurResult & E_SIDE_LEFT) Points.push_back(Vector3i( a_X-1, a_Y, a_Z )); + if(m_CurResult & E_SIDE_RIGHT) Points.push_back(Vector3i( a_X+1, a_Y, a_Z )); + if(m_CurResult & E_SIDE_FRONT) Points.push_back(Vector3i( a_X, a_Y, a_Z+1 )); + if(m_CurResult & E_SIDE_BACK) Points.push_back(Vector3i( a_X, a_Y, a_Z-1 )); + + if(Points.empty()) + { + Vector3i LevelPoints [] = { + Vector3i( a_X-1, a_Y, a_Z ), + Vector3i( a_X+1, a_Y, a_Z ), + Vector3i( a_X, a_Y, a_Z-1 ), + Vector3i( a_X, a_Y, a_Z+1 ), + }; + for( int i = 0; i < 4; ++i ) + { + char Block = m_World->GetBlock( LevelPoints[i].x, a_Y, LevelPoints[i].z ); + if( m_Simulator->IsPassableForFluid(Block) ) + Points.push_back( LevelPoints[i] ); + } + } + + return Points; + } + + std::set< Vector3i >* m_ActiveFluid; + std::set< Vector3i >* m_Buffer; + cWorld* m_World; + cFluidSimulator *m_Simulator; + + const static int AREA_WIDTH = 11; + + const static unsigned char E_SIDE_RIGHT = 0x10; + const static unsigned char E_SIDE_LEFT = 0x20; + const static unsigned char E_SIDE_FRONT = 0x40; + const static unsigned char E_SIDE_BACK = 0x80; + const static unsigned char E_SIDE_NONE = 0x00; + + enum eRelief {E_HOLE = 0, E_PLAIN = 1, E_BLOCK = 2}; + + eRelief m_Relief[AREA_WIDTH][AREA_WIDTH]; + unsigned char m_WayLength[AREA_WIDTH][AREA_WIDTH]; + unsigned char m_StartSide[AREA_WIDTH][AREA_WIDTH]; + + std::queue m_WaveQueue; + + int m_NearestHole; + unsigned char m_CurResult; +}; + + + + + +cFluidSimulator::cFluidSimulator( cWorld* a_World ) + : cSimulator(a_World) + , m_Data(0) +{ + m_Data = new FluidData(a_World, this); +} + + + + + +cFluidSimulator::~cFluidSimulator() +{ + delete m_Data; +} + + + + + +void cFluidSimulator::AddBlock( int a_X, int a_Y, int a_Z ) +{ + char BlockType = m_World->GetBlock(a_X, a_Y, a_Z); + if (!IsAllowedBlock(BlockType)) //This should save very much time because it doesn´t have to iterate through all blocks + { + return; + } + + std::set< Vector3i > & ActiveFluid = *m_Data->m_ActiveFluid; + ActiveFluid.insert( Vector3i( a_X, a_Y, a_Z ) ); +} + + + + + +char cFluidSimulator::GetHighestLevelAround( int a_X, int a_Y, int a_Z ) +{ + char Max = m_MaxHeight + m_FlowReduction; + +#define __HIGHLEVEL_CHECK__( x, y, z ) \ + if( IsAllowedBlock( m_World->GetBlock( x, y, z ) ) ) \ + { \ + char Meta; \ + if( (Meta = m_World->GetBlockMeta( x, y, z ) ) < Max ) Max = Meta; \ + else if( Meta == m_MaxHeight + m_FlowReduction ) Max = 0; \ + if( Max == 0 ) return 0; \ + } + + __HIGHLEVEL_CHECK__( a_X-1, a_Y, a_Z ); + __HIGHLEVEL_CHECK__( a_X+1, a_Y, a_Z ); + __HIGHLEVEL_CHECK__( a_X, a_Y, a_Z-1 ); + __HIGHLEVEL_CHECK__( a_X, a_Y, a_Z+1 ); + + return Max; +} + + + + + +void cFluidSimulator::Simulate( float a_Dt ) +{ + m_Timer += a_Dt; + + if (m_Data->m_ActiveFluid->empty()) //Nothing to do if there is no active fluid ;) saves very little time ;D + { + return; + } + + std::swap( m_Data->m_ActiveFluid, m_Data->m_Buffer ); // Swap so blocks can be added to empty ActiveFluid array + m_Data->m_ActiveFluid->clear(); + + std::set< Vector3i > & FluidBlocks = *m_Data->m_Buffer; + for( std::set< Vector3i >::iterator itr = FluidBlocks.begin(); itr != FluidBlocks.end(); ++itr ) + { + const Vector3i & pos = *itr; + + if(UniqueSituation(pos)) + { + continue; + } + + char BlockID = m_World->GetBlock( pos.x, pos.y, pos.z ); + if( IsAllowedBlock( BlockID ) ) // only care about own fluid + { + bool bIsFed = false; + char Meta = m_World->GetBlockMeta( pos.x, pos.y, pos.z ); + char Feed = Meta; + if( BlockID == m_StationaryFluidBlock) Meta = 0; + if( Meta == 8 ) // Falling fluid + { + if( IsAllowedBlock( m_World->GetBlock(pos.x, pos.y+1, pos.z) ) ) // Block above is fluid + { + bIsFed = true; + Meta = 0; // Make it a full block + } + } + else if( Meta < m_FlowReduction ) // It's a full block, so it's always fed + { + bIsFed = true; + } + else + { + if( (Feed = GetHighestLevelAround( pos.x, pos.y, pos.z )) < Meta ) + bIsFed = true; + } + + + if( bIsFed ) + { + char DownID = m_World->GetBlock( pos.x, pos.y-1, pos.z ); + bool bWashedAwayItem = CanWashAway( DownID ); + if( (IsPassableForFluid(DownID) || bWashedAwayItem) && !IsStationaryBlock(DownID) ) // free for fluid + { + if( bWashedAwayItem ) + { + cItems Drops; + cBlockToPickup::ToPickup(DownID, m_World->GetBlockMeta(pos.x, pos.y - 1, pos.z), E_ITEM_EMPTY, Drops); + m_World->SpawnItemPickups(Drops, pos.x, pos.y - 1, pos.z); + } + if (pos.y > 0) + { + m_World->FastSetBlock( pos.x, pos.y-1, pos.z, m_FluidBlock, 8 ); // falling + AddBlock( pos.x, pos.y-1, pos.z ); + ApplyUniqueToNearest(pos - Vector3i(0, 1, 0)); + } + } + if(IsSolidBlock(DownID)||( BlockID == m_StationaryFluidBlock)) // Not falling + { + if( Feed + m_FlowReduction < Meta ) + { + m_World->FastSetBlock( pos.x, pos.y, pos.z, m_FluidBlock, Feed + m_FlowReduction ); + AddBlock( pos.x, pos.y, pos.z ); + ApplyUniqueToNearest(pos); + } + else if(( Meta < m_MaxHeight )||( BlockID == m_StationaryFluidBlock)) // max is the lowest, so it cannot spread + { + std::vector< Vector3i > Points = m_Data->GetLowestPoints( pos.x, pos.y, pos.z ); + for( std::vector< Vector3i >::iterator itr = Points.begin(); itr != Points.end(); ++itr ) + { + Vector3i & p = *itr; + char BlockID = m_World->GetBlock( p.x, p.y, p.z ); + bool bWashedAwayItem = CanWashAway( BlockID ); + + if (!IsPassableForFluid(BlockID)) continue; + + if (!IsAllowedBlock(BlockID)) + { + if (bWashedAwayItem) + { + cItems Drops; + cBlockToPickup::ToPickup(DownID, m_World->GetBlockMeta(p.x, p.y, p.z), E_ITEM_EMPTY, Drops); + m_World->SpawnItemPickups(Drops, p.x, p.y, p.z); + } + + if( p.y == pos.y ) + { + m_World->FastSetBlock(p.x, p.y, p.z, m_FluidBlock, Meta + m_FlowReduction); + } + else + { + m_World->FastSetBlock(p.x, p.y, p.z, m_FluidBlock, 8); + } + AddBlock( p.x, p.y, p.z ); + ApplyUniqueToNearest(p); + } + else // it's fluid + { + char PointMeta = m_World->GetBlockMeta( p.x, p.y, p.z ); + if( PointMeta > Meta + m_FlowReduction ) + { + AddBlock( p.x, p.y, p.z ); + ApplyUniqueToNearest(p); + } + } + } + } + } + } + else// not fed + { + m_World->FastSetBlock( pos.x, pos.y, pos.z, E_BLOCK_AIR, 0 ); + WakeUp( pos.x, pos.y, pos.z ); + } + } + } +} + + + + + +bool cFluidSimulator::IsPassableForFluid(char a_BlockID) +{ + return a_BlockID == E_BLOCK_AIR + || a_BlockID == E_BLOCK_FIRE + || IsAllowedBlock(a_BlockID) + || CanWashAway(a_BlockID); +} + + + + + +bool cFluidSimulator::IsStationaryBlock (char a_BlockID) +{ + return a_BlockID == m_StationaryFluidBlock; +} + + + + + +bool cFluidSimulator::CanWashAway( char a_BlockID ) +{ + switch( a_BlockID ) + { + case E_BLOCK_YELLOW_FLOWER: + case E_BLOCK_RED_ROSE: + case E_BLOCK_RED_MUSHROOM: + case E_BLOCK_BROWN_MUSHROOM: + case E_BLOCK_CACTUS: + return true; + default: + return false; + }; +} + + + + + +bool cFluidSimulator::IsSolidBlock( char a_BlockID ) +{ + return !(a_BlockID == E_BLOCK_AIR + || a_BlockID == E_BLOCK_FIRE + || IsBlockLava(a_BlockID) + || IsBlockWater(a_BlockID) + || CanWashAway(a_BlockID)); +} + + + + + +//TODO Not working very well yet :s +Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a_Over) +{ + char BlockID = m_World->GetBlock(a_X, a_Y, a_Z); + if(!IsAllowedBlock(BlockID)) //No Fluid -> No Flowing direction :D + return NONE; + + + /* + Disabled because of causing problems and beeing useless atm + char BlockBelow = m_World->GetBlock(a_X, a_Y - 1, a_Z); //If there is nothing or fluid below it -> dominating flow is down :D + if(BlockBelow == E_BLOCK_AIR || IsAllowedBlock(BlockBelow)) + return Y_MINUS; + */ + + char LowestPoint = m_World->GetBlockMeta(a_X, a_Y, a_Z); //Current Block Meta so only lower points will be counted + int X = 0, Y = 0, Z = 0; //Lowest Pos will be stored here + + if(IsAllowedBlock(m_World->GetBlock(a_X, a_Y + 1, a_Z)) && a_Over) //check for upper block to flow because this also affects the flowing direction + { + return GetFlowingDirection(a_X, a_Y + 1, a_Z, false); + } + + std::vector< Vector3i * > Points; + + Points.reserve(4); //Already allocate 4 places :D + + //add blocks around the checking pos + Points.push_back(new Vector3i(a_X - 1, a_Y, a_Z)); + Points.push_back(new Vector3i(a_X + 1, a_Y, a_Z)); + Points.push_back(new Vector3i(a_X, a_Y, a_Z + 1)); + Points.push_back(new Vector3i(a_X, a_Y, a_Z - 1)); + + for(std::vector::iterator it = Points.begin(); it < Points.end(); it++) + { + Vector3i *Pos = (*it); + char BlockID = m_World->GetBlock(Pos->x, Pos->y, Pos->z); + if(IsAllowedBlock(BlockID)) + { + char Meta = m_World->GetBlockMeta(Pos->x, Pos->y, Pos->z); + + if(Meta > LowestPoint) + { + LowestPoint = Meta; + X = Pos->x; + Y = Pos->y; + Z = Pos->z; + } + }else if(BlockID == E_BLOCK_AIR) + { + LowestPoint = 9; //This always dominates + X = Pos->x; + Y = Pos->y; + Z = Pos->z; + + } + delete Pos; + } + + if(LowestPoint == m_World->GetBlockMeta(a_X, a_Y, a_Z)) + return NONE; + + if(a_X - X > 0) + { + return X_MINUS; + } + + if(a_X - X < 0) + { + return X_PLUS; + } + + if(a_Z - Z > 0) + { + return Z_MINUS; + } + + if(a_Z - Z < 0) + { + return Z_PLUS; + } + + return NONE; +} + + + + + +bool cFluidSimulator::UniqueSituation(Vector3i a_Pos) +{ + bool result = false; + + char BlockId = m_World->GetBlock( a_Pos.x, a_Pos.y, a_Pos.z ); + char Meta = m_World->GetBlockMeta( a_Pos.x, a_Pos.y, a_Pos.z ); + + if(IsBlockWater(BlockId)) + { + + char UpperBlock = m_World->GetBlock( a_Pos.x, a_Pos.y + 1, a_Pos.z ); + if(IsBlockLava(UpperBlock)) + { + m_World->SetBlock(a_Pos.x, a_Pos.y, a_Pos.z, E_BLOCK_STONE, 0); + } + + + if(BlockId != E_BLOCK_STATIONARY_WATER) + { + char DownBlockId = m_World->GetBlock( a_Pos.x, a_Pos.y-1, a_Pos.z ); + if(IsSolidBlock(DownBlockId)) + { + Vector3i LevelPoints [] = { + Vector3i( a_Pos.x-1, a_Pos.y, a_Pos.z ), + Vector3i( a_Pos.x+1, a_Pos.y, a_Pos.z ), + Vector3i( a_Pos.x, a_Pos.y, a_Pos.z-1 ), + Vector3i( a_Pos.x, a_Pos.y, a_Pos.z+1 ), + }; + int SourceBlocksCount = 0; + for(int i=0; i<4; i++) + { + if (m_World->GetBlock(LevelPoints[i].x, LevelPoints[i].y, LevelPoints[i].z)==E_BLOCK_STATIONARY_WATER) + { + SourceBlocksCount++; + } + } + if(SourceBlocksCount>=2) + { + m_World->SetBlock(a_Pos.x, a_Pos.y, a_Pos.z, E_BLOCK_STATIONARY_WATER, 0); + } + } + + } + } + + if(IsBlockLava(BlockId)) + { + bool bWater = false; + + char UpperBlock = m_World->GetBlock( a_Pos.x, a_Pos.y + 1, a_Pos.z ); + if (IsBlockWater(UpperBlock)) + { + bWater = true; + } + else + { + Vector3i LevelPoints [] = { + Vector3i( a_Pos.x-1, a_Pos.y, a_Pos.z ), + Vector3i( a_Pos.x+1, a_Pos.y, a_Pos.z ), + Vector3i( a_Pos.x, a_Pos.y, a_Pos.z-1 ), + Vector3i( a_Pos.x, a_Pos.y, a_Pos.z+1 ), + }; + + for(int i=0; i<4; i++) + { + if (IsBlockWater(m_World->GetBlock(LevelPoints[i].x, LevelPoints[i].y, LevelPoints[i].z))) + { + bWater = true; + } + } + } + + + if(bWater) + { + if(BlockId == E_BLOCK_STATIONARY_LAVA) + { + m_World->SetBlock(a_Pos.x, a_Pos.y, a_Pos.z, E_BLOCK_OBSIDIAN, 0); + } + else if (MetaSetBlock(a_Pos.x, a_Pos.y, a_Pos.z, E_BLOCK_COBBLESTONE, 0); + } + } + } + + return result; +} + + + + + +void cFluidSimulator::ApplyUniqueToNearest(Vector3i a_Pos) +{ + Vector3i NearPoints [] = { + Vector3i( a_Pos.x-1, a_Pos.y, a_Pos.z ), + Vector3i( a_Pos.x+1, a_Pos.y, a_Pos.z ), + Vector3i( a_Pos.x, a_Pos.y, a_Pos.z-1 ), + Vector3i( a_Pos.x, a_Pos.y, a_Pos.z+1 ), + Vector3i( a_Pos.x, a_Pos.y-1, a_Pos.z ) + }; + + for(int i=0; i<5; i++) + { + UniqueSituation(NearPoints[i]); + } +} + + + + diff --git a/source/cFluidSimulator.h b/source/cFluidSimulator.h index afacea5f7..4557d3ef1 100644 --- a/source/cFluidSimulator.h +++ b/source/cFluidSimulator.h @@ -1,55 +1,55 @@ -#pragma once - -#include "cSimulator.h" -#include "Vector3i.h" - - -//TODO This definitly needs a better naming :D but how? -enum Direction -{ - X_PLUS, - X_MINUS, - Y_PLUS, - Y_MINUS, - Z_PLUS, - Z_MINUS, - NONE -}; - -class Vector3i; -class cWorld; -class cFluidSimulator : public cSimulator -{ -public: - cFluidSimulator( cWorld* a_World ); - ~cFluidSimulator(); - - virtual void Simulate( float a_Dt ); - - //Gets the flowing direction. if a_Over is true also the block over the current block affects the direction (standard) - Direction GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a_Over = true); - - virtual bool IsAllowedBlock( char a_BlockID ) = 0; - virtual bool IsStationaryBlock( char a_BlockID); - virtual bool IsPassableForFluid( char a_BlockID ); - bool CanWashAway( char a_BlockID ); - bool IsSolidBlock(char a_BlockID); -protected: - virtual void AddBlock( int a_X, int a_Y, int a_Z); - char GetHighestLevelAround( int a_X, int a_Y, int a_Z ); - - bool UniqueSituation(Vector3i a_Pos); //Applys special for this fluid rules like generation of water betwin sources, returns false if it is necessary to apply general rules - void ApplyUniqueToNearest(Vector3i a_Pos); - - float m_Timer; - - class FluidData; - FluidData* m_Data; - - //Customize - char m_FluidBlock; - char m_StationaryFluidBlock; - char m_MaxHeight; - char m_FlowReduction; - +#pragma once + +#include "cSimulator.h" +#include "Vector3i.h" + + +//TODO This definitly needs a better naming :D but how? +enum Direction +{ + X_PLUS, + X_MINUS, + Y_PLUS, + Y_MINUS, + Z_PLUS, + Z_MINUS, + NONE +}; + +class Vector3i; +class cWorld; +class cFluidSimulator : public cSimulator +{ +public: + cFluidSimulator( cWorld* a_World ); + ~cFluidSimulator(); + + virtual void Simulate( float a_Dt ); + + //Gets the flowing direction. if a_Over is true also the block over the current block affects the direction (standard) + Direction GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a_Over = true); + + virtual bool IsAllowedBlock( char a_BlockID ) = 0; + virtual bool IsStationaryBlock( char a_BlockID); + virtual bool IsPassableForFluid( char a_BlockID ); + bool CanWashAway( char a_BlockID ); + bool IsSolidBlock(char a_BlockID); +protected: + virtual void AddBlock( int a_X, int a_Y, int a_Z); + char GetHighestLevelAround( int a_X, int a_Y, int a_Z ); + + bool UniqueSituation(Vector3i a_Pos); //Applys special for this fluid rules like generation of water betwin sources, returns false if it is necessary to apply general rules + void ApplyUniqueToNearest(Vector3i a_Pos); + + float m_Timer; + + class FluidData; + FluidData* m_Data; + + //Customize + char m_FluidBlock; + char m_StationaryFluidBlock; + char m_MaxHeight; + char m_FlowReduction; + }; \ No newline at end of file diff --git a/source/cFurnaceEntity.cpp b/source/cFurnaceEntity.cpp index 925682590..f127e05e8 100644 --- a/source/cFurnaceEntity.cpp +++ b/source/cFurnaceEntity.cpp @@ -1,401 +1,401 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cFurnaceEntity.h" -#include "BlockID.h" -#include "cItem.h" -#include "cFurnaceWindow.h" -#include "cPlayer.h" -#include "cWorld.h" -#include "cClientHandle.h" -#include "cFurnaceRecipe.h" -#include "cServer.h" -#include "cPickup.h" -#include "cRoot.h" - -#include "packets/cPacket_InventoryProgressBar.h" - -#include - - - - - -cFurnaceEntity::cFurnaceEntity(int a_X, int a_Y, int a_Z, cWorld * a_World) - : cBlockEntity( E_BLOCK_FURNACE, a_X, a_Y, a_Z, a_World ) - , m_Items( new cItem[3] ) - , m_CookingItem( 0 ) - , m_CookTime( 0 ) - , m_TimeCooked( 0 ) - , m_BurnTime( 0 ) - , m_TimeBurned( 0 ) -{ -} - - - - - -cFurnaceEntity::~cFurnaceEntity() -{ - // Tell window its owner is destroyed - if( GetWindow() ) - { - GetWindow()->OwnerDestroyed(); - } - - // Clean up items - if( m_Items ) - { - delete [] m_Items; - } -} - - - - - -void cFurnaceEntity::Destroy() -{ - // Drop items - cItems Pickups; - for( int i = 0; i < 3; i++) - { - if( !m_Items[i].IsEmpty() ) - { - Pickups.push_back(m_Items[i]); - m_Items[i].Empty(); - } - } - m_World->SpawnItemPickups(Pickups, m_PosX, m_PosY, m_PosZ); -} - - - - - -void cFurnaceEntity::UsedBy( cPlayer * a_Player ) -{ - LOG("Used a furnace"); - - if( !GetWindow() ) - { - cWindow* Window = new cFurnaceWindow( this ); - Window->SetSlots( m_Items, 3 ); - Window->SetWindowTitle("UberFurnace"); - Window->GetOwner()->SetEntity(this); - OpenWindow( Window ); - } - if( GetWindow() ) - { - if( a_Player->GetWindow() != GetWindow() ) - { - a_Player->OpenWindow( GetWindow() ); - - GetWindow()->SendWholeWindow( a_Player->GetClientHandle() ); - } - } -} - - - - - -bool cFurnaceEntity::Tick( float a_Dt ) -{ - /* - // DEBUG: - Int16 BurnTime = (Int16)(GetTimeToBurn() / 50.0); - Int16 CookTime = (Int16)(GetTimeCooked() / 50.0); - LOGD("Furnace: BurnTime %d, CookTime %d", BurnTime, CookTime); - */ - - if (m_BurnTime <= 0) - { - // There is no fuel and no flame, no need to tick at all - return false; - } - - // DEBUG: LOGD("Furnace: Left: %0.1f Burned: %0.1f Burn time: %0.1f", m_CookTime - m_TimeCooked, m_TimeBurned, m_BurnTime ); - - if ((m_CookingItem != NULL) && ((m_TimeBurned < m_BurnTime) || (m_TimeCooked + a_Dt >= m_CookTime))) - { - if (m_CookingItem->Equals(m_Items[2]) || m_Items[2].IsEmpty()) - { - m_TimeCooked += a_Dt; - if ( m_TimeCooked >= m_CookTime ) - { - m_Items[0].m_ItemCount--; - if( m_Items[0].IsEmpty() ) m_Items[0].Empty(); - - m_Items[2].m_ItemHealth = m_CookingItem->m_ItemHealth; - m_Items[2].m_ItemID = m_CookingItem->m_ItemID; - m_Items[2].m_ItemCount += m_CookingItem->m_ItemCount; - delete m_CookingItem; - m_CookingItem = NULL; - - cWindow * Window = GetWindow(); - if (Window != NULL) - { - Window->BroadcastWholeWindow(); - } - - m_TimeCooked -= m_CookTime; - StartCooking(); - } - cWindow * Window = GetWindow(); - if (Window != NULL) - { - cPacket_InventoryProgressBar Progress; - Progress.m_ProgressBar = 0; - Progress.m_WindowID = (char)Window->GetWindowID(); - Progress.m_Value = (short)( m_TimeCooked * (180.f / m_CookTime) ); - if (Progress.m_Value > 180) Progress.m_Value = 180; - if (Progress.m_Value < 0) Progress.m_Value = 0; - Window->Broadcast(Progress); - } - } - } - - m_TimeBurned += a_Dt; - - cWindow * Window = GetWindow(); - if (m_TimeBurned >= m_BurnTime) - { - m_TimeBurned -= m_BurnTime; - m_BurnTime = 0; - if (StartCooking() && (Window != NULL)) - { - Window->BroadcastWholeWindow(); - } - } - if (Window != NULL) - { - cPacket_InventoryProgressBar Progress; - Progress.m_WindowID = (char)Window->GetWindowID(); - Progress.m_ProgressBar = 1; - - if (m_BurnTime > 0.f) - { - Progress.m_Value = 250 - (short)( m_TimeBurned * (250.f / m_BurnTime) ); - if (Progress.m_Value > 250) Progress.m_Value = 250; - if (Progress.m_Value < 0) Progress.m_Value = 0; - } - else - { - Progress.m_Value = 0; - } - Window->Broadcast(Progress); - } - return ((m_CookingItem != NULL) || (m_TimeBurned < m_BurnTime)) && (m_BurnTime > 0.0); // Keep on ticking, if there's more to cook, or if it's cooking -} - - - - - -bool cFurnaceEntity::StartCooking(void) -{ - cFurnaceRecipe* FR = cRoot::Get()->GetFurnaceRecipe(); - float BurnTime = FR->GetBurnTime( m_Items[1] ); - if( (m_TimeBurned < m_BurnTime) || BurnTime > 0.f ) // burnable material - { - const cFurnaceRecipe::Recipe* R = FR->GetRecipeFrom( m_Items[0] ); - if( R ) // cook able ingredient - { - if( m_Items[2].Equals( *R->Out ) || m_Items[2].IsEmpty() ) - { - // good to go - - if( m_TimeBurned >= m_BurnTime ) // burn new material - { - m_Items[1].m_ItemCount--; - if( m_Items[1].m_ItemCount <= 0 ) m_Items[1].Empty(); - m_TimeBurned = 0; - m_BurnTime = BurnTime; - } - - if( !m_CookingItem ) // Only cook new item if not already cooking - { - m_CookingItem = new cItem( *R->Out ); // Resulting item - m_TimeCooked = 0.f; - m_CookTime = R->CookTime; - } - return true; - } - } - } - return false; -} - - - - - -bool cFurnaceEntity::ContinueCooking(void) -{ - cFurnaceRecipe * FR = cRoot::Get()->GetFurnaceRecipe(); - float BurnTime = FR->GetBurnTime( m_Items[1] ); - if( (m_TimeBurned < m_BurnTime) || BurnTime > 0.f ) // burnable material - { - const cFurnaceRecipe::Recipe * R = FR->GetRecipeFrom( m_Items[0] ); - if (R != NULL) // cook able ingredient - { - if (m_Items[2].Equals(*R->Out) || m_Items[2].IsEmpty()) - { - // good to go - if (m_CookingItem == NULL) // Only cook new item if not already cooking - { - m_CookingItem = new cItem( *R->Out ); // Resulting item - } - return true; - } - } - } - return false; -} - - - - - -void cFurnaceEntity::ResetCookTimer() -{ - delete m_CookingItem; - m_CookingItem = NULL; - m_TimeCooked = 0.f; - m_CookTime = 0.f; -} - - - - - -void cFurnaceEntity::SetSlot(int a_Slot, const cItem & a_Item) -{ - if ((a_Slot < 0) || (a_Slot >= 3)) - { - ASSERT(!"Furnace: slot number out of range"); - return; - } - m_Items[a_Slot] = a_Item; -} - - - - - -#define READ(File, Var) \ - if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \ - { \ - LOGERROR("ERROR READING cFurnaceEntity %s FROM FILE (line %d)", #Var, __LINE__); \ - return false; \ - } - -bool cFurnaceEntity::LoadFromFile(cFile & f) -{ - READ(f, m_PosX); - READ(f, m_PosY); - READ(f, m_PosZ); - - unsigned int NumSlots = 0; - READ(f, NumSlots); - m_Items = new cItem[ NumSlots ]; - for(unsigned int i = 0; i < NumSlots; i++) - { - cItem & Item = m_Items[i]; - READ(f, Item.m_ItemID); - READ(f, Item.m_ItemCount); - READ(f, Item.m_ItemHealth); - } - cItem CookingItem; - READ(f, CookingItem.m_ItemID); - READ(f, CookingItem.m_ItemCount); - READ(f, CookingItem.m_ItemHealth); - if (!CookingItem.IsEmpty()) - { - m_CookingItem = new cItem(CookingItem); - } - - READ(f, m_CookTime); - READ(f, m_TimeCooked); - READ(f, m_BurnTime); - READ(f, m_TimeBurned); - - return true; -} - - - - - -bool cFurnaceEntity::LoadFromJson( const Json::Value& a_Value ) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - Json::Value AllSlots = a_Value.get("Slots", 0); - int SlotIdx = 0; - for( Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr ) - { - m_Items[ SlotIdx ].FromJson( *itr ); - SlotIdx++; - } - - // Get currently cooking item - Json::Value JsonItem = a_Value.get("Cooking", Json::nullValue ); - if( !JsonItem.empty() ) - { - cItem Item; - Item.FromJson( JsonItem ); - if( !Item.IsEmpty() ) - { - m_CookingItem = new cItem( Item ); - } - } - - m_CookTime = (float)a_Value.get("CookTime", 0).asDouble(); - m_TimeCooked = (float)a_Value.get("TimeCooked", 0).asDouble(); - m_BurnTime = (float)a_Value.get("BurnTime", 0).asDouble(); - m_TimeBurned = (float)a_Value.get("TimeBurned", 0).asDouble(); - - return true; -} - - - - - -void cFurnaceEntity::SaveToJson( Json::Value& a_Value ) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - Json::Value AllSlots; - for(unsigned int i = 0; i < 3; i++) - { - Json::Value Slot; - m_Items[ i ].GetJson( Slot ); - AllSlots.append( Slot ); - } - a_Value["Slots"] = AllSlots; - - // Currently cooking item - if( m_CookingItem ) - { - Json::Value JsonItem; - m_CookingItem->GetJson( JsonItem ); - a_Value["Cooking"] = JsonItem; - } - - a_Value["CookTime"] = m_CookTime; - a_Value["TimeCooked"] = m_TimeCooked; - a_Value["BurnTime"] = m_BurnTime; - a_Value["TimeBurned"] = m_TimeBurned; -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cFurnaceEntity.h" +#include "BlockID.h" +#include "cItem.h" +#include "cFurnaceWindow.h" +#include "cPlayer.h" +#include "cWorld.h" +#include "cClientHandle.h" +#include "cFurnaceRecipe.h" +#include "cServer.h" +#include "cPickup.h" +#include "cRoot.h" + +#include "packets/cPacket_InventoryProgressBar.h" + +#include + + + + + +cFurnaceEntity::cFurnaceEntity(int a_X, int a_Y, int a_Z, cWorld * a_World) + : cBlockEntity( E_BLOCK_FURNACE, a_X, a_Y, a_Z, a_World ) + , m_Items( new cItem[3] ) + , m_CookingItem( 0 ) + , m_CookTime( 0 ) + , m_TimeCooked( 0 ) + , m_BurnTime( 0 ) + , m_TimeBurned( 0 ) +{ +} + + + + + +cFurnaceEntity::~cFurnaceEntity() +{ + // Tell window its owner is destroyed + if( GetWindow() ) + { + GetWindow()->OwnerDestroyed(); + } + + // Clean up items + if( m_Items ) + { + delete [] m_Items; + } +} + + + + + +void cFurnaceEntity::Destroy() +{ + // Drop items + cItems Pickups; + for( int i = 0; i < 3; i++) + { + if( !m_Items[i].IsEmpty() ) + { + Pickups.push_back(m_Items[i]); + m_Items[i].Empty(); + } + } + m_World->SpawnItemPickups(Pickups, m_PosX, m_PosY, m_PosZ); +} + + + + + +void cFurnaceEntity::UsedBy( cPlayer * a_Player ) +{ + LOG("Used a furnace"); + + if( !GetWindow() ) + { + cWindow* Window = new cFurnaceWindow( this ); + Window->SetSlots( m_Items, 3 ); + Window->SetWindowTitle("UberFurnace"); + Window->GetOwner()->SetEntity(this); + OpenWindow( Window ); + } + if( GetWindow() ) + { + if( a_Player->GetWindow() != GetWindow() ) + { + a_Player->OpenWindow( GetWindow() ); + + GetWindow()->SendWholeWindow( a_Player->GetClientHandle() ); + } + } +} + + + + + +bool cFurnaceEntity::Tick( float a_Dt ) +{ + /* + // DEBUG: + Int16 BurnTime = (Int16)(GetTimeToBurn() / 50.0); + Int16 CookTime = (Int16)(GetTimeCooked() / 50.0); + LOGD("Furnace: BurnTime %d, CookTime %d", BurnTime, CookTime); + */ + + if (m_BurnTime <= 0) + { + // There is no fuel and no flame, no need to tick at all + return false; + } + + // DEBUG: LOGD("Furnace: Left: %0.1f Burned: %0.1f Burn time: %0.1f", m_CookTime - m_TimeCooked, m_TimeBurned, m_BurnTime ); + + if ((m_CookingItem != NULL) && ((m_TimeBurned < m_BurnTime) || (m_TimeCooked + a_Dt >= m_CookTime))) + { + if (m_CookingItem->Equals(m_Items[2]) || m_Items[2].IsEmpty()) + { + m_TimeCooked += a_Dt; + if ( m_TimeCooked >= m_CookTime ) + { + m_Items[0].m_ItemCount--; + if( m_Items[0].IsEmpty() ) m_Items[0].Empty(); + + m_Items[2].m_ItemHealth = m_CookingItem->m_ItemHealth; + m_Items[2].m_ItemID = m_CookingItem->m_ItemID; + m_Items[2].m_ItemCount += m_CookingItem->m_ItemCount; + delete m_CookingItem; + m_CookingItem = NULL; + + cWindow * Window = GetWindow(); + if (Window != NULL) + { + Window->BroadcastWholeWindow(); + } + + m_TimeCooked -= m_CookTime; + StartCooking(); + } + cWindow * Window = GetWindow(); + if (Window != NULL) + { + cPacket_InventoryProgressBar Progress; + Progress.m_ProgressBar = 0; + Progress.m_WindowID = (char)Window->GetWindowID(); + Progress.m_Value = (short)( m_TimeCooked * (180.f / m_CookTime) ); + if (Progress.m_Value > 180) Progress.m_Value = 180; + if (Progress.m_Value < 0) Progress.m_Value = 0; + Window->Broadcast(Progress); + } + } + } + + m_TimeBurned += a_Dt; + + cWindow * Window = GetWindow(); + if (m_TimeBurned >= m_BurnTime) + { + m_TimeBurned -= m_BurnTime; + m_BurnTime = 0; + if (StartCooking() && (Window != NULL)) + { + Window->BroadcastWholeWindow(); + } + } + if (Window != NULL) + { + cPacket_InventoryProgressBar Progress; + Progress.m_WindowID = (char)Window->GetWindowID(); + Progress.m_ProgressBar = 1; + + if (m_BurnTime > 0.f) + { + Progress.m_Value = 250 - (short)( m_TimeBurned * (250.f / m_BurnTime) ); + if (Progress.m_Value > 250) Progress.m_Value = 250; + if (Progress.m_Value < 0) Progress.m_Value = 0; + } + else + { + Progress.m_Value = 0; + } + Window->Broadcast(Progress); + } + return ((m_CookingItem != NULL) || (m_TimeBurned < m_BurnTime)) && (m_BurnTime > 0.0); // Keep on ticking, if there's more to cook, or if it's cooking +} + + + + + +bool cFurnaceEntity::StartCooking(void) +{ + cFurnaceRecipe* FR = cRoot::Get()->GetFurnaceRecipe(); + float BurnTime = FR->GetBurnTime( m_Items[1] ); + if( (m_TimeBurned < m_BurnTime) || BurnTime > 0.f ) // burnable material + { + const cFurnaceRecipe::Recipe* R = FR->GetRecipeFrom( m_Items[0] ); + if( R ) // cook able ingredient + { + if( m_Items[2].Equals( *R->Out ) || m_Items[2].IsEmpty() ) + { + // good to go + + if( m_TimeBurned >= m_BurnTime ) // burn new material + { + m_Items[1].m_ItemCount--; + if( m_Items[1].m_ItemCount <= 0 ) m_Items[1].Empty(); + m_TimeBurned = 0; + m_BurnTime = BurnTime; + } + + if( !m_CookingItem ) // Only cook new item if not already cooking + { + m_CookingItem = new cItem( *R->Out ); // Resulting item + m_TimeCooked = 0.f; + m_CookTime = R->CookTime; + } + return true; + } + } + } + return false; +} + + + + + +bool cFurnaceEntity::ContinueCooking(void) +{ + cFurnaceRecipe * FR = cRoot::Get()->GetFurnaceRecipe(); + float BurnTime = FR->GetBurnTime( m_Items[1] ); + if( (m_TimeBurned < m_BurnTime) || BurnTime > 0.f ) // burnable material + { + const cFurnaceRecipe::Recipe * R = FR->GetRecipeFrom( m_Items[0] ); + if (R != NULL) // cook able ingredient + { + if (m_Items[2].Equals(*R->Out) || m_Items[2].IsEmpty()) + { + // good to go + if (m_CookingItem == NULL) // Only cook new item if not already cooking + { + m_CookingItem = new cItem( *R->Out ); // Resulting item + } + return true; + } + } + } + return false; +} + + + + + +void cFurnaceEntity::ResetCookTimer() +{ + delete m_CookingItem; + m_CookingItem = NULL; + m_TimeCooked = 0.f; + m_CookTime = 0.f; +} + + + + + +void cFurnaceEntity::SetSlot(int a_Slot, const cItem & a_Item) +{ + if ((a_Slot < 0) || (a_Slot >= 3)) + { + ASSERT(!"Furnace: slot number out of range"); + return; + } + m_Items[a_Slot] = a_Item; +} + + + + + +#define READ(File, Var) \ + if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \ + { \ + LOGERROR("ERROR READING cFurnaceEntity %s FROM FILE (line %d)", #Var, __LINE__); \ + return false; \ + } + +bool cFurnaceEntity::LoadFromFile(cFile & f) +{ + READ(f, m_PosX); + READ(f, m_PosY); + READ(f, m_PosZ); + + unsigned int NumSlots = 0; + READ(f, NumSlots); + m_Items = new cItem[ NumSlots ]; + for(unsigned int i = 0; i < NumSlots; i++) + { + cItem & Item = m_Items[i]; + READ(f, Item.m_ItemID); + READ(f, Item.m_ItemCount); + READ(f, Item.m_ItemHealth); + } + cItem CookingItem; + READ(f, CookingItem.m_ItemID); + READ(f, CookingItem.m_ItemCount); + READ(f, CookingItem.m_ItemHealth); + if (!CookingItem.IsEmpty()) + { + m_CookingItem = new cItem(CookingItem); + } + + READ(f, m_CookTime); + READ(f, m_TimeCooked); + READ(f, m_BurnTime); + READ(f, m_TimeBurned); + + return true; +} + + + + + +bool cFurnaceEntity::LoadFromJson( const Json::Value& a_Value ) +{ + m_PosX = a_Value.get("x", 0).asInt(); + m_PosY = a_Value.get("y", 0).asInt(); + m_PosZ = a_Value.get("z", 0).asInt(); + + Json::Value AllSlots = a_Value.get("Slots", 0); + int SlotIdx = 0; + for( Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr ) + { + m_Items[ SlotIdx ].FromJson( *itr ); + SlotIdx++; + } + + // Get currently cooking item + Json::Value JsonItem = a_Value.get("Cooking", Json::nullValue ); + if( !JsonItem.empty() ) + { + cItem Item; + Item.FromJson( JsonItem ); + if( !Item.IsEmpty() ) + { + m_CookingItem = new cItem( Item ); + } + } + + m_CookTime = (float)a_Value.get("CookTime", 0).asDouble(); + m_TimeCooked = (float)a_Value.get("TimeCooked", 0).asDouble(); + m_BurnTime = (float)a_Value.get("BurnTime", 0).asDouble(); + m_TimeBurned = (float)a_Value.get("TimeBurned", 0).asDouble(); + + return true; +} + + + + + +void cFurnaceEntity::SaveToJson( Json::Value& a_Value ) +{ + a_Value["x"] = m_PosX; + a_Value["y"] = m_PosY; + a_Value["z"] = m_PosZ; + + Json::Value AllSlots; + for(unsigned int i = 0; i < 3; i++) + { + Json::Value Slot; + m_Items[ i ].GetJson( Slot ); + AllSlots.append( Slot ); + } + a_Value["Slots"] = AllSlots; + + // Currently cooking item + if( m_CookingItem ) + { + Json::Value JsonItem; + m_CookingItem->GetJson( JsonItem ); + a_Value["Cooking"] = JsonItem; + } + + a_Value["CookTime"] = m_CookTime; + a_Value["TimeCooked"] = m_TimeCooked; + a_Value["BurnTime"] = m_BurnTime; + a_Value["TimeBurned"] = m_TimeBurned; +} + + + + diff --git a/source/cFurnaceEntity.h b/source/cFurnaceEntity.h index 253990000..7fc090bee 100644 --- a/source/cFurnaceEntity.h +++ b/source/cFurnaceEntity.h @@ -1,74 +1,74 @@ - -#pragma once - -#include "cBlockEntity.h" -#include "cWindowOwner.h" -#include "FileDefine.h" -#include "cItem.h" - - - - - -namespace Json -{ - class Value; -} - -class cClientHandle; -class cServer; - - - - -class cFurnaceEntity : - public cBlockEntity, - public cWindowOwner -{ -public: - cFurnaceEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); - virtual ~cFurnaceEntity(); - virtual void Destroy(); - - bool LoadFromFile(cFile & a_File); // deprecated format - - bool LoadFromJson(const Json::Value& a_Value ); - virtual void SaveToJson(Json::Value& a_Value ) override; - - // Returns true if there's any change, forcing the chunk to go dirty. - bool Tick( float a_Dt ); - - virtual void UsedBy( cPlayer * a_Player ) override; - - bool StartCooking(); - - /// Restarts cooking. Used after the furnace is loaded from storage to set up the internal variables so that cooking continues, if it was active. Returns true if cooking. - bool ContinueCooking(void); - - void ResetCookTimer(); - - const cItem & GetSlot(int i) const { return m_Items[i]; } - - void SetSlot(int a_Slot, const cItem & a_Item); - - float GetTimeCooked(void) const {return m_TimeCooked; } - float GetTimeToBurn(void) const {return m_BurnTime - m_TimeBurned; } - - void SetBurnTimes(float a_BurnTime, float a_TimeBurned) {m_BurnTime = a_BurnTime; m_TimeBurned = 0; } - void SetCookTimes(float a_CookTime, float a_TimeCooked) {m_CookTime = a_CookTime; m_TimeCooked = a_TimeCooked; } - -private: - - cItem * m_Items; - cItem * m_CookingItem; - - // All timers are in 1 ms - float m_CookTime; // Amount of time needed to fully cook current item - float m_TimeCooked; // Amount of time that the current item has been cooking - float m_BurnTime; // Amount of time that the current fuel can burn (in total); zero if no fuel burning - float m_TimeBurned; // Amount of time that the current fuel has been burning -}; - - - - + +#pragma once + +#include "cBlockEntity.h" +#include "cWindowOwner.h" +#include "FileDefine.h" +#include "cItem.h" + + + + + +namespace Json +{ + class Value; +} + +class cClientHandle; +class cServer; + + + + +class cFurnaceEntity : + public cBlockEntity, + public cWindowOwner +{ +public: + cFurnaceEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); + virtual ~cFurnaceEntity(); + virtual void Destroy(); + + bool LoadFromFile(cFile & a_File); // deprecated format + + bool LoadFromJson(const Json::Value& a_Value ); + virtual void SaveToJson(Json::Value& a_Value ) override; + + // Returns true if there's any change, forcing the chunk to go dirty. + bool Tick( float a_Dt ); + + virtual void UsedBy( cPlayer * a_Player ) override; + + bool StartCooking(); + + /// Restarts cooking. Used after the furnace is loaded from storage to set up the internal variables so that cooking continues, if it was active. Returns true if cooking. + bool ContinueCooking(void); + + void ResetCookTimer(); + + const cItem & GetSlot(int i) const { return m_Items[i]; } + + void SetSlot(int a_Slot, const cItem & a_Item); + + float GetTimeCooked(void) const {return m_TimeCooked; } + float GetTimeToBurn(void) const {return m_BurnTime - m_TimeBurned; } + + void SetBurnTimes(float a_BurnTime, float a_TimeBurned) {m_BurnTime = a_BurnTime; m_TimeBurned = 0; } + void SetCookTimes(float a_CookTime, float a_TimeCooked) {m_CookTime = a_CookTime; m_TimeCooked = a_TimeCooked; } + +private: + + cItem * m_Items; + cItem * m_CookingItem; + + // All timers are in 1 ms + float m_CookTime; // Amount of time needed to fully cook current item + float m_TimeCooked; // Amount of time that the current item has been cooking + float m_BurnTime; // Amount of time that the current fuel can burn (in total); zero if no fuel burning + float m_TimeBurned; // Amount of time that the current fuel has been burning +}; + + + + diff --git a/source/cFurnaceRecipe.cpp b/source/cFurnaceRecipe.cpp index b17ec51cd..3f6416d92 100644 --- a/source/cFurnaceRecipe.cpp +++ b/source/cFurnaceRecipe.cpp @@ -1,241 +1,241 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cFurnaceRecipe.h" -#include "cItem.h" - -#include -#include - - - - - -typedef std::list< cFurnaceRecipe::Recipe > RecipeList; -typedef std::list< cFurnaceRecipe::Fuel > FuelList; - - - - - -struct cFurnaceRecipe::sFurnaceRecipeState -{ - RecipeList Recipes; - FuelList Fuel; -}; - - - - - -cFurnaceRecipe::cFurnaceRecipe() - : m_pState( new sFurnaceRecipeState ) -{ - ReloadRecipes(); -} - - - - - -cFurnaceRecipe::~cFurnaceRecipe() -{ - ClearRecipes(); - delete m_pState; -} - - - - - -void cFurnaceRecipe::ReloadRecipes() -{ - ClearRecipes(); - LOG("-- Loading furnace recipes --"); - - std::ifstream f; - char a_File[] = "furnace.txt"; - f.open(a_File, std::ios::in); - std::string input; - - if( !f.good() ) - { - f.close(); - LOG("Could not open file for recipes: %s", a_File); - return; - } - - bool bSyntaxError = false; - while( f.good() ) - { - char c; - - ////////////////////////////////////////////////////////////////////////// - // comments - f >> c; - f.unget(); - if( c == '#' ) - { - while( f.good() && c != '\n' ) - { - f.get( c ); - } - continue; - } - - - ////////////////////////////////////////////////////////////////////////// - // Line breaks - f.get( c ); - while( f.good() && ( c == '\n' || c == '\r' ) ) { f.get( c ); } - if( f.eof() ) break; - f.unget(); - - ////////////////////////////////////////////////////////////////////////// - // Check for fuel - f >> c; - if( c == '!' ) // It's fuel :) - { - // Read item - int IItemID = 0, IItemCount = 0, IItemHealth = 0; - f >> IItemID; - f >> c; if( c != ':' ) { bSyntaxError = true; break; } - f >> IItemCount; - - // Optional health - f >> c; - if( c != ':' ) - f.unget(); - else - { - f >> IItemHealth; - } - - // Burn time - float BurnTime; - f >> c; if( c != '=' ) { bSyntaxError = true; break; } - f >> BurnTime; - - // Add to fuel list - Fuel F; - F.In = new cItem( (ENUM_ITEM_ID) IItemID, (char)IItemCount, (short)IItemHealth ); - F.BurnTime = BurnTime; - m_pState->Fuel.push_back( F ); - continue; - } - f.unget(); - - ////////////////////////////////////////////////////////////////////////// - // Read items - int IItemID = 0, IItemCount = 0, IItemHealth = 0; - f >> IItemID; - f >> c; if( c != ':' ) { bSyntaxError = true; break; } - f >> IItemCount; - - // Optional health - f >> c; - if( c != ':' ) - f.unget(); - else - { - f >> IItemHealth; - } - - float CookTime; - f >> c; if( c != '@' ) { bSyntaxError = true; break; } - f >> CookTime; - - int OItemID = 0, OItemCount = 0, OItemHealth = 0; - f >> c; if( c != '=' ) { bSyntaxError = true; break; } - f >> OItemID; - f >> c; if( c != ':' ) { bSyntaxError = true; break; } - f >> OItemCount; - - // Optional health - f >> c; - if( c != ':' ) - f.unget(); - else - { - f >> OItemHealth; - } - - // Add to recipe list - Recipe R; - R.In = new cItem( (ENUM_ITEM_ID)IItemID, (char)IItemCount, (short)IItemHealth ); - R.Out = new cItem( (ENUM_ITEM_ID)OItemID, (char)OItemCount, (short)OItemHealth ); - R.CookTime = CookTime; - m_pState->Recipes.push_back( R ); - } - if( bSyntaxError ) - { - LOGERROR("ERROR: FurnaceRecipe, syntax error" ); - } - LOG("Got %i furnace recipes, and %i fuels.", m_pState->Recipes.size(), m_pState->Fuel.size() ); - - LOG("-- Done loading furnace recipes --"); -} - - - - - -void cFurnaceRecipe::ClearRecipes() -{ - for( RecipeList::iterator itr = m_pState->Recipes.begin(); itr != m_pState->Recipes.end(); ++itr ) - { - Recipe R = *itr; - delete R.In; - delete R.Out; - } - m_pState->Recipes.clear(); - - for( FuelList::iterator itr = m_pState->Fuel.begin(); itr != m_pState->Fuel.end(); ++itr ) - { - Fuel F = *itr; - delete F.In; - } - m_pState->Fuel.clear(); -} - -const cFurnaceRecipe::Recipe* cFurnaceRecipe::GetRecipeFrom( const cItem & a_Ingredient ) const -{ - const Recipe* BestRecipe = 0; - for( RecipeList::const_iterator itr = m_pState->Recipes.begin(); itr != m_pState->Recipes.end(); ++itr ) - { - const Recipe & R = *itr; - if( (R.In->m_ItemID == a_Ingredient.m_ItemID) && (R.In->m_ItemCount <= a_Ingredient.m_ItemCount ) ) - { - if( BestRecipe && (BestRecipe->In->m_ItemCount > R.In->m_ItemCount) ) - { - continue; - } - else - { - BestRecipe = &R; - } - } - } - return BestRecipe; -} - -float cFurnaceRecipe::GetBurnTime( const cItem & a_Fuel ) const -{ - float BestFuel = 0.f; - for( FuelList::const_iterator itr = m_pState->Fuel.begin(); itr != m_pState->Fuel.end(); ++itr ) - { - const Fuel & F = *itr; - if( (F.In->m_ItemID == a_Fuel.m_ItemID) && (F.In->m_ItemCount <= a_Fuel.m_ItemCount ) ) - { - if( BestFuel > 0.f && (BestFuel > F.BurnTime ) ) - { - continue; - } - else - { - BestFuel = F.BurnTime; - } - } - } - return BestFuel; + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cFurnaceRecipe.h" +#include "cItem.h" + +#include +#include + + + + + +typedef std::list< cFurnaceRecipe::Recipe > RecipeList; +typedef std::list< cFurnaceRecipe::Fuel > FuelList; + + + + + +struct cFurnaceRecipe::sFurnaceRecipeState +{ + RecipeList Recipes; + FuelList Fuel; +}; + + + + + +cFurnaceRecipe::cFurnaceRecipe() + : m_pState( new sFurnaceRecipeState ) +{ + ReloadRecipes(); +} + + + + + +cFurnaceRecipe::~cFurnaceRecipe() +{ + ClearRecipes(); + delete m_pState; +} + + + + + +void cFurnaceRecipe::ReloadRecipes() +{ + ClearRecipes(); + LOG("-- Loading furnace recipes --"); + + std::ifstream f; + char a_File[] = "furnace.txt"; + f.open(a_File, std::ios::in); + std::string input; + + if( !f.good() ) + { + f.close(); + LOG("Could not open file for recipes: %s", a_File); + return; + } + + bool bSyntaxError = false; + while( f.good() ) + { + char c; + + ////////////////////////////////////////////////////////////////////////// + // comments + f >> c; + f.unget(); + if( c == '#' ) + { + while( f.good() && c != '\n' ) + { + f.get( c ); + } + continue; + } + + + ////////////////////////////////////////////////////////////////////////// + // Line breaks + f.get( c ); + while( f.good() && ( c == '\n' || c == '\r' ) ) { f.get( c ); } + if( f.eof() ) break; + f.unget(); + + ////////////////////////////////////////////////////////////////////////// + // Check for fuel + f >> c; + if( c == '!' ) // It's fuel :) + { + // Read item + int IItemID = 0, IItemCount = 0, IItemHealth = 0; + f >> IItemID; + f >> c; if( c != ':' ) { bSyntaxError = true; break; } + f >> IItemCount; + + // Optional health + f >> c; + if( c != ':' ) + f.unget(); + else + { + f >> IItemHealth; + } + + // Burn time + float BurnTime; + f >> c; if( c != '=' ) { bSyntaxError = true; break; } + f >> BurnTime; + + // Add to fuel list + Fuel F; + F.In = new cItem( (ENUM_ITEM_ID) IItemID, (char)IItemCount, (short)IItemHealth ); + F.BurnTime = BurnTime; + m_pState->Fuel.push_back( F ); + continue; + } + f.unget(); + + ////////////////////////////////////////////////////////////////////////// + // Read items + int IItemID = 0, IItemCount = 0, IItemHealth = 0; + f >> IItemID; + f >> c; if( c != ':' ) { bSyntaxError = true; break; } + f >> IItemCount; + + // Optional health + f >> c; + if( c != ':' ) + f.unget(); + else + { + f >> IItemHealth; + } + + float CookTime; + f >> c; if( c != '@' ) { bSyntaxError = true; break; } + f >> CookTime; + + int OItemID = 0, OItemCount = 0, OItemHealth = 0; + f >> c; if( c != '=' ) { bSyntaxError = true; break; } + f >> OItemID; + f >> c; if( c != ':' ) { bSyntaxError = true; break; } + f >> OItemCount; + + // Optional health + f >> c; + if( c != ':' ) + f.unget(); + else + { + f >> OItemHealth; + } + + // Add to recipe list + Recipe R; + R.In = new cItem( (ENUM_ITEM_ID)IItemID, (char)IItemCount, (short)IItemHealth ); + R.Out = new cItem( (ENUM_ITEM_ID)OItemID, (char)OItemCount, (short)OItemHealth ); + R.CookTime = CookTime; + m_pState->Recipes.push_back( R ); + } + if( bSyntaxError ) + { + LOGERROR("ERROR: FurnaceRecipe, syntax error" ); + } + LOG("Got %i furnace recipes, and %i fuels.", m_pState->Recipes.size(), m_pState->Fuel.size() ); + + LOG("-- Done loading furnace recipes --"); +} + + + + + +void cFurnaceRecipe::ClearRecipes() +{ + for( RecipeList::iterator itr = m_pState->Recipes.begin(); itr != m_pState->Recipes.end(); ++itr ) + { + Recipe R = *itr; + delete R.In; + delete R.Out; + } + m_pState->Recipes.clear(); + + for( FuelList::iterator itr = m_pState->Fuel.begin(); itr != m_pState->Fuel.end(); ++itr ) + { + Fuel F = *itr; + delete F.In; + } + m_pState->Fuel.clear(); +} + +const cFurnaceRecipe::Recipe* cFurnaceRecipe::GetRecipeFrom( const cItem & a_Ingredient ) const +{ + const Recipe* BestRecipe = 0; + for( RecipeList::const_iterator itr = m_pState->Recipes.begin(); itr != m_pState->Recipes.end(); ++itr ) + { + const Recipe & R = *itr; + if( (R.In->m_ItemID == a_Ingredient.m_ItemID) && (R.In->m_ItemCount <= a_Ingredient.m_ItemCount ) ) + { + if( BestRecipe && (BestRecipe->In->m_ItemCount > R.In->m_ItemCount) ) + { + continue; + } + else + { + BestRecipe = &R; + } + } + } + return BestRecipe; +} + +float cFurnaceRecipe::GetBurnTime( const cItem & a_Fuel ) const +{ + float BestFuel = 0.f; + for( FuelList::const_iterator itr = m_pState->Fuel.begin(); itr != m_pState->Fuel.end(); ++itr ) + { + const Fuel & F = *itr; + if( (F.In->m_ItemID == a_Fuel.m_ItemID) && (F.In->m_ItemCount <= a_Fuel.m_ItemCount ) ) + { + if( BestFuel > 0.f && (BestFuel > F.BurnTime ) ) + { + continue; + } + else + { + BestFuel = F.BurnTime; + } + } + } + return BestFuel; } \ No newline at end of file diff --git a/source/cFurnaceRecipe.h b/source/cFurnaceRecipe.h index 75e569099..ccb008604 100644 --- a/source/cFurnaceRecipe.h +++ b/source/cFurnaceRecipe.h @@ -1,46 +1,46 @@ - -#pragma once - - - - - -class cItem; - - - - - -class cFurnaceRecipe -{ -public: - cFurnaceRecipe(); - ~cFurnaceRecipe(); - - void ReloadRecipes(); - - struct Fuel - { - cItem* In; - float BurnTime; - }; - - struct Recipe - { - cItem* In; - cItem* Out; - float CookTime; - }; - const Recipe* GetRecipeFrom( const cItem & a_Ingredient ) const; - float GetBurnTime( const cItem & a_Fuel ) const; - -private: - void ClearRecipes(); - - struct sFurnaceRecipeState; - sFurnaceRecipeState* m_pState; -}; - - - - + +#pragma once + + + + + +class cItem; + + + + + +class cFurnaceRecipe +{ +public: + cFurnaceRecipe(); + ~cFurnaceRecipe(); + + void ReloadRecipes(); + + struct Fuel + { + cItem* In; + float BurnTime; + }; + + struct Recipe + { + cItem* In; + cItem* Out; + float CookTime; + }; + const Recipe* GetRecipeFrom( const cItem & a_Ingredient ) const; + float GetBurnTime( const cItem & a_Fuel ) const; + +private: + void ClearRecipes(); + + struct sFurnaceRecipeState; + sFurnaceRecipeState* m_pState; +}; + + + + diff --git a/source/cFurnaceWindow.cpp b/source/cFurnaceWindow.cpp index b76c53498..963c848ec 100644 --- a/source/cFurnaceWindow.cpp +++ b/source/cFurnaceWindow.cpp @@ -1,47 +1,47 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cFurnaceWindow.h" -#include "cItem.h" -#include "cFurnaceEntity.h" -#include "cPlayer.h" - -#include "packets/cPacket_WindowClick.h" - - - - - -cFurnaceWindow::cFurnaceWindow( cFurnaceEntity* a_Owner ) - : cWindow( a_Owner, true ) - , m_Furnace( a_Owner ) -{ - SetWindowID( 1 ); - SetWindowType( cWindow::Furnace ); // Furnace -} - -void cFurnaceWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ) -{ - cItem Fuel = *GetSlot( 0 ); - - cWindow::Clicked( a_ClickPacket, a_Player ); - if( m_Furnace ) - { - if( a_ClickPacket->m_SlotNum >= 0 && a_ClickPacket->m_SlotNum <= 2 ) // them important slots - { - if( Fuel.m_ItemID != GetSlot( 0 )->m_ItemID ) - m_Furnace->ResetCookTimer(); - - if( m_Furnace->StartCooking() ) - { - SendWholeWindow( a_Player.GetClientHandle() ); - } - } - } -} - -void cFurnaceWindow::Close( cPlayer & a_Player ) -{ - m_Furnace = 0; - cWindow::Close( a_Player ); + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cFurnaceWindow.h" +#include "cItem.h" +#include "cFurnaceEntity.h" +#include "cPlayer.h" + +#include "packets/cPacket_WindowClick.h" + + + + + +cFurnaceWindow::cFurnaceWindow( cFurnaceEntity* a_Owner ) + : cWindow( a_Owner, true ) + , m_Furnace( a_Owner ) +{ + SetWindowID( 1 ); + SetWindowType( cWindow::Furnace ); // Furnace +} + +void cFurnaceWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ) +{ + cItem Fuel = *GetSlot( 0 ); + + cWindow::Clicked( a_ClickPacket, a_Player ); + if( m_Furnace ) + { + if( a_ClickPacket->m_SlotNum >= 0 && a_ClickPacket->m_SlotNum <= 2 ) // them important slots + { + if( Fuel.m_ItemID != GetSlot( 0 )->m_ItemID ) + m_Furnace->ResetCookTimer(); + + if( m_Furnace->StartCooking() ) + { + SendWholeWindow( a_Player.GetClientHandle() ); + } + } + } +} + +void cFurnaceWindow::Close( cPlayer & a_Player ) +{ + m_Furnace = 0; + cWindow::Close( a_Player ); } \ No newline at end of file diff --git a/source/cFurnaceWindow.h b/source/cFurnaceWindow.h index 8dd7d3223..f6ae36be5 100644 --- a/source/cFurnaceWindow.h +++ b/source/cFurnaceWindow.h @@ -1,16 +1,16 @@ -#pragma once - -#include "cWindow.h" - -class cFurnaceEntity; -class cWindowOwner; -class cFurnaceWindow : public cWindow -{ -public: - cFurnaceWindow( cFurnaceEntity* a_Owner ); - - virtual void Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ); - virtual void Close( cPlayer & a_Player ); -private: - cFurnaceEntity* m_Furnace; +#pragma once + +#include "cWindow.h" + +class cFurnaceEntity; +class cWindowOwner; +class cFurnaceWindow : public cWindow +{ +public: + cFurnaceWindow( cFurnaceEntity* a_Owner ); + + virtual void Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ); + virtual void Close( cPlayer & a_Player ); +private: + cFurnaceEntity* m_Furnace; }; \ No newline at end of file diff --git a/source/cGhast.cpp b/source/cGhast.cpp index c19753641..857c1c6fb 100644 --- a/source/cGhast.cpp +++ b/source/cGhast.cpp @@ -1,49 +1,49 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cGhast.h" - - - - - -cGhast::cGhast() -{ - m_MobType = 56; - GetMonsterConfig("Ghast"); -} - - - - - -cGhast::~cGhast() -{ -} - - - - - -bool cGhast::IsA( const char* a_EntityType ) -{ - if( strcmp( a_EntityType, "cGhast" ) == 0 ) return true; - return cMonster::IsA( a_EntityType ); -} - - - - - -void cGhast::KilledBy( cEntity* a_Killer ) -{ - cItems Drops; - AddRandomDropItem(Drops, 0, 2, E_ITEM_GUNPOWDER); - AddRandomDropItem(Drops, 0, 1, E_ITEM_GHAST_TEAR); - - cMonster::KilledBy( a_Killer ); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cGhast.h" + + + + + +cGhast::cGhast() +{ + m_MobType = 56; + GetMonsterConfig("Ghast"); +} + + + + + +cGhast::~cGhast() +{ +} + + + + + +bool cGhast::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cGhast" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cGhast::KilledBy( cEntity* a_Killer ) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_GUNPOWDER); + AddRandomDropItem(Drops, 0, 1, E_ITEM_GHAST_TEAR); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cGhast.h b/source/cGhast.h index c33d32df5..e65a45ba0 100644 --- a/source/cGhast.h +++ b/source/cGhast.h @@ -1,14 +1,14 @@ -#pragma once - -#include "cAggressiveMonster.h" - -class cGhast : public cAggressiveMonster -{ -public: - cGhast(); - ~cGhast(); - - virtual bool IsA( const char* a_EntityType ); - - virtual void KilledBy( cEntity* a_Killer ); -}; +#pragma once + +#include "cAggressiveMonster.h" + +class cGhast : public cAggressiveMonster +{ +public: + cGhast(); + ~cGhast(); + + virtual bool IsA( const char* a_EntityType ); + + virtual void KilledBy( cEntity* a_Killer ); +}; diff --git a/source/cGroup.cpp b/source/cGroup.cpp index 4fef22cb2..04549b0eb 100644 --- a/source/cGroup.cpp +++ b/source/cGroup.cpp @@ -1,37 +1,37 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cGroup.h" - -void cGroup::AddCommand( std::string a_Command ) -{ - m_Commands[ a_Command ] = true; -} - -void cGroup::AddPermission( std::string a_Permission ) -{ - m_Permissions[ a_Permission ] = true; -} - -bool cGroup::HasCommand( std::string a_Command ) -{ - if( m_Commands.find("*") != m_Commands.end() ) return true; - - CommandMap::iterator itr = m_Commands.find( a_Command ); - if( itr != m_Commands.end() ) - { - if( itr->second ) return true; - } - - for( GroupList::iterator itr = m_Inherits.begin(); itr != m_Inherits.end(); ++itr ) - { - if( (*itr)->HasCommand( a_Command ) ) return true; - } - return false; -} - -void cGroup::InheritFrom( cGroup* a_Group ) -{ - m_Inherits.remove( a_Group ); - m_Inherits.push_back( a_Group ); + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cGroup.h" + +void cGroup::AddCommand( std::string a_Command ) +{ + m_Commands[ a_Command ] = true; +} + +void cGroup::AddPermission( std::string a_Permission ) +{ + m_Permissions[ a_Permission ] = true; +} + +bool cGroup::HasCommand( std::string a_Command ) +{ + if( m_Commands.find("*") != m_Commands.end() ) return true; + + CommandMap::iterator itr = m_Commands.find( a_Command ); + if( itr != m_Commands.end() ) + { + if( itr->second ) return true; + } + + for( GroupList::iterator itr = m_Inherits.begin(); itr != m_Inherits.end(); ++itr ) + { + if( (*itr)->HasCommand( a_Command ) ) return true; + } + return false; +} + +void cGroup::InheritFrom( cGroup* a_Group ) +{ + m_Inherits.remove( a_Group ); + m_Inherits.push_back( a_Group ); } \ No newline at end of file diff --git a/source/cGroup.h b/source/cGroup.h index 02fb7f05c..447802e88 100644 --- a/source/cGroup.h +++ b/source/cGroup.h @@ -1,40 +1,40 @@ - -#pragma once - - - - - -class cGroup //tolua_export -{ //tolua_export -public: //tolua_export - cGroup() {} - ~cGroup() {} - - void SetName( std::string a_Name ) { m_Name = a_Name; } //tolua_export - const std::string & GetName() const { return m_Name; } //tolua_export - void SetColor( std::string a_Color ) { m_Color = a_Color; } //tolua_export - void AddCommand( std::string a_Command ); //tolua_export - void AddPermission( std::string a_Permission ); //tolua_export - void InheritFrom( cGroup* a_Group ); //tolua_export - - bool HasCommand( std::string a_Command ); //tolua_export - - typedef std::map< std::string, bool > PermissionMap; - const PermissionMap & GetPermissions() const { return m_Permissions; } - - typedef std::map< std::string, bool > CommandMap; - const CommandMap & GetCommands() const { return m_Commands; } - - const AString & GetColor() const { return m_Color; } //tolua_export - - typedef std::list< cGroup* > GroupList; - const GroupList & GetInherits() const { return m_Inherits; } -private: - std::string m_Name; - std::string m_Color; - - PermissionMap m_Permissions; - CommandMap m_Commands; - GroupList m_Inherits; + +#pragma once + + + + + +class cGroup //tolua_export +{ //tolua_export +public: //tolua_export + cGroup() {} + ~cGroup() {} + + void SetName( std::string a_Name ) { m_Name = a_Name; } //tolua_export + const std::string & GetName() const { return m_Name; } //tolua_export + void SetColor( std::string a_Color ) { m_Color = a_Color; } //tolua_export + void AddCommand( std::string a_Command ); //tolua_export + void AddPermission( std::string a_Permission ); //tolua_export + void InheritFrom( cGroup* a_Group ); //tolua_export + + bool HasCommand( std::string a_Command ); //tolua_export + + typedef std::map< std::string, bool > PermissionMap; + const PermissionMap & GetPermissions() const { return m_Permissions; } + + typedef std::map< std::string, bool > CommandMap; + const CommandMap & GetCommands() const { return m_Commands; } + + const AString & GetColor() const { return m_Color; } //tolua_export + + typedef std::list< cGroup* > GroupList; + const GroupList & GetInherits() const { return m_Inherits; } +private: + std::string m_Name; + std::string m_Color; + + PermissionMap m_Permissions; + CommandMap m_Commands; + GroupList m_Inherits; };//tolua_export \ No newline at end of file diff --git a/source/cGroupManager.cpp b/source/cGroupManager.cpp index 30d70171c..2458308c9 100644 --- a/source/cGroupManager.cpp +++ b/source/cGroupManager.cpp @@ -1,108 +1,108 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cGroupManager.h" -#include "cGroup.h" -#include "../iniFile/iniFile.h" -#include "cChatColor.h" -#include "cRoot.h" - - - - - -typedef std::map< std::string, cGroup* > GroupMap; -struct cGroupManager::sGroupManagerState -{ - GroupMap Groups; -}; - -cGroupManager* cGroupManager::GetGroupManager() -{ - LOGWARN("WARNING: Using deprecated function cGroupManager::GetGroupManager() use cRoot::Get()->GetGroupManager() instead!"); - return cRoot::Get()->GetGroupManager(); -} - -cGroupManager::~cGroupManager() -{ - for( GroupMap::iterator itr = m_pState->Groups.begin(); itr != m_pState->Groups.end(); ++itr ) - { - delete itr->second; - } - m_pState->Groups.clear(); - - delete m_pState; -} - -cGroupManager::cGroupManager() - : m_pState( new sGroupManagerState ) -{ - LOG("-- Loading Groups --"); - cIniFile IniFile("groups.ini"); - if( IniFile.ReadFile() ) - { - unsigned int NumKeys = IniFile.GetNumKeys(); - for( unsigned int i = 0; i < NumKeys; i++ ) - { - std::string KeyName = IniFile.GetKeyName( i ); - cGroup* Group = GetGroup( KeyName.c_str() ); - - LOG("Loading group: %s", KeyName.c_str() ); - - Group->SetName( KeyName ); - char Color = IniFile.GetValue( KeyName, "Color", "-" )[0]; - if( Color != '-' ) - Group->SetColor( cChatColor::MakeColor(Color) ); - else - Group->SetColor( cChatColor::White ); - - std::string Commands = IniFile.GetValue( KeyName, "Commands", "" ); - if( Commands.size() > 0 ) - { - AStringVector Split = StringSplit( Commands, "," ); - for( unsigned int i = 0; i < Split.size(); i++) - { - Group->AddCommand( Split[i] ); - //LOG("%s", Split[i].c_str() ); - } - } - - std::string Permissions = IniFile.GetValue( KeyName, "Permissions", "" ); - if( Permissions.size() > 0 ) - { - AStringVector Split = StringSplit( Permissions, "," ); - for( unsigned int i = 0; i < Split.size(); i++) - { - Group->AddPermission( Split[i] ); - LOGINFO("Permission: %s", Split[i].c_str() ); - } - } - - std::string Groups = IniFile.GetValue( KeyName, "Inherits", "" ); - if( Groups.size() > 0 ) - { - AStringVector Split = StringSplit( Groups, "," ); - for( unsigned int i = 0; i < Split.size(); i++) - { - Group->InheritFrom( GetGroup( Split[i].c_str() ) ); - } - } - } - } - LOG("-- Done Loading Groups --"); -} - -cGroup* cGroupManager::GetGroup( const char* a_Name ) -{ - GroupMap::iterator itr = m_pState->Groups.find( a_Name ); - if( itr != m_pState->Groups.end() ) - { - return itr->second; - } - - cGroup* Group = new cGroup(); - m_pState->Groups[a_Name] = Group; - - return Group; - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cGroupManager.h" +#include "cGroup.h" +#include "../iniFile/iniFile.h" +#include "cChatColor.h" +#include "cRoot.h" + + + + + +typedef std::map< std::string, cGroup* > GroupMap; +struct cGroupManager::sGroupManagerState +{ + GroupMap Groups; +}; + +cGroupManager* cGroupManager::GetGroupManager() +{ + LOGWARN("WARNING: Using deprecated function cGroupManager::GetGroupManager() use cRoot::Get()->GetGroupManager() instead!"); + return cRoot::Get()->GetGroupManager(); +} + +cGroupManager::~cGroupManager() +{ + for( GroupMap::iterator itr = m_pState->Groups.begin(); itr != m_pState->Groups.end(); ++itr ) + { + delete itr->second; + } + m_pState->Groups.clear(); + + delete m_pState; +} + +cGroupManager::cGroupManager() + : m_pState( new sGroupManagerState ) +{ + LOG("-- Loading Groups --"); + cIniFile IniFile("groups.ini"); + if( IniFile.ReadFile() ) + { + unsigned int NumKeys = IniFile.GetNumKeys(); + for( unsigned int i = 0; i < NumKeys; i++ ) + { + std::string KeyName = IniFile.GetKeyName( i ); + cGroup* Group = GetGroup( KeyName.c_str() ); + + LOG("Loading group: %s", KeyName.c_str() ); + + Group->SetName( KeyName ); + char Color = IniFile.GetValue( KeyName, "Color", "-" )[0]; + if( Color != '-' ) + Group->SetColor( cChatColor::MakeColor(Color) ); + else + Group->SetColor( cChatColor::White ); + + std::string Commands = IniFile.GetValue( KeyName, "Commands", "" ); + if( Commands.size() > 0 ) + { + AStringVector Split = StringSplit( Commands, "," ); + for( unsigned int i = 0; i < Split.size(); i++) + { + Group->AddCommand( Split[i] ); + //LOG("%s", Split[i].c_str() ); + } + } + + std::string Permissions = IniFile.GetValue( KeyName, "Permissions", "" ); + if( Permissions.size() > 0 ) + { + AStringVector Split = StringSplit( Permissions, "," ); + for( unsigned int i = 0; i < Split.size(); i++) + { + Group->AddPermission( Split[i] ); + LOGINFO("Permission: %s", Split[i].c_str() ); + } + } + + std::string Groups = IniFile.GetValue( KeyName, "Inherits", "" ); + if( Groups.size() > 0 ) + { + AStringVector Split = StringSplit( Groups, "," ); + for( unsigned int i = 0; i < Split.size(); i++) + { + Group->InheritFrom( GetGroup( Split[i].c_str() ) ); + } + } + } + } + LOG("-- Done Loading Groups --"); +} + +cGroup* cGroupManager::GetGroup( const char* a_Name ) +{ + GroupMap::iterator itr = m_pState->Groups.find( a_Name ); + if( itr != m_pState->Groups.end() ) + { + return itr->second; + } + + cGroup* Group = new cGroup(); + m_pState->Groups[a_Name] = Group; + + return Group; + } \ No newline at end of file diff --git a/source/cGroupManager.h b/source/cGroupManager.h index fbd16f117..214d6991d 100644 --- a/source/cGroupManager.h +++ b/source/cGroupManager.h @@ -1,17 +1,17 @@ -#pragma once - -class cGroup; -class cGroupManager -{ -public: - static cGroupManager * GetGroupManager(); //tolua_export - - cGroup* GetGroup( const char* a_Name ); -private: - friend class cRoot; - cGroupManager(); - ~cGroupManager(); - - struct sGroupManagerState; - sGroupManagerState* m_pState; +#pragma once + +class cGroup; +class cGroupManager +{ +public: + static cGroupManager * GetGroupManager(); //tolua_export + + cGroup* GetGroup( const char* a_Name ); +private: + friend class cRoot; + cGroupManager(); + ~cGroupManager(); + + struct sGroupManagerState; + sGroupManagerState* m_pState; }; \ No newline at end of file diff --git a/source/cHeartBeat.cpp b/source/cHeartBeat.cpp index e8c49454d..5ac119593 100644 --- a/source/cHeartBeat.cpp +++ b/source/cHeartBeat.cpp @@ -1,144 +1,144 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cHeartBeat.h" -#include "cMCLogger.h" -#include "md5/md5.h" - -#include "cRoot.h" -#include "cServer.h" -#include "cSleep.h" - - - - - -cHeartBeat::cHeartBeat() -{ - m_State = 0; - Authenticate(); -} - - - - - -cHeartBeat::~cHeartBeat() -{ -} - - - - - -void cHeartBeat::ReceivedData( char a_Data[256], int a_Size ) -{ - if( a_Size < 0 ) // Disconnected - return; - - char MySalt[] = "1234567890"; - - if( a_Size == 0 ) - { - Authenticate(); - return; - } - - bool bLoop = false; - do - { - switch (m_State) - { - case 1: - { - m_ServerID = std::string( a_Data, a_Size ); - LOGINFO("Got server ID %s", m_ServerID.c_str() ); - std::string Hash = md5( m_ServerID + std::string( MySalt ) ); - CloseSocket(); - if( Connect( "mc-server.org", 80 ) ) - { - SendMessage( (std::string("GET http://master.mc-server.org/?hash=") + Hash + std::string("&server=") + m_ServerID + "\n").c_str() ); - m_State = 2; - } - } - break; - case 2: - { - std::string ReturnedString = std::string( a_Data, a_Size ); - if( ReturnedString.compare("VALIDATED") == 0 ) - { - LOGINFO("Successfully validated server on master server list"); - } - else - { - LOGINFO("Could not validate server! Will try again later."); - cSleep::MilliSleep( 10*1000 ); - Authenticate(); - return; - } - m_State = 3; - } // Don't break, but fall through and update server info - case 3: - { - cSleep::MilliSleep( 10*1000 ); - SendUpdate(); - m_State = 4; - } - break; - case 4: - { - if( a_Data[0] == '0' ) - { - LOGINFO("Successfully updated server info!"); - cSleep::MilliSleep( 10*1000 ); - SendUpdate(); - } - else - { - LOGINFO("Failed to update server info, reauthenticating"); - Authenticate(); - } - } - default: - break; - }; - } while( bLoop ); -} - - - - - -void cHeartBeat::SendUpdate() -{ - CloseSocket(); - if( Connect( "mc-server.org", 80 ) ) - { - int Port = cRoot::Get()->GetServer()->GetPort(); - AString Msg; - AString sPort; - Printf(sPort, "%i", Port); - AString sChecksum = md5( m_ServerID + sPort ); - Printf(Msg, "GET http://master.mc-server.org/?update=%s&checksum=%s&port=%d\n", m_ServerID.c_str(), sChecksum.c_str(), Port); - SendMessage(Msg.c_str()); - } -} - - - - - -void cHeartBeat::Authenticate() -{ - CloseSocket(); - if (Connect( "mc-server.org", 80)) - { - m_State = 1; - int RetVal = SendMessage( "GET http://master.mc-server.org/\r\n\r\n"); - LOGINFO("Returned %i", RetVal); - } -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cHeartBeat.h" +#include "cMCLogger.h" +#include "md5/md5.h" + +#include "cRoot.h" +#include "cServer.h" +#include "cSleep.h" + + + + + +cHeartBeat::cHeartBeat() +{ + m_State = 0; + Authenticate(); +} + + + + + +cHeartBeat::~cHeartBeat() +{ +} + + + + + +void cHeartBeat::ReceivedData( char a_Data[256], int a_Size ) +{ + if( a_Size < 0 ) // Disconnected + return; + + char MySalt[] = "1234567890"; + + if( a_Size == 0 ) + { + Authenticate(); + return; + } + + bool bLoop = false; + do + { + switch (m_State) + { + case 1: + { + m_ServerID = std::string( a_Data, a_Size ); + LOGINFO("Got server ID %s", m_ServerID.c_str() ); + std::string Hash = md5( m_ServerID + std::string( MySalt ) ); + CloseSocket(); + if( Connect( "mc-server.org", 80 ) ) + { + SendMessage( (std::string("GET http://master.mc-server.org/?hash=") + Hash + std::string("&server=") + m_ServerID + "\n").c_str() ); + m_State = 2; + } + } + break; + case 2: + { + std::string ReturnedString = std::string( a_Data, a_Size ); + if( ReturnedString.compare("VALIDATED") == 0 ) + { + LOGINFO("Successfully validated server on master server list"); + } + else + { + LOGINFO("Could not validate server! Will try again later."); + cSleep::MilliSleep( 10*1000 ); + Authenticate(); + return; + } + m_State = 3; + } // Don't break, but fall through and update server info + case 3: + { + cSleep::MilliSleep( 10*1000 ); + SendUpdate(); + m_State = 4; + } + break; + case 4: + { + if( a_Data[0] == '0' ) + { + LOGINFO("Successfully updated server info!"); + cSleep::MilliSleep( 10*1000 ); + SendUpdate(); + } + else + { + LOGINFO("Failed to update server info, reauthenticating"); + Authenticate(); + } + } + default: + break; + }; + } while( bLoop ); +} + + + + + +void cHeartBeat::SendUpdate() +{ + CloseSocket(); + if( Connect( "mc-server.org", 80 ) ) + { + int Port = cRoot::Get()->GetServer()->GetPort(); + AString Msg; + AString sPort; + Printf(sPort, "%i", Port); + AString sChecksum = md5( m_ServerID + sPort ); + Printf(Msg, "GET http://master.mc-server.org/?update=%s&checksum=%s&port=%d\n", m_ServerID.c_str(), sChecksum.c_str(), Port); + SendMessage(Msg.c_str()); + } +} + + + + + +void cHeartBeat::Authenticate() +{ + CloseSocket(); + if (Connect( "mc-server.org", 80)) + { + m_State = 1; + int RetVal = SendMessage( "GET http://master.mc-server.org/\r\n\r\n"); + LOGINFO("Returned %i", RetVal); + } +} + + + + diff --git a/source/cHeartBeat.h b/source/cHeartBeat.h index 0adaf6b59..416494701 100644 --- a/source/cHeartBeat.h +++ b/source/cHeartBeat.h @@ -1,28 +1,28 @@ - -#pragma once - -#include "cTCPLink.h" - - - - - -class cHeartBeat : public cTCPLink -{ -public: - cHeartBeat(); - ~cHeartBeat(); -private: - virtual void ReceivedData( char a_Data[256], int a_Size ); - - void Authenticate(); - int m_State; - - void SendUpdate(); - - std::string m_ServerID; -}; - - - - + +#pragma once + +#include "cTCPLink.h" + + + + + +class cHeartBeat : public cTCPLink +{ +public: + cHeartBeat(); + ~cHeartBeat(); +private: + virtual void ReceivedData( char a_Data[256], int a_Size ); + + void Authenticate(); + int m_State; + + void SendUpdate(); + + std::string m_ServerID; +}; + + + + diff --git a/source/cInventory.cpp b/source/cInventory.cpp index e3c92f307..8854ad29a 100644 --- a/source/cInventory.cpp +++ b/source/cInventory.cpp @@ -1,360 +1,360 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cInventory.h" -#include "cPlayer.h" -#include "cClientHandle.h" -#include "cWindow.h" -#include "cItem.h" -#include "cRoot.h" - -#include - -#include "packets/cPacket_WindowClick.h" -#include "packets/cPacket_WholeInventory.h" -#include "packets/cPacket_InventorySlot.h" - - - - - -cInventory::~cInventory() -{ - delete [] m_Slots; - delete m_EquippedItem; - if( GetWindow() ) GetWindow()->Close( *m_Owner ); - CloseWindow(); -} - - - - - -cInventory::cInventory(cPlayer* a_Owner) -{ - m_Owner = a_Owner; - - m_Slots = new cItem[c_NumSlots]; - for(unsigned int i = 0; i < c_NumSlots; i++) - m_Slots[i].Empty(); - - m_CraftSlots = m_Slots + c_CraftOffset; - m_ArmorSlots = m_Slots + c_ArmorOffset; - m_MainSlots = m_Slots + c_MainOffset; - m_HotSlots = m_Slots + c_HotOffset; - - m_EquippedItem = new cItem(); - m_EquippedSlot = 0; - - if( !GetWindow() ) - { - cWindow* Window = new cWindow( this, false ); - Window->SetSlots( m_Slots, c_NumSlots ); - Window->SetWindowID( 0 ); - OpenWindow( Window ); - } -} - - - - - -bool cInventory::AddItem( cItem & a_Item ) -{ - cItem BackupSlots[c_NumSlots]; - memcpy( BackupSlots, m_Slots, c_NumSlots * sizeof( cItem ) ); - - bool ChangedSlots[c_NumSlots]; - memset( ChangedSlots, false, c_NumSlots * sizeof( bool ) ); - - if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_HotOffset, c_HotSlots, ChangedSlots, 0 ); - if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_MainOffset, c_MainSlots, ChangedSlots, 0 ); - if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_HotOffset, c_HotSlots, ChangedSlots, 2 ); - if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_MainOffset, c_MainSlots, ChangedSlots, 2 ); - - if( a_Item.m_ItemCount > 0 ) // Could not add all items - { - // retore backup - memcpy( m_Slots, BackupSlots, c_NumSlots * sizeof( cItem ) ); - return false; - } - - for(unsigned int i = 0; i < c_NumSlots; i++) - { - if( ChangedSlots[i] ) - { - LOG("Item was added to %i ID:%i Count:%i", i, m_Slots[i].m_ItemID, m_Slots[i].m_ItemCount ); - SendSlot(i); - } - } - - return (a_Item.m_ItemCount == 0); -} - - - - - -// TODO: Right now if you dont have enough items, the items you did have are removed, and the function returns false anyway -bool cInventory::RemoveItem( cItem & a_Item ) -{ - // First check equipped slot - if( m_EquippedSlot >= 0 && m_EquippedSlot < 9 ) - { - if( m_HotSlots[m_EquippedSlot].m_ItemID == a_Item.m_ItemID ) - { - cItem & Item = m_HotSlots[m_EquippedSlot]; - if(Item.m_ItemCount > a_Item.m_ItemCount) - { - Item.m_ItemCount -= a_Item.m_ItemCount; - SendSlot( m_EquippedSlot + c_HotOffset ); - return true; - } - else if(Item.m_ItemCount > 0 ) - { - a_Item.m_ItemCount -= Item.m_ItemCount; - Item.Empty(); - SendSlot( m_EquippedSlot + c_HotOffset ); - } - } - } - - // Then check other slotz - if( a_Item.m_ItemCount > 0 ) - { - for(int i = 0; i < 36; i++) - { - cItem & Item = m_MainSlots[i]; - if( Item.m_ItemID == a_Item.m_ItemID ) - { - if(Item.m_ItemCount > a_Item.m_ItemCount) - { - Item.m_ItemCount -= a_Item.m_ItemCount; - SendSlot( i + c_MainOffset ); - return true; - } - else if(Item.m_ItemCount > 0 ) - { - a_Item.m_ItemCount -= Item.m_ItemCount; - Item.Empty(); - SendSlot( i + c_MainOffset ); - } - } - } - } - - if( a_Item.m_ItemCount == 0 ) - return true; - else - return false; -} - - - - - -void cInventory::Clear() -{ - for(unsigned int i = 0; i < c_NumSlots; i++) - m_Slots[i].Empty(); -} - - - - - -cItem * cInventory::GetSlotsForType( int a_Type ) -{ - switch( a_Type ) - { - case -1: - return m_MainSlots; - case -2: - return m_CraftSlots; - case -3: - return m_ArmorSlots; - } - return 0; -} - - - - - -int cInventory::GetSlotCountForType( int a_Type ) -{ - switch (a_Type) - { - case -1: - return 36; - case -2: - case -3: - return 4; - } - return 0; -} - - - - - -cItem* cInventory::GetSlot( int a_SlotNum ) -{ - if( a_SlotNum < 0 || a_SlotNum >= (short)c_NumSlots ) return 0; - return &m_Slots[a_SlotNum]; -} - - - - - -cItem* cInventory::GetFromHotBar( int a_SlotNum ) -{ - if ((a_SlotNum < 0) || (a_SlotNum >= 9)) - { - return NULL; - } - return &m_HotSlots[a_SlotNum]; -} - - - - - -void cInventory::SetEquippedSlot( int a_SlotNum ) -{ - if( a_SlotNum < 0 || a_SlotNum >= 9 ) m_EquippedSlot = 0; - else m_EquippedSlot = (short)a_SlotNum; -} - - - - - -cItem & cInventory::GetEquippedItem() -{ - cItem* Item = GetFromHotBar( m_EquippedSlot ); - if( Item ) - { - *m_EquippedItem = *Item; - return *Item; - } - else - { - m_EquippedItem->Empty(); - } - return *m_EquippedItem; -} - - - - - -void cInventory::SendWholeInventory( cClientHandle* a_Client ) -{ - cPacket_WholeInventory Inventory( this ); - a_Client->Send( Inventory ); -} - - - - - -void cInventory::SendSlot( int a_SlotNum ) -{ - cItem* Item = GetSlot( a_SlotNum ); - if( Item ) - { - cPacket_InventorySlot InventorySlot; - InventorySlot.m_ItemCount = Item->m_ItemCount; - InventorySlot.m_ItemID = (short) Item->m_ItemID; - InventorySlot.m_ItemUses = (char) Item->m_ItemHealth; - InventorySlot.m_SlotNum = (short) a_SlotNum; - InventorySlot.m_WindowID = 0; // Inventory window ID - m_Owner->GetClientHandle()->Send( InventorySlot ); - } -} - - - - - -bool cInventory::AddToBar( cItem & a_Item, const int a_Offset, const int a_Size, bool* a_bChangedSlots, int a_Mode /* = 0 */ ) -{ - // Fill already present stacks - if( a_Mode < 2 ) - { - for(int i = 0; i < a_Size; i++) - { - if( m_Slots[i + a_Offset].m_ItemID == a_Item.m_ItemID && m_Slots[i + a_Offset].m_ItemCount < 64 && m_Slots[i + a_Offset].m_ItemHealth == a_Item.m_ItemHealth ) - { - int NumFree = 64 - m_Slots[i + a_Offset].m_ItemCount; - if( NumFree >= a_Item.m_ItemCount ) - { - - //printf("1. Adding %i items ( free: %i )\n", a_Item.m_ItemCount, NumFree ); - m_Slots[i + a_Offset].m_ItemCount += a_Item.m_ItemCount; - a_Item.m_ItemCount = 0; - a_bChangedSlots[i + a_Offset] = true; - break; - } - else - { - //printf("2. Adding %i items\n", NumFree ); - m_Slots[i + a_Offset].m_ItemCount += (char)NumFree; - a_Item.m_ItemCount -= (char)NumFree; - a_bChangedSlots[i + a_Offset] = true; - } - } - } - } - - if( a_Mode > 0 ) - { - // If we got more left, find first empty slot - for(int i = 0; i < a_Size && a_Item.m_ItemCount > 0; i++) - { - if( m_Slots[i + a_Offset].m_ItemID == -1 ) - { - m_Slots[i + a_Offset] = a_Item; - a_Item.m_ItemCount = 0; - a_bChangedSlots[i + a_Offset] = true; - } - } - } - - return true; -} - - - - - -void cInventory::SaveToJson(Json::Value & a_Value) -{ - for(unsigned int i = 0; i < c_NumSlots; i++) - { - Json::Value JSON_Item; - m_Slots[i].GetJson( JSON_Item ); - a_Value.append( JSON_Item ); - } -} - - - - - -bool cInventory::LoadFromJson(Json::Value & a_Value) -{ - int SlotIdx = 0; - for( Json::Value::iterator itr = a_Value.begin(); itr != a_Value.end(); ++itr ) - { - m_Slots[SlotIdx].FromJson( *itr ); - SlotIdx++; - } - return true; -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cInventory.h" +#include "cPlayer.h" +#include "cClientHandle.h" +#include "cWindow.h" +#include "cItem.h" +#include "cRoot.h" + +#include + +#include "packets/cPacket_WindowClick.h" +#include "packets/cPacket_WholeInventory.h" +#include "packets/cPacket_InventorySlot.h" + + + + + +cInventory::~cInventory() +{ + delete [] m_Slots; + delete m_EquippedItem; + if( GetWindow() ) GetWindow()->Close( *m_Owner ); + CloseWindow(); +} + + + + + +cInventory::cInventory(cPlayer* a_Owner) +{ + m_Owner = a_Owner; + + m_Slots = new cItem[c_NumSlots]; + for(unsigned int i = 0; i < c_NumSlots; i++) + m_Slots[i].Empty(); + + m_CraftSlots = m_Slots + c_CraftOffset; + m_ArmorSlots = m_Slots + c_ArmorOffset; + m_MainSlots = m_Slots + c_MainOffset; + m_HotSlots = m_Slots + c_HotOffset; + + m_EquippedItem = new cItem(); + m_EquippedSlot = 0; + + if( !GetWindow() ) + { + cWindow* Window = new cWindow( this, false ); + Window->SetSlots( m_Slots, c_NumSlots ); + Window->SetWindowID( 0 ); + OpenWindow( Window ); + } +} + + + + + +bool cInventory::AddItem( cItem & a_Item ) +{ + cItem BackupSlots[c_NumSlots]; + memcpy( BackupSlots, m_Slots, c_NumSlots * sizeof( cItem ) ); + + bool ChangedSlots[c_NumSlots]; + memset( ChangedSlots, false, c_NumSlots * sizeof( bool ) ); + + if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_HotOffset, c_HotSlots, ChangedSlots, 0 ); + if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_MainOffset, c_MainSlots, ChangedSlots, 0 ); + if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_HotOffset, c_HotSlots, ChangedSlots, 2 ); + if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_MainOffset, c_MainSlots, ChangedSlots, 2 ); + + if( a_Item.m_ItemCount > 0 ) // Could not add all items + { + // retore backup + memcpy( m_Slots, BackupSlots, c_NumSlots * sizeof( cItem ) ); + return false; + } + + for(unsigned int i = 0; i < c_NumSlots; i++) + { + if( ChangedSlots[i] ) + { + LOG("Item was added to %i ID:%i Count:%i", i, m_Slots[i].m_ItemID, m_Slots[i].m_ItemCount ); + SendSlot(i); + } + } + + return (a_Item.m_ItemCount == 0); +} + + + + + +// TODO: Right now if you dont have enough items, the items you did have are removed, and the function returns false anyway +bool cInventory::RemoveItem( cItem & a_Item ) +{ + // First check equipped slot + if( m_EquippedSlot >= 0 && m_EquippedSlot < 9 ) + { + if( m_HotSlots[m_EquippedSlot].m_ItemID == a_Item.m_ItemID ) + { + cItem & Item = m_HotSlots[m_EquippedSlot]; + if(Item.m_ItemCount > a_Item.m_ItemCount) + { + Item.m_ItemCount -= a_Item.m_ItemCount; + SendSlot( m_EquippedSlot + c_HotOffset ); + return true; + } + else if(Item.m_ItemCount > 0 ) + { + a_Item.m_ItemCount -= Item.m_ItemCount; + Item.Empty(); + SendSlot( m_EquippedSlot + c_HotOffset ); + } + } + } + + // Then check other slotz + if( a_Item.m_ItemCount > 0 ) + { + for(int i = 0; i < 36; i++) + { + cItem & Item = m_MainSlots[i]; + if( Item.m_ItemID == a_Item.m_ItemID ) + { + if(Item.m_ItemCount > a_Item.m_ItemCount) + { + Item.m_ItemCount -= a_Item.m_ItemCount; + SendSlot( i + c_MainOffset ); + return true; + } + else if(Item.m_ItemCount > 0 ) + { + a_Item.m_ItemCount -= Item.m_ItemCount; + Item.Empty(); + SendSlot( i + c_MainOffset ); + } + } + } + } + + if( a_Item.m_ItemCount == 0 ) + return true; + else + return false; +} + + + + + +void cInventory::Clear() +{ + for(unsigned int i = 0; i < c_NumSlots; i++) + m_Slots[i].Empty(); +} + + + + + +cItem * cInventory::GetSlotsForType( int a_Type ) +{ + switch( a_Type ) + { + case -1: + return m_MainSlots; + case -2: + return m_CraftSlots; + case -3: + return m_ArmorSlots; + } + return 0; +} + + + + + +int cInventory::GetSlotCountForType( int a_Type ) +{ + switch (a_Type) + { + case -1: + return 36; + case -2: + case -3: + return 4; + } + return 0; +} + + + + + +cItem* cInventory::GetSlot( int a_SlotNum ) +{ + if( a_SlotNum < 0 || a_SlotNum >= (short)c_NumSlots ) return 0; + return &m_Slots[a_SlotNum]; +} + + + + + +cItem* cInventory::GetFromHotBar( int a_SlotNum ) +{ + if ((a_SlotNum < 0) || (a_SlotNum >= 9)) + { + return NULL; + } + return &m_HotSlots[a_SlotNum]; +} + + + + + +void cInventory::SetEquippedSlot( int a_SlotNum ) +{ + if( a_SlotNum < 0 || a_SlotNum >= 9 ) m_EquippedSlot = 0; + else m_EquippedSlot = (short)a_SlotNum; +} + + + + + +cItem & cInventory::GetEquippedItem() +{ + cItem* Item = GetFromHotBar( m_EquippedSlot ); + if( Item ) + { + *m_EquippedItem = *Item; + return *Item; + } + else + { + m_EquippedItem->Empty(); + } + return *m_EquippedItem; +} + + + + + +void cInventory::SendWholeInventory( cClientHandle* a_Client ) +{ + cPacket_WholeInventory Inventory( this ); + a_Client->Send( Inventory ); +} + + + + + +void cInventory::SendSlot( int a_SlotNum ) +{ + cItem* Item = GetSlot( a_SlotNum ); + if( Item ) + { + cPacket_InventorySlot InventorySlot; + InventorySlot.m_ItemCount = Item->m_ItemCount; + InventorySlot.m_ItemID = (short) Item->m_ItemID; + InventorySlot.m_ItemUses = (char) Item->m_ItemHealth; + InventorySlot.m_SlotNum = (short) a_SlotNum; + InventorySlot.m_WindowID = 0; // Inventory window ID + m_Owner->GetClientHandle()->Send( InventorySlot ); + } +} + + + + + +bool cInventory::AddToBar( cItem & a_Item, const int a_Offset, const int a_Size, bool* a_bChangedSlots, int a_Mode /* = 0 */ ) +{ + // Fill already present stacks + if( a_Mode < 2 ) + { + for(int i = 0; i < a_Size; i++) + { + if( m_Slots[i + a_Offset].m_ItemID == a_Item.m_ItemID && m_Slots[i + a_Offset].m_ItemCount < 64 && m_Slots[i + a_Offset].m_ItemHealth == a_Item.m_ItemHealth ) + { + int NumFree = 64 - m_Slots[i + a_Offset].m_ItemCount; + if( NumFree >= a_Item.m_ItemCount ) + { + + //printf("1. Adding %i items ( free: %i )\n", a_Item.m_ItemCount, NumFree ); + m_Slots[i + a_Offset].m_ItemCount += a_Item.m_ItemCount; + a_Item.m_ItemCount = 0; + a_bChangedSlots[i + a_Offset] = true; + break; + } + else + { + //printf("2. Adding %i items\n", NumFree ); + m_Slots[i + a_Offset].m_ItemCount += (char)NumFree; + a_Item.m_ItemCount -= (char)NumFree; + a_bChangedSlots[i + a_Offset] = true; + } + } + } + } + + if( a_Mode > 0 ) + { + // If we got more left, find first empty slot + for(int i = 0; i < a_Size && a_Item.m_ItemCount > 0; i++) + { + if( m_Slots[i + a_Offset].m_ItemID == -1 ) + { + m_Slots[i + a_Offset] = a_Item; + a_Item.m_ItemCount = 0; + a_bChangedSlots[i + a_Offset] = true; + } + } + } + + return true; +} + + + + + +void cInventory::SaveToJson(Json::Value & a_Value) +{ + for(unsigned int i = 0; i < c_NumSlots; i++) + { + Json::Value JSON_Item; + m_Slots[i].GetJson( JSON_Item ); + a_Value.append( JSON_Item ); + } +} + + + + + +bool cInventory::LoadFromJson(Json::Value & a_Value) +{ + int SlotIdx = 0; + for( Json::Value::iterator itr = a_Value.begin(); itr != a_Value.end(); ++itr ) + { + m_Slots[SlotIdx].FromJson( *itr ); + SlotIdx++; + } + return true; +} + + + + diff --git a/source/cInventory.h b/source/cInventory.h index b7e91195b..0b4220b32 100644 --- a/source/cInventory.h +++ b/source/cInventory.h @@ -1,82 +1,82 @@ - -#pragma once - -#include "cWindowOwner.h" -#include "FileDefine.h" - -namespace Json -{ - class Value; -}; - -class cItem; -class cClientHandle; -class cPlayer; -class cPacket; -class cPacket_EntityEquipment; - - - - - -class cInventory //tolua_export - : public cWindowOwner -{ //tolua_export -public: - cInventory(cPlayer* a_Owner); - ~cInventory(); - - void Clear(); //tolua_export - - cItem* GetSlotsForType( int a_Type ); - int GetSlotCountForType( int a_Type ); - - bool AddItem( cItem & a_Item ); //tolua_export - bool RemoveItem( cItem & a_Item ); //tolua_export - - void SaveToJson(Json::Value & a_Value); - bool LoadFromJson(Json::Value & a_Value); - - void SendWholeInventory( cClientHandle* a_Client ); - - cItem* GetSlot( int a_SlotNum ); //tolua_export - cItem* GetSlots() { return m_Slots; } - cItem* GetFromHotBar( int a_SlotNum ); //tolua_export - - cItem & GetEquippedItem(); //tolua_export - void SetEquippedSlot( int a_SlotNum ); //tolua_export - short GetEquippedSlot() { return m_EquippedSlot; } //tolua_export - - virtual void Clicked( cPacket* a_ClickPacket ) = 0; - - void SendSlot( int a_SlotNum ); //tolua_export - - static const unsigned int c_NumSlots = 45; - static const unsigned int c_MainSlots = 27; - static const unsigned int c_HotSlots = 9; - static const unsigned int c_CraftSlots = 4; - static const unsigned int c_ArmorSlots = 4; - - static const unsigned int c_CraftOffset = 0; - static const unsigned int c_ArmorOffset = 5; - static const unsigned int c_MainOffset = 9; - static const unsigned int c_HotOffset = 36; - -protected: - bool AddToBar( cItem & a_Item, const int a_Offset, const int a_Size, bool* a_bChangedSlots, int a_Mode = 0 ); - - cItem* m_Slots; - cItem* m_MainSlots; - cItem* m_CraftSlots; - cItem* m_ArmorSlots; - cItem* m_HotSlots; - - cItem* m_EquippedItem; - short m_EquippedSlot; - - cPlayer* m_Owner; -}; //tolua_export - - - - + +#pragma once + +#include "cWindowOwner.h" +#include "FileDefine.h" + +namespace Json +{ + class Value; +}; + +class cItem; +class cClientHandle; +class cPlayer; +class cPacket; +class cPacket_EntityEquipment; + + + + + +class cInventory //tolua_export + : public cWindowOwner +{ //tolua_export +public: + cInventory(cPlayer* a_Owner); + ~cInventory(); + + void Clear(); //tolua_export + + cItem* GetSlotsForType( int a_Type ); + int GetSlotCountForType( int a_Type ); + + bool AddItem( cItem & a_Item ); //tolua_export + bool RemoveItem( cItem & a_Item ); //tolua_export + + void SaveToJson(Json::Value & a_Value); + bool LoadFromJson(Json::Value & a_Value); + + void SendWholeInventory( cClientHandle* a_Client ); + + cItem* GetSlot( int a_SlotNum ); //tolua_export + cItem* GetSlots() { return m_Slots; } + cItem* GetFromHotBar( int a_SlotNum ); //tolua_export + + cItem & GetEquippedItem(); //tolua_export + void SetEquippedSlot( int a_SlotNum ); //tolua_export + short GetEquippedSlot() { return m_EquippedSlot; } //tolua_export + + virtual void Clicked( cPacket* a_ClickPacket ) = 0; + + void SendSlot( int a_SlotNum ); //tolua_export + + static const unsigned int c_NumSlots = 45; + static const unsigned int c_MainSlots = 27; + static const unsigned int c_HotSlots = 9; + static const unsigned int c_CraftSlots = 4; + static const unsigned int c_ArmorSlots = 4; + + static const unsigned int c_CraftOffset = 0; + static const unsigned int c_ArmorOffset = 5; + static const unsigned int c_MainOffset = 9; + static const unsigned int c_HotOffset = 36; + +protected: + bool AddToBar( cItem & a_Item, const int a_Offset, const int a_Size, bool* a_bChangedSlots, int a_Mode = 0 ); + + cItem* m_Slots; + cItem* m_MainSlots; + cItem* m_CraftSlots; + cItem* m_ArmorSlots; + cItem* m_HotSlots; + + cItem* m_EquippedItem; + short m_EquippedSlot; + + cPlayer* m_Owner; +}; //tolua_export + + + + diff --git a/source/cIsThread.cpp b/source/cIsThread.cpp index edde68767..cfc6fa72a 100644 --- a/source/cIsThread.cpp +++ b/source/cIsThread.cpp @@ -1,167 +1,167 @@ - -// cIsThread.cpp - -// Implements the cIsThread class representing an OS-independent wrapper for a class that implements a thread. -// This class will eventually suupersede the old cThread class - -#include "Globals.h" - -#include "cIsThread.h" - - - - - -// When in MSVC, the debugger provides "thread naming" by catching special exceptions. Interface here: -#if defined(_MSC_VER) && defined(_DEBUG) -// -// Usage: SetThreadName (-1, "MainThread"); -// - -static void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName) -{ - struct - { - DWORD dwType; // must be 0x1000 - LPCSTR szName; // pointer to name (in user addr space) - DWORD dwThreadID; // thread ID (-1=caller thread) - DWORD dwFlags; // reserved for future use, must be zero - } info; - - info.dwType = 0x1000; - info.szName = szThreadName; - info.dwThreadID = dwThreadID; - info.dwFlags = 0; - - __try - { - RaiseException(0x406D1388, 0, sizeof(info) / sizeof(DWORD), (DWORD *)&info); - } - __except(EXCEPTION_CONTINUE_EXECUTION) - { - } -} -#endif // _MSC_VER && _DEBUG - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cIsThread: - -cIsThread::cIsThread(const AString & iThreadName) : - m_ThreadName(iThreadName), - m_ShouldTerminate(false), - #ifdef _WIN32 - m_Handle(NULL) - #else // _WIN32 - m_HasStarted(false) - #endif // else _WIN32 -{ -} - - - - - -cIsThread::~cIsThread() -{ - m_ShouldTerminate = true; - Wait(); -} - - - - - -bool cIsThread::Start(void) -{ - #ifdef _WIN32 - ASSERT(m_Handle == NULL); // Has already started one thread? - - // Create the thread suspended, so that the mHandle variable is valid in the thread procedure - DWORD ThreadID = 0; - m_Handle = CreateThread(NULL, 0, thrExecute, this, CREATE_SUSPENDED, &ThreadID); - if (m_Handle == NULL) - { - LOGERROR("ERROR: Could not create thread \"%s\", GLE = %d!", m_ThreadName.c_str(), GetLastError()); - return false; - } - ResumeThread(m_Handle); - - #if defined(_DEBUG) && defined(_MSC_VER) - // Thread naming is available only in MSVC - if (!m_ThreadName.empty()) - { - SetThreadName(ThreadID, m_ThreadName.c_str()); - } - #endif // _DEBUG and _MSC_VER - - #else // _WIN32 - ASSERT(!m_HasStarted); - - if (pthread_create(&m_Handle, NULL, thrExecute, this)) - { - LOGERROR("ERROR: Could not create thread \"%s\", !", m_ThreadName.c_str()); - return false; - } - m_HasStarted = true; - #endif // else _WIN32 - - return true; -} - - - - - -bool cIsThread::Wait(void) -{ - #ifdef _WIN32 - - if (m_Handle == NULL) - { - return true; - } - // Cannot log, logger may already be stopped: - // LOG("Waiting for thread \"%s\" to terminate.", m_ThreadName.c_str()); - int res = WaitForSingleObject(m_Handle, INFINITE); - m_Handle = NULL; - // Cannot log, logger may already be stopped: - // LOG("Thread \"%s\" %s terminated, GLE = %d", m_ThreadName.c_str(), (res == WAIT_OBJECT_0) ? "" : "not", GetLastError()); - return (res == WAIT_OBJECT_0); - - #else // _WIN32 - - if (!m_HasStarted) - { - return true; - } - // Cannot log, logger may already be stopped: - // LOG("Waiting for thread \"%s\" to terminate.", m_ThreadName.c_str()); - int res = pthread_join(m_Handle, NULL); - m_HasStarted = false; - // Cannot log, logger may already be stopped: - // LOG("Thread \"%s\" %s terminated, errno = %d", m_ThreadName.c_str(), (res == 0) ? "" : "not", errno); - return (res == 0); - - #endif // else _WIN32 -} - - - - - -unsigned long cIsThread::GetCurrentID(void) -{ - #ifdef _WIN32 - return (unsigned long) GetCurrentThreadId(); - #else - return (unsigned long) pthread_self(); - #endif -} - - - - + +// cIsThread.cpp + +// Implements the cIsThread class representing an OS-independent wrapper for a class that implements a thread. +// This class will eventually suupersede the old cThread class + +#include "Globals.h" + +#include "cIsThread.h" + + + + + +// When in MSVC, the debugger provides "thread naming" by catching special exceptions. Interface here: +#if defined(_MSC_VER) && defined(_DEBUG) +// +// Usage: SetThreadName (-1, "MainThread"); +// + +static void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName) +{ + struct + { + DWORD dwType; // must be 0x1000 + LPCSTR szName; // pointer to name (in user addr space) + DWORD dwThreadID; // thread ID (-1=caller thread) + DWORD dwFlags; // reserved for future use, must be zero + } info; + + info.dwType = 0x1000; + info.szName = szThreadName; + info.dwThreadID = dwThreadID; + info.dwFlags = 0; + + __try + { + RaiseException(0x406D1388, 0, sizeof(info) / sizeof(DWORD), (DWORD *)&info); + } + __except(EXCEPTION_CONTINUE_EXECUTION) + { + } +} +#endif // _MSC_VER && _DEBUG + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cIsThread: + +cIsThread::cIsThread(const AString & iThreadName) : + m_ThreadName(iThreadName), + m_ShouldTerminate(false), + #ifdef _WIN32 + m_Handle(NULL) + #else // _WIN32 + m_HasStarted(false) + #endif // else _WIN32 +{ +} + + + + + +cIsThread::~cIsThread() +{ + m_ShouldTerminate = true; + Wait(); +} + + + + + +bool cIsThread::Start(void) +{ + #ifdef _WIN32 + ASSERT(m_Handle == NULL); // Has already started one thread? + + // Create the thread suspended, so that the mHandle variable is valid in the thread procedure + DWORD ThreadID = 0; + m_Handle = CreateThread(NULL, 0, thrExecute, this, CREATE_SUSPENDED, &ThreadID); + if (m_Handle == NULL) + { + LOGERROR("ERROR: Could not create thread \"%s\", GLE = %d!", m_ThreadName.c_str(), GetLastError()); + return false; + } + ResumeThread(m_Handle); + + #if defined(_DEBUG) && defined(_MSC_VER) + // Thread naming is available only in MSVC + if (!m_ThreadName.empty()) + { + SetThreadName(ThreadID, m_ThreadName.c_str()); + } + #endif // _DEBUG and _MSC_VER + + #else // _WIN32 + ASSERT(!m_HasStarted); + + if (pthread_create(&m_Handle, NULL, thrExecute, this)) + { + LOGERROR("ERROR: Could not create thread \"%s\", !", m_ThreadName.c_str()); + return false; + } + m_HasStarted = true; + #endif // else _WIN32 + + return true; +} + + + + + +bool cIsThread::Wait(void) +{ + #ifdef _WIN32 + + if (m_Handle == NULL) + { + return true; + } + // Cannot log, logger may already be stopped: + // LOG("Waiting for thread \"%s\" to terminate.", m_ThreadName.c_str()); + int res = WaitForSingleObject(m_Handle, INFINITE); + m_Handle = NULL; + // Cannot log, logger may already be stopped: + // LOG("Thread \"%s\" %s terminated, GLE = %d", m_ThreadName.c_str(), (res == WAIT_OBJECT_0) ? "" : "not", GetLastError()); + return (res == WAIT_OBJECT_0); + + #else // _WIN32 + + if (!m_HasStarted) + { + return true; + } + // Cannot log, logger may already be stopped: + // LOG("Waiting for thread \"%s\" to terminate.", m_ThreadName.c_str()); + int res = pthread_join(m_Handle, NULL); + m_HasStarted = false; + // Cannot log, logger may already be stopped: + // LOG("Thread \"%s\" %s terminated, errno = %d", m_ThreadName.c_str(), (res == 0) ? "" : "not", errno); + return (res == 0); + + #endif // else _WIN32 +} + + + + + +unsigned long cIsThread::GetCurrentID(void) +{ + #ifdef _WIN32 + return (unsigned long) GetCurrentThreadId(); + #else + return (unsigned long) pthread_self(); + #endif +} + + + + diff --git a/source/cIsThread.h b/source/cIsThread.h index 20084dfad..e2d53565d 100644 --- a/source/cIsThread.h +++ b/source/cIsThread.h @@ -1,78 +1,78 @@ - -// cIsThread.h - -// Interfaces to the cIsThread class representing an OS-independent wrapper for a class that implements a thread. -// This class will eventually suupersede the old cThread class - -/* -Usage: -To have a new thread, declare a class descending from cIsClass. -Then override its Execute() method to provide your thread processing. -In the descending class' constructor call the Start() method to start the thread once you're finished with initialization. -*/ - - - - - -#pragma once -#ifndef CISTHREAD_H_INCLUDED -#define CISTHREAD_H_INCLUDED - - - - - -class cIsThread -{ -protected: - virtual void Execute(void) = 0; // This function is called in the new thread's context - - volatile bool m_ShouldTerminate; // The overriden Execute() method should check this periodically and terminate if this is true - -public: - cIsThread(const AString & iThreadName); - ~cIsThread(); - - bool Start(void); // Starts the thread - bool Wait(void); // Waits for the thread to finish - - static unsigned long GetCurrentID(void); // Returns the OS-dependent thread ID for the caller's thread - -private: - AString m_ThreadName; - - #ifdef _WIN32 - - HANDLE m_Handle; - - static DWORD_PTR __stdcall thrExecute(LPVOID a_Param) - { - ((cIsThread *)a_Param)->Execute(); - return 0; - } - - #else // _WIN32 - - pthread_t m_Handle; - bool m_HasStarted; - - static void * thrExecute(void * a_Param) - { - ((cIsThread *)a_Param)->Execute(); - return NULL; - } - - #endif // else _WIN32 - -} ; - - - - - -#endif // CISTHREAD_H_INCLUDED - - - - + +// cIsThread.h + +// Interfaces to the cIsThread class representing an OS-independent wrapper for a class that implements a thread. +// This class will eventually suupersede the old cThread class + +/* +Usage: +To have a new thread, declare a class descending from cIsClass. +Then override its Execute() method to provide your thread processing. +In the descending class' constructor call the Start() method to start the thread once you're finished with initialization. +*/ + + + + + +#pragma once +#ifndef CISTHREAD_H_INCLUDED +#define CISTHREAD_H_INCLUDED + + + + + +class cIsThread +{ +protected: + virtual void Execute(void) = 0; // This function is called in the new thread's context + + volatile bool m_ShouldTerminate; // The overriden Execute() method should check this periodically and terminate if this is true + +public: + cIsThread(const AString & iThreadName); + ~cIsThread(); + + bool Start(void); // Starts the thread + bool Wait(void); // Waits for the thread to finish + + static unsigned long GetCurrentID(void); // Returns the OS-dependent thread ID for the caller's thread + +private: + AString m_ThreadName; + + #ifdef _WIN32 + + HANDLE m_Handle; + + static DWORD_PTR __stdcall thrExecute(LPVOID a_Param) + { + ((cIsThread *)a_Param)->Execute(); + return 0; + } + + #else // _WIN32 + + pthread_t m_Handle; + bool m_HasStarted; + + static void * thrExecute(void * a_Param) + { + ((cIsThread *)a_Param)->Execute(); + return NULL; + } + + #endif // else _WIN32 + +} ; + + + + + +#endif // CISTHREAD_H_INCLUDED + + + + diff --git a/source/cItem.cpp b/source/cItem.cpp index acb51611a..f13b9cbf3 100644 --- a/source/cItem.cpp +++ b/source/cItem.cpp @@ -1,51 +1,51 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cItem.h" -#include - - - - - -void cItem::GetJson( Json::Value & a_OutValue ) const -{ - a_OutValue["ID"] = m_ItemID; - if( m_ItemID > 0 ) - { - a_OutValue["Count"] = m_ItemCount; - a_OutValue["Health"] = m_ItemHealth; - } -} - -void cItem::FromJson( const Json::Value & a_Value ) -{ - m_ItemID = (ENUM_ITEM_ID)a_Value.get("ID", -1 ).asInt(); - if( m_ItemID > 0 ) - { - m_ItemCount = (char)a_Value.get("Count", -1 ).asInt(); - m_ItemHealth = (short)a_Value.get("Health", -1 ).asInt(); - } -} - -bool cItem::IsEnchantable(ENUM_ITEM_ID item) -{ - if(item >= 256 && item <= 259) - return true; - if(item >= 267 && item <= 279) - return true; - if(item >= 283 && item <= 286) - return true; - if(item >= 290 && item <= 294) - return true; - if(item >= 298 && item <= 317) - return true; - if(item >= 290 && item <= 294) - return true; - - if(item == 346 || item == 359 || item == 261) - return true; - - - return false; -} + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cItem.h" +#include + + + + + +void cItem::GetJson( Json::Value & a_OutValue ) const +{ + a_OutValue["ID"] = m_ItemID; + if( m_ItemID > 0 ) + { + a_OutValue["Count"] = m_ItemCount; + a_OutValue["Health"] = m_ItemHealth; + } +} + +void cItem::FromJson( const Json::Value & a_Value ) +{ + m_ItemID = (ENUM_ITEM_ID)a_Value.get("ID", -1 ).asInt(); + if( m_ItemID > 0 ) + { + m_ItemCount = (char)a_Value.get("Count", -1 ).asInt(); + m_ItemHealth = (short)a_Value.get("Health", -1 ).asInt(); + } +} + +bool cItem::IsEnchantable(ENUM_ITEM_ID item) +{ + if(item >= 256 && item <= 259) + return true; + if(item >= 267 && item <= 279) + return true; + if(item >= 283 && item <= 286) + return true; + if(item >= 290 && item <= 294) + return true; + if(item >= 298 && item <= 317) + return true; + if(item >= 290 && item <= 294) + return true; + + if(item == 346 || item == 359 || item == 261) + return true; + + + return false; +} diff --git a/source/cItem.h b/source/cItem.h index 28eed0d42..0f4aa6b70 100644 --- a/source/cItem.h +++ b/source/cItem.h @@ -1,114 +1,114 @@ -#pragma once - -#include "Defines.h" -#include "BlockID.h" - -namespace Json -{ - class Value; -}; - - - - - -// tolua_begin -class cItem -{ -public: - cItem( ENUM_ITEM_ID a_ItemID = E_ITEM_EMPTY, char a_ItemCount = 0, short a_ItemHealth = 0 ) - : m_ItemID ( a_ItemID ) - , m_ItemCount ( a_ItemCount ) - , m_ItemHealth ( a_ItemHealth ) - { - if(!IsValidItem( m_ItemID ) ) m_ItemID = E_ITEM_EMPTY; - } - void Empty() - { - m_ItemID = E_ITEM_EMPTY; - m_ItemCount = 0; - m_ItemHealth = 0; - } - void Clear(void) - { - m_ItemID = E_ITEM_EMPTY; - m_ItemCount = 0; - m_ItemHealth = 0; - } - bool IsEmpty(void) const - { - return (m_ItemID <= 0 || m_ItemCount <= 0); - } - bool Equals( cItem & a_Item ) const - { - return ( (m_ItemID == a_Item.m_ItemID) && (m_ItemHealth == a_Item.m_ItemHealth) ); - } - - // TODO Sorry for writing the functions in the header. But somehow it doesn´t worked when I put them into the cpp File :s - - inline int GetMaxDuration(void) const - { - switch(m_ItemID) - { - case 256: return 251; - case 257: return 251; - case 258: return 251; - case 259: return 65; //Lighter / Flint and Steel - case 267: return 251; - case 268: return 60; - case 269: return 60; - case 270: return 60; - case 271: return 60; - case 272: return 132; - case 273: return 132; - case 274: return 132; - case 275: return 132; - case 276: return 1563; - case 277: return 1563; - case 278: return 1563; - case 279: return 1563; - case 283: return 32; - case 284: return 32; - case 285: return 32; - case 286: return 32; - case 290: return 60; - case 291: return 132; - case 292: return 251; - case 293: return 1563; - case 294: return 32; - case 359: return 251; - default: return 0; - } - } - - // Damages a weapon / tool. Returns true when destroyed - inline bool DamageItem() - { - if (HasDuration()) - { - m_ItemHealth++; - if(m_ItemHealth >= GetMaxDuration()) - return true; - } - return false; - } - - inline bool HasDuration() { return GetMaxDuration() > 0; } - - void GetJson( Json::Value & a_OutValue ) const; - void FromJson( const Json::Value & a_Value ); - - static bool IsEnchantable(ENUM_ITEM_ID item); - - ENUM_ITEM_ID m_ItemID; - char m_ItemCount; - short m_ItemHealth; - -}; -// tolua_end - -typedef std::vector cItems; - - - - +#pragma once + +#include "Defines.h" +#include "BlockID.h" + +namespace Json +{ + class Value; +}; + + + + + +// tolua_begin +class cItem +{ +public: + cItem( ENUM_ITEM_ID a_ItemID = E_ITEM_EMPTY, char a_ItemCount = 0, short a_ItemHealth = 0 ) + : m_ItemID ( a_ItemID ) + , m_ItemCount ( a_ItemCount ) + , m_ItemHealth ( a_ItemHealth ) + { + if(!IsValidItem( m_ItemID ) ) m_ItemID = E_ITEM_EMPTY; + } + void Empty() + { + m_ItemID = E_ITEM_EMPTY; + m_ItemCount = 0; + m_ItemHealth = 0; + } + void Clear(void) + { + m_ItemID = E_ITEM_EMPTY; + m_ItemCount = 0; + m_ItemHealth = 0; + } + bool IsEmpty(void) const + { + return (m_ItemID <= 0 || m_ItemCount <= 0); + } + bool Equals( cItem & a_Item ) const + { + return ( (m_ItemID == a_Item.m_ItemID) && (m_ItemHealth == a_Item.m_ItemHealth) ); + } + + // TODO Sorry for writing the functions in the header. But somehow it doesn´t worked when I put them into the cpp File :s + + inline int GetMaxDuration(void) const + { + switch(m_ItemID) + { + case 256: return 251; + case 257: return 251; + case 258: return 251; + case 259: return 65; //Lighter / Flint and Steel + case 267: return 251; + case 268: return 60; + case 269: return 60; + case 270: return 60; + case 271: return 60; + case 272: return 132; + case 273: return 132; + case 274: return 132; + case 275: return 132; + case 276: return 1563; + case 277: return 1563; + case 278: return 1563; + case 279: return 1563; + case 283: return 32; + case 284: return 32; + case 285: return 32; + case 286: return 32; + case 290: return 60; + case 291: return 132; + case 292: return 251; + case 293: return 1563; + case 294: return 32; + case 359: return 251; + default: return 0; + } + } + + // Damages a weapon / tool. Returns true when destroyed + inline bool DamageItem() + { + if (HasDuration()) + { + m_ItemHealth++; + if(m_ItemHealth >= GetMaxDuration()) + return true; + } + return false; + } + + inline bool HasDuration() { return GetMaxDuration() > 0; } + + void GetJson( Json::Value & a_OutValue ) const; + void FromJson( const Json::Value & a_Value ); + + static bool IsEnchantable(ENUM_ITEM_ID item); + + ENUM_ITEM_ID m_ItemID; + char m_ItemCount; + short m_ItemHealth; + +}; +// tolua_end + +typedef std::vector cItems; + + + + diff --git a/source/cLadder.h b/source/cLadder.h index be3964f10..b3dc0fb96 100644 --- a/source/cLadder.h +++ b/source/cLadder.h @@ -1,43 +1,43 @@ -#pragma once - -class cLadder //tolua_export -{ //tolua_export -public: - - static char DirectionToMetaData( char a_Direction ) //tolua_export - { //tolua_export - switch( a_Direction ) - { - case 0x2: - return 0x2; - case 0x3: - return 0x3; - case 0x4: - return 0x4; - case 0x5: - return 0x5; - default: - break; - }; - return 0x2; - } //tolua_export - - static char MetaDataToDirection( char a_MetaData ) //tolua_export - { //tolua_export - switch( a_MetaData ) - { - case 0x2: - return 0x2; - case 0x3: - return 0x3; - case 0x4: - return 0x4; - case 0x5: - return 0x5; - default: - break; - }; - return 0x2; - } //tolua_export - +#pragma once + +class cLadder //tolua_export +{ //tolua_export +public: + + static char DirectionToMetaData( char a_Direction ) //tolua_export + { //tolua_export + switch( a_Direction ) + { + case 0x2: + return 0x2; + case 0x3: + return 0x3; + case 0x4: + return 0x4; + case 0x5: + return 0x5; + default: + break; + }; + return 0x2; + } //tolua_export + + static char MetaDataToDirection( char a_MetaData ) //tolua_export + { //tolua_export + switch( a_MetaData ) + { + case 0x2: + return 0x2; + case 0x3: + return 0x3; + case 0x4: + return 0x4; + case 0x5: + return 0x5; + default: + break; + }; + return 0x2; + } //tolua_export + }; //tolua_export \ No newline at end of file diff --git a/source/cLavaSimulator.cpp b/source/cLavaSimulator.cpp index ad9afcdc8..6e3c2a3fa 100644 --- a/source/cLavaSimulator.cpp +++ b/source/cLavaSimulator.cpp @@ -1,20 +1,20 @@ -#include "Globals.h" -#include "cLavaSimulator.h" -#include "Defines.h" -#include "cWorld.h" - - -cLavaSimulator::cLavaSimulator(cWorld *a_World) - : cFluidSimulator(a_World) -{ - m_FluidBlock = E_BLOCK_LAVA; - m_StationaryFluidBlock = E_BLOCK_STATIONARY_LAVA; - m_MaxHeight = 6; - m_FlowReduction = 2; -} - - -bool cLavaSimulator::IsAllowedBlock(char a_BlockID) -{ - return IsBlockLava(a_BlockID); +#include "Globals.h" +#include "cLavaSimulator.h" +#include "Defines.h" +#include "cWorld.h" + + +cLavaSimulator::cLavaSimulator(cWorld *a_World) + : cFluidSimulator(a_World) +{ + m_FluidBlock = E_BLOCK_LAVA; + m_StationaryFluidBlock = E_BLOCK_STATIONARY_LAVA; + m_MaxHeight = 6; + m_FlowReduction = 2; +} + + +bool cLavaSimulator::IsAllowedBlock(char a_BlockID) +{ + return IsBlockLava(a_BlockID); } \ No newline at end of file diff --git a/source/cLavaSimulator.h b/source/cLavaSimulator.h index aa20b4d1d..44f9935dd 100644 --- a/source/cLavaSimulator.h +++ b/source/cLavaSimulator.h @@ -1,12 +1,12 @@ -#pragma once -#include "cFluidSimulator.h" - -class cLavaSimulator : public cFluidSimulator -{ -public: - cLavaSimulator( cWorld* a_World ); - - virtual bool IsAllowedBlock( char a_BlockID ); - - +#pragma once +#include "cFluidSimulator.h" + +class cLavaSimulator : public cFluidSimulator +{ +public: + cLavaSimulator( cWorld* a_World ); + + virtual bool IsAllowedBlock( char a_BlockID ); + + }; \ No newline at end of file diff --git a/source/cLog.cpp b/source/cLog.cpp index cf8448d8b..5e79b48bf 100644 --- a/source/cLog.cpp +++ b/source/cLog.cpp @@ -1,159 +1,159 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cLog.h" - -#include -#include -#include "cMakeDir.h" - -#include "cIsThread.h" - - - - - -cLog* cLog::s_Log = NULL; - -cLog::cLog(const AString & a_FileName ) - : m_File(NULL) -{ - s_Log = this; - - // create logs directory - cMakeDir::MakeDir("logs"); - - OpenLog( (std::string("logs/") + a_FileName).c_str() ); -} - - - - - -cLog::~cLog() -{ - CloseLog(); - s_Log = NULL; -} - - - - - -cLog* cLog::GetInstance() -{ - if(s_Log) - return s_Log; - - new cLog("log.txt"); - return s_Log; -} - - - - - -void cLog::CloseLog() -{ - if( m_File ) - fclose (m_File); - m_File = 0; -} - - - - - -void cLog::OpenLog( const char* a_FileName ) -{ - if(m_File) fclose (m_File); - #ifdef _WIN32 - fopen_s( &m_File, a_FileName, "a+" ); - #else - m_File = fopen(a_FileName, "a+" ); - #endif -} - - - - - -void cLog::ClearLog() -{ - #ifdef _WIN32 - if( fopen_s( &m_File, "log.txt", "w" ) == 0) - fclose (m_File); - #else - m_File = fopen("log.txt", "w" ); - if( m_File ) - fclose (m_File); - #endif - m_File = 0; -} - - - - - -void cLog::Log(const char * a_Format, va_list argList) -{ - AString Message; - AppendVPrintf(Message, a_Format, argList); - - time_t rawtime; - time ( &rawtime ); - - struct tm* timeinfo; -#ifdef _WIN32 - struct tm timeinforeal; - timeinfo = &timeinforeal; - localtime_s(timeinfo, &rawtime ); -#else - timeinfo = localtime( &rawtime ); -#endif - - AString Line; - #ifdef _DEBUG - Printf(Line, "[%04x|%02d:%02d:%02d] %s\n", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); - #else - Printf(Line, "[%02d:%02d:%02d] %s\n", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); - #endif - if (m_File) - { - fputs(Line.c_str(), m_File); - fflush(m_File); - } - - // Print to console: - printf("%s", Line.c_str()); - - #if defined (_WIN32) && defined(_DEBUG) - // In a Windows Debug build, output the log to debug console as well: - OutputDebugString(Line.c_str()); - #endif // _WIN32 -} - - - - - -void cLog::Log(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - Log( a_Format, argList ); - va_end(argList); -} - - - - - -void cLog::SimpleLog(const char* a_String) -{ - Log("%s", a_String ); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cLog.h" + +#include +#include +#include "cMakeDir.h" + +#include "cIsThread.h" + + + + + +cLog* cLog::s_Log = NULL; + +cLog::cLog(const AString & a_FileName ) + : m_File(NULL) +{ + s_Log = this; + + // create logs directory + cMakeDir::MakeDir("logs"); + + OpenLog( (std::string("logs/") + a_FileName).c_str() ); +} + + + + + +cLog::~cLog() +{ + CloseLog(); + s_Log = NULL; +} + + + + + +cLog* cLog::GetInstance() +{ + if(s_Log) + return s_Log; + + new cLog("log.txt"); + return s_Log; +} + + + + + +void cLog::CloseLog() +{ + if( m_File ) + fclose (m_File); + m_File = 0; +} + + + + + +void cLog::OpenLog( const char* a_FileName ) +{ + if(m_File) fclose (m_File); + #ifdef _WIN32 + fopen_s( &m_File, a_FileName, "a+" ); + #else + m_File = fopen(a_FileName, "a+" ); + #endif +} + + + + + +void cLog::ClearLog() +{ + #ifdef _WIN32 + if( fopen_s( &m_File, "log.txt", "w" ) == 0) + fclose (m_File); + #else + m_File = fopen("log.txt", "w" ); + if( m_File ) + fclose (m_File); + #endif + m_File = 0; +} + + + + + +void cLog::Log(const char * a_Format, va_list argList) +{ + AString Message; + AppendVPrintf(Message, a_Format, argList); + + time_t rawtime; + time ( &rawtime ); + + struct tm* timeinfo; +#ifdef _WIN32 + struct tm timeinforeal; + timeinfo = &timeinforeal; + localtime_s(timeinfo, &rawtime ); +#else + timeinfo = localtime( &rawtime ); +#endif + + AString Line; + #ifdef _DEBUG + Printf(Line, "[%04x|%02d:%02d:%02d] %s\n", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); + #else + Printf(Line, "[%02d:%02d:%02d] %s\n", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); + #endif + if (m_File) + { + fputs(Line.c_str(), m_File); + fflush(m_File); + } + + // Print to console: + printf("%s", Line.c_str()); + + #if defined (_WIN32) && defined(_DEBUG) + // In a Windows Debug build, output the log to debug console as well: + OutputDebugString(Line.c_str()); + #endif // _WIN32 +} + + + + + +void cLog::Log(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + Log( a_Format, argList ); + va_end(argList); +} + + + + + +void cLog::SimpleLog(const char* a_String) +{ + Log("%s", a_String ); +} + + + + diff --git a/source/cLog.h b/source/cLog.h index 1a688b0c0..f48dae822 100644 --- a/source/cLog.h +++ b/source/cLog.h @@ -1,32 +1,32 @@ - -#pragma once - -#include "FileDefine.h" - - - - - -class cLog -{ // tolua_export -private: - FILE * m_File; - static cLog * s_Log; - -public: - cLog(const AString & a_FileName); - ~cLog(); - void Log(const char* a_Format, va_list argList ); - void Log(const char* a_Format, ...); - //tolua_begin - void SimpleLog(const char* a_String); - void OpenLog( const char* a_FileName ); - void CloseLog(); - void ClearLog(); - static cLog* GetInstance(); -}; -//tolua_end - - - - + +#pragma once + +#include "FileDefine.h" + + + + + +class cLog +{ // tolua_export +private: + FILE * m_File; + static cLog * s_Log; + +public: + cLog(const AString & a_FileName); + ~cLog(); + void Log(const char* a_Format, va_list argList ); + void Log(const char* a_Format, ...); + //tolua_begin + void SimpleLog(const char* a_String); + void OpenLog( const char* a_FileName ); + void CloseLog(); + void ClearLog(); + static cLog* GetInstance(); +}; +//tolua_end + + + + diff --git a/source/cLuaChunk.cpp b/source/cLuaChunk.cpp index c97595599..a5f831ba7 100644 --- a/source/cLuaChunk.cpp +++ b/source/cLuaChunk.cpp @@ -1,4 +1,4 @@ -#include "Globals.h" - -#include "cLuaChunk.h" - +#include "Globals.h" + +#include "cLuaChunk.h" + diff --git a/source/cLuaChunk.h b/source/cLuaChunk.h index 70aa4e615..dc6f2a0f2 100644 --- a/source/cLuaChunk.h +++ b/source/cLuaChunk.h @@ -1,139 +1,139 @@ -#pragma once - -#include "ChunkDef.h" - -class cLuaChunk //tolua_export -{ //tolua_export -public: - cLuaChunk( cChunkDef::BlockTypes & a_BlockTypes - , cChunkDef::BlockNibbles & a_BlockNibbles - , cChunkDef::HeightMap & a_HeightMap - , cChunkDef::BiomeMap & a_BiomeMap - ) - : m_BiomeMap( a_BiomeMap ) - , m_BlockTypes( a_BlockTypes ) - , m_BlockMeta( a_BlockNibbles ) - , m_HeightMap( a_HeightMap ) - , m_bUseDefaultBiomes( false ) - , m_bUseDefaultComposition( false ) - , m_bUseDefaultStructures( false ) - , m_bUseDefaultFinish( false ) - { - memset( m_BlockTypes, 0, sizeof( cChunkDef::BlockTypes ) ); - memset( m_BlockMeta, 0, sizeof( cChunkDef::BlockNibbles ) ); - memset( m_BiomeMap, 0, sizeof( cChunkDef::BiomeMap ) ); - memset( m_HeightMap, 0, sizeof( cChunkDef::HeightMap ) ); - } - ~cLuaChunk() - {} - - //tolua_begin - - // Block functions - void FillBlocks( char a_BlockID, unsigned char a_BlockMeta ) - { - const NIBBLETYPE CompressedMeta = a_BlockMeta | a_BlockMeta << 4; - memset( m_BlockTypes, a_BlockID, sizeof( cChunkDef::BlockTypes ) ); - memset( m_BlockMeta, CompressedMeta, sizeof( cChunkDef::BlockNibbles ) ); - } - - void SetBlock( int a_X, int a_Y, int a_Z, char a_BlockID, unsigned char a_BlockMeta ) - { - cChunkDef::SetBlock( m_BlockTypes, a_X, a_Y, a_Z, a_BlockID ); - cChunkDef::SetNibble( m_BlockMeta, a_X, a_Y, a_Z, a_BlockMeta ); - } - - char GetBlock( int a_X, int a_Y, int a_Z ) - { - return cChunkDef::GetBlock( m_BlockTypes, a_X, a_Y, a_Z ); - } - - char GetBlockMeta( int a_X, int a_Y, int a_Z ) - { - return cChunkDef::GetNibble( m_BlockMeta, a_X, a_Y, a_Z ); - } - - - - - - // Biome functinos - void SetBiome( int a_X, int a_Z, int a_BiomeID ) - { - cChunkDef::SetBiome( m_BiomeMap, a_X, a_Z, (EMCSBiome)a_BiomeID ); - } - - int GetBiome( int a_X, int a_Z ) - { - return cChunkDef::GetBiome( m_BiomeMap, a_X, a_Z ); - } - - - - - - // Height functions - void SetHeight( int a_X, int a_Z, int a_Height ) - { - cChunkDef::SetHeight( m_HeightMap, a_X, a_Z, a_Height ); - } - - int GetHeight( int a_X, int a_Z ) - { - return cChunkDef::GetHeight( m_HeightMap, a_X, a_Z ); - } - - - - - - // Functions to explicitly tell the server to use default behavior for certain parts of generating terrain - void SetUseDefaultBiomes( bool a_bUseDefaultBiomes ) - { - m_bUseDefaultBiomes = a_bUseDefaultBiomes; - } - bool IsUsingDefaultBiomes() - { - return m_bUseDefaultBiomes; - } - - void SetUseDefaultComposition( bool a_bUseDefaultComposition ) - { - m_bUseDefaultComposition = a_bUseDefaultComposition; - } - bool IsUsingDefaultComposition() - { - return m_bUseDefaultComposition; - } - - void SetUseDefaultStructures( bool a_bUseDefaultStructures ) - { - m_bUseDefaultStructures = a_bUseDefaultStructures; - } - bool IsUsingDefaultStructures() - { - return m_bUseDefaultStructures; - } - - void SetUseDefaultFinish( bool a_bUseDefaultFinish ) - { - m_bUseDefaultFinish = a_bUseDefaultFinish; - } - bool IsUsingDefaultFinish() - { - return m_bUseDefaultFinish; - } - - //tolua_end - -private: - bool m_bUseDefaultBiomes; - bool m_bUseDefaultComposition; - bool m_bUseDefaultStructures; - bool m_bUseDefaultFinish; - - cChunkDef::BiomeMap & m_BiomeMap; - cChunkDef::BlockTypes & m_BlockTypes; - cChunkDef::BlockNibbles & m_BlockMeta; - cChunkDef::HeightMap & m_HeightMap; +#pragma once + +#include "ChunkDef.h" + +class cLuaChunk //tolua_export +{ //tolua_export +public: + cLuaChunk( cChunkDef::BlockTypes & a_BlockTypes + , cChunkDef::BlockNibbles & a_BlockNibbles + , cChunkDef::HeightMap & a_HeightMap + , cChunkDef::BiomeMap & a_BiomeMap + ) + : m_BiomeMap( a_BiomeMap ) + , m_BlockTypes( a_BlockTypes ) + , m_BlockMeta( a_BlockNibbles ) + , m_HeightMap( a_HeightMap ) + , m_bUseDefaultBiomes( false ) + , m_bUseDefaultComposition( false ) + , m_bUseDefaultStructures( false ) + , m_bUseDefaultFinish( false ) + { + memset( m_BlockTypes, 0, sizeof( cChunkDef::BlockTypes ) ); + memset( m_BlockMeta, 0, sizeof( cChunkDef::BlockNibbles ) ); + memset( m_BiomeMap, 0, sizeof( cChunkDef::BiomeMap ) ); + memset( m_HeightMap, 0, sizeof( cChunkDef::HeightMap ) ); + } + ~cLuaChunk() + {} + + //tolua_begin + + // Block functions + void FillBlocks( char a_BlockID, unsigned char a_BlockMeta ) + { + const NIBBLETYPE CompressedMeta = a_BlockMeta | a_BlockMeta << 4; + memset( m_BlockTypes, a_BlockID, sizeof( cChunkDef::BlockTypes ) ); + memset( m_BlockMeta, CompressedMeta, sizeof( cChunkDef::BlockNibbles ) ); + } + + void SetBlock( int a_X, int a_Y, int a_Z, char a_BlockID, unsigned char a_BlockMeta ) + { + cChunkDef::SetBlock( m_BlockTypes, a_X, a_Y, a_Z, a_BlockID ); + cChunkDef::SetNibble( m_BlockMeta, a_X, a_Y, a_Z, a_BlockMeta ); + } + + char GetBlock( int a_X, int a_Y, int a_Z ) + { + return cChunkDef::GetBlock( m_BlockTypes, a_X, a_Y, a_Z ); + } + + char GetBlockMeta( int a_X, int a_Y, int a_Z ) + { + return cChunkDef::GetNibble( m_BlockMeta, a_X, a_Y, a_Z ); + } + + + + + + // Biome functinos + void SetBiome( int a_X, int a_Z, int a_BiomeID ) + { + cChunkDef::SetBiome( m_BiomeMap, a_X, a_Z, (EMCSBiome)a_BiomeID ); + } + + int GetBiome( int a_X, int a_Z ) + { + return cChunkDef::GetBiome( m_BiomeMap, a_X, a_Z ); + } + + + + + + // Height functions + void SetHeight( int a_X, int a_Z, int a_Height ) + { + cChunkDef::SetHeight( m_HeightMap, a_X, a_Z, a_Height ); + } + + int GetHeight( int a_X, int a_Z ) + { + return cChunkDef::GetHeight( m_HeightMap, a_X, a_Z ); + } + + + + + + // Functions to explicitly tell the server to use default behavior for certain parts of generating terrain + void SetUseDefaultBiomes( bool a_bUseDefaultBiomes ) + { + m_bUseDefaultBiomes = a_bUseDefaultBiomes; + } + bool IsUsingDefaultBiomes() + { + return m_bUseDefaultBiomes; + } + + void SetUseDefaultComposition( bool a_bUseDefaultComposition ) + { + m_bUseDefaultComposition = a_bUseDefaultComposition; + } + bool IsUsingDefaultComposition() + { + return m_bUseDefaultComposition; + } + + void SetUseDefaultStructures( bool a_bUseDefaultStructures ) + { + m_bUseDefaultStructures = a_bUseDefaultStructures; + } + bool IsUsingDefaultStructures() + { + return m_bUseDefaultStructures; + } + + void SetUseDefaultFinish( bool a_bUseDefaultFinish ) + { + m_bUseDefaultFinish = a_bUseDefaultFinish; + } + bool IsUsingDefaultFinish() + { + return m_bUseDefaultFinish; + } + + //tolua_end + +private: + bool m_bUseDefaultBiomes; + bool m_bUseDefaultComposition; + bool m_bUseDefaultStructures; + bool m_bUseDefaultFinish; + + cChunkDef::BiomeMap & m_BiomeMap; + cChunkDef::BlockTypes & m_BlockTypes; + cChunkDef::BlockNibbles & m_BlockMeta; + cChunkDef::HeightMap & m_HeightMap; }; //tolua_export \ No newline at end of file diff --git a/source/cLuaCommandBinder.cpp b/source/cLuaCommandBinder.cpp index 712ea61c3..62d57b640 100644 --- a/source/cLuaCommandBinder.cpp +++ b/source/cLuaCommandBinder.cpp @@ -1,122 +1,122 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cLuaCommandBinder.h" -#include "cPlayer.h" -#include "cPlugin.h" -#include "cPlugin_Lua.h" - -#include "tolua++.h" - - - - - -extern bool report_errors(lua_State* lua, int status); - -cLuaCommandBinder::cLuaCommandBinder() -{ -} - -cLuaCommandBinder::~cLuaCommandBinder() -{ -} - -void cLuaCommandBinder::ClearBindings() -{ - m_BoundCommands.clear(); -} - -void cLuaCommandBinder::RemoveBindingsForPlugin( cPlugin* a_Plugin ) -{ - for( CommandMap::iterator itr = m_BoundCommands.begin(); itr != m_BoundCommands.end(); ) - { - if( itr->second.Plugin == a_Plugin ) - { - LOGINFO("Unbinding %s ", itr->first.c_str( ) ); - luaL_unref( itr->second.LuaState, LUA_REGISTRYINDEX, itr->second.Reference ); // unreference - CommandMap::iterator eraseme = itr; - ++itr; - m_BoundCommands.erase( eraseme ); - continue; - } - ++itr; - } -} - -bool cLuaCommandBinder::BindCommand( const std::string & a_Command, const std::string & a_Permission, cPlugin* a_Plugin, lua_State * a_LuaState, int a_FunctionReference ) -{ - if( !a_Plugin->CanBindCommands() ) - { - LOGERROR("ERROR: Trying to bind command \"%s\" to a plugin that is not initialized.", a_Command.c_str() ); - return false; - } - if( m_BoundCommands.find( a_Command ) != m_BoundCommands.end() ) - { - LOGERROR("ERROR: Trying to bind command \"%s\" that has already been bound.", a_Command.c_str() ); - return false; - } - LOGINFO("Binding %s (%s)", a_Command.c_str(), a_Permission.c_str() ); - m_BoundCommands[ a_Command ] = BoundFunction( a_Plugin, a_LuaState, a_FunctionReference, a_Permission ); - return true; -} - -bool cLuaCommandBinder::HandleCommand( const std::string & a_Command, cPlayer* a_Player ) -{ - AStringVector Split = StringSplit(a_Command, " "); - if (Split.size() == 0) - { - return false; - } - - CommandMap::iterator FoundCommand = m_BoundCommands.find( Split[0] ); - if( FoundCommand != m_BoundCommands.end() ) - { - const BoundFunction & func = FoundCommand->second; - if( func.Permission.size() > 0 ) - { - if( !a_Player->HasPermission( func.Permission.c_str() ) ) - { - return false; - } - } - - // For enabling 'self' in the function, it's kind of a hack I'm not sure this is the way to go - lua_pushvalue(func.LuaState, LUA_GLOBALSINDEX); - lua_pushstring(func.LuaState, "self"); - tolua_pushusertype( func.LuaState, func.Plugin, "cPlugin" ); - lua_rawset(func.LuaState, -3); - lua_pop(func.LuaState, 1); - - LOGINFO("1. Stack size: %i", lua_gettop(func.LuaState) ); - lua_rawgeti( func.LuaState, LUA_REGISTRYINDEX, func.Reference); // same as lua_getref() - - // Push the split - LOGINFO("2. Stack size: %i", lua_gettop(func.LuaState) ); - lua_createtable(func.LuaState, Split.size(), 0); - int newTable = lua_gettop(func.LuaState); - int index = 1; - std::vector::const_iterator iter = Split.begin(); - while(iter != Split.end()) { - tolua_pushstring( func.LuaState, (*iter).c_str() ); - lua_rawseti(func.LuaState, newTable, index); - ++iter; - ++index; - } - LOGINFO("3. Stack size: %i", lua_gettop(func.LuaState) ); - // Push player - tolua_pushusertype( func.LuaState, a_Player, "cPlayer" ); - LOGINFO("Calling bound function! :D"); - int s = lua_pcall(func.LuaState, 2, 1, 0); - if( report_errors( func.LuaState, s ) ) - { - LOGINFO("error. Stack size: %i", lua_gettop(func.LuaState) ); - return false; - } - bool RetVal = (tolua_toboolean(func.LuaState, -1, 0) > 0); - lua_pop(func.LuaState, 1); // Pop return value - LOGINFO("ok. Stack size: %i", lua_gettop(func.LuaState) ); - return RetVal; - } - return false; -} + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cLuaCommandBinder.h" +#include "cPlayer.h" +#include "cPlugin.h" +#include "cPlugin_Lua.h" + +#include "tolua++.h" + + + + + +extern bool report_errors(lua_State* lua, int status); + +cLuaCommandBinder::cLuaCommandBinder() +{ +} + +cLuaCommandBinder::~cLuaCommandBinder() +{ +} + +void cLuaCommandBinder::ClearBindings() +{ + m_BoundCommands.clear(); +} + +void cLuaCommandBinder::RemoveBindingsForPlugin( cPlugin* a_Plugin ) +{ + for( CommandMap::iterator itr = m_BoundCommands.begin(); itr != m_BoundCommands.end(); ) + { + if( itr->second.Plugin == a_Plugin ) + { + LOGINFO("Unbinding %s ", itr->first.c_str( ) ); + luaL_unref( itr->second.LuaState, LUA_REGISTRYINDEX, itr->second.Reference ); // unreference + CommandMap::iterator eraseme = itr; + ++itr; + m_BoundCommands.erase( eraseme ); + continue; + } + ++itr; + } +} + +bool cLuaCommandBinder::BindCommand( const std::string & a_Command, const std::string & a_Permission, cPlugin* a_Plugin, lua_State * a_LuaState, int a_FunctionReference ) +{ + if( !a_Plugin->CanBindCommands() ) + { + LOGERROR("ERROR: Trying to bind command \"%s\" to a plugin that is not initialized.", a_Command.c_str() ); + return false; + } + if( m_BoundCommands.find( a_Command ) != m_BoundCommands.end() ) + { + LOGERROR("ERROR: Trying to bind command \"%s\" that has already been bound.", a_Command.c_str() ); + return false; + } + LOGINFO("Binding %s (%s)", a_Command.c_str(), a_Permission.c_str() ); + m_BoundCommands[ a_Command ] = BoundFunction( a_Plugin, a_LuaState, a_FunctionReference, a_Permission ); + return true; +} + +bool cLuaCommandBinder::HandleCommand( const std::string & a_Command, cPlayer* a_Player ) +{ + AStringVector Split = StringSplit(a_Command, " "); + if (Split.size() == 0) + { + return false; + } + + CommandMap::iterator FoundCommand = m_BoundCommands.find( Split[0] ); + if( FoundCommand != m_BoundCommands.end() ) + { + const BoundFunction & func = FoundCommand->second; + if( func.Permission.size() > 0 ) + { + if( !a_Player->HasPermission( func.Permission.c_str() ) ) + { + return false; + } + } + + // For enabling 'self' in the function, it's kind of a hack I'm not sure this is the way to go + lua_pushvalue(func.LuaState, LUA_GLOBALSINDEX); + lua_pushstring(func.LuaState, "self"); + tolua_pushusertype( func.LuaState, func.Plugin, "cPlugin" ); + lua_rawset(func.LuaState, -3); + lua_pop(func.LuaState, 1); + + LOGINFO("1. Stack size: %i", lua_gettop(func.LuaState) ); + lua_rawgeti( func.LuaState, LUA_REGISTRYINDEX, func.Reference); // same as lua_getref() + + // Push the split + LOGINFO("2. Stack size: %i", lua_gettop(func.LuaState) ); + lua_createtable(func.LuaState, Split.size(), 0); + int newTable = lua_gettop(func.LuaState); + int index = 1; + std::vector::const_iterator iter = Split.begin(); + while(iter != Split.end()) { + tolua_pushstring( func.LuaState, (*iter).c_str() ); + lua_rawseti(func.LuaState, newTable, index); + ++iter; + ++index; + } + LOGINFO("3. Stack size: %i", lua_gettop(func.LuaState) ); + // Push player + tolua_pushusertype( func.LuaState, a_Player, "cPlayer" ); + LOGINFO("Calling bound function! :D"); + int s = lua_pcall(func.LuaState, 2, 1, 0); + if( report_errors( func.LuaState, s ) ) + { + LOGINFO("error. Stack size: %i", lua_gettop(func.LuaState) ); + return false; + } + bool RetVal = (tolua_toboolean(func.LuaState, -1, 0) > 0); + lua_pop(func.LuaState, 1); // Pop return value + LOGINFO("ok. Stack size: %i", lua_gettop(func.LuaState) ); + return RetVal; + } + return false; +} diff --git a/source/cLuaCommandBinder.h b/source/cLuaCommandBinder.h index b623c5c92..768d097f8 100644 --- a/source/cLuaCommandBinder.h +++ b/source/cLuaCommandBinder.h @@ -1,42 +1,42 @@ - -#pragma once - -struct lua_State; -class cPlugin; -class cPlayer; - - - - - -class cLuaCommandBinder -{ -public: - cLuaCommandBinder(); - ~cLuaCommandBinder(); - - bool HandleCommand( const std::string & a_Command, cPlayer* a_Player ); - - bool BindCommand( const std::string & a_Command, const std::string & a_Permission, cPlugin* a_Plugin, lua_State * a_LuaState, int a_FunctionReference ); - - void ClearBindings(); - void RemoveBindingsForPlugin( cPlugin* a_Plugin ); -private: - struct BoundFunction - { - BoundFunction() : Plugin( 0 ), LuaState( 0 ), Reference( 0 ) {} - BoundFunction( cPlugin* a_Plugin, lua_State * a_LuaState, int a_Reference, const std::string & a_Permission ) : Plugin( a_Plugin ), LuaState( a_LuaState ), Reference( a_Reference ), Permission( a_Permission ) {} - cPlugin* Plugin; - lua_State* LuaState; - int Reference; - std::string Permission; - }; - - typedef std::map< std::string, BoundFunction > CommandMap; - CommandMap m_BoundCommands; -}; - - - - - + +#pragma once + +struct lua_State; +class cPlugin; +class cPlayer; + + + + + +class cLuaCommandBinder +{ +public: + cLuaCommandBinder(); + ~cLuaCommandBinder(); + + bool HandleCommand( const std::string & a_Command, cPlayer* a_Player ); + + bool BindCommand( const std::string & a_Command, const std::string & a_Permission, cPlugin* a_Plugin, lua_State * a_LuaState, int a_FunctionReference ); + + void ClearBindings(); + void RemoveBindingsForPlugin( cPlugin* a_Plugin ); +private: + struct BoundFunction + { + BoundFunction() : Plugin( 0 ), LuaState( 0 ), Reference( 0 ) {} + BoundFunction( cPlugin* a_Plugin, lua_State * a_LuaState, int a_Reference, const std::string & a_Permission ) : Plugin( a_Plugin ), LuaState( a_LuaState ), Reference( a_Reference ), Permission( a_Permission ) {} + cPlugin* Plugin; + lua_State* LuaState; + int Reference; + std::string Permission; + }; + + typedef std::map< std::string, BoundFunction > CommandMap; + CommandMap m_BoundCommands; +}; + + + + + diff --git a/source/cMCLogger.cpp b/source/cMCLogger.cpp index 0869daa53..4e0823d14 100644 --- a/source/cMCLogger.cpp +++ b/source/cMCLogger.cpp @@ -1,191 +1,191 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include -#include "cLog.h" - - - - - -cMCLogger* cMCLogger::s_MCLogger = 0; - -cMCLogger* cMCLogger::GetInstance() -{ - return s_MCLogger; -} - - - - - -cMCLogger::cMCLogger() -{ - AString FileName; - Printf(FileName, "LOG_%d.txt", (int)time(0) ); - m_Log = new cLog(FileName); - m_Log->Log("--- Started Log ---"); - - s_MCLogger = this; -} - - - - - -cMCLogger::cMCLogger( char* a_File ) -{ - m_Log = new cLog( a_File ); -} - - - - - -cMCLogger::~cMCLogger() -{ - m_Log->Log("--- Stopped Log ---"); - delete m_Log; - if (this == s_MCLogger) - s_MCLogger = NULL; -} - - - - - -void cMCLogger::LogSimple(const char* a_Text, int a_LogType /* = 0 */ ) -{ - switch( a_LogType ) - { - case 0: - LOG("%s", a_Text); - break; - case 1: - LOGINFO("%s", a_Text); - break; - case 2: - LOGWARN("%s", a_Text); - break; - case 3: - LOGERROR("%s", a_Text); - break; - default: - LOG("(#%d#: %s", a_LogType, a_Text); - break; - } -} - - - - - -void cMCLogger::Log(const char* a_Format, va_list a_ArgList) -{ - cCSLock Lock(m_CriticalSection); - SetColor( 0x7 ); // 0x7 is default grey color - m_Log->Log( a_Format, a_ArgList ); - SetColor(0x07); // revert color back -} - - - - - -void cMCLogger::Info(const char* a_Format, va_list a_ArgList) -{ - cCSLock Lock(m_CriticalSection); -// for( int i = 0; i < 16; i++) -// { -// for( int j = 0; j < 16; j++ ) -// { -// SetConsoleTextAttribute( hConsole, i | (j<<4) ); -// printf("0x%x", (i|j<<4)); -// } -// printf("\n"); -// } - - SetColor( 0xe ); // 0xe is yellow - m_Log->Log( a_Format, a_ArgList ); - SetColor(0x07); // revert color back -} - - - - - -void cMCLogger::Warn(const char* a_Format, va_list a_ArgList) -{ - cCSLock Lock(m_CriticalSection); - SetColor( 0xc ); // 0xc is red - m_Log->Log( a_Format, a_ArgList ); - SetColor(0x07); // revert color back -} - - - - - -void cMCLogger::Error(const char* a_Format, va_list a_ArgList) -{ - cCSLock Lock(m_CriticalSection); - SetColor( 0xc0 ); // 0xc0 is red bg and black text - m_Log->Log( a_Format, a_ArgList ); - SetColor(0x07); // revert color back -} - - - - - -void cMCLogger::SetColor( unsigned char a_Color ) -{ -#ifdef _WIN32 - HANDLE hConsole = GetStdHandle( STD_OUTPUT_HANDLE ); - SetConsoleTextAttribute( hConsole, a_Color ); -#else - (void)a_Color; -#endif -} - - - - - -////////////////////////////////////////////////////////////////////////// -// Global functions -void LOG(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - cMCLogger::GetInstance()->Log( a_Format, argList ); - va_end(argList); -} - -void LOGINFO(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - cMCLogger::GetInstance()->Info( a_Format, argList ); - va_end(argList); -} - -void LOGWARN(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - cMCLogger::GetInstance()->Warn( a_Format, argList ); - va_end(argList); -} - -void LOGERROR(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - cMCLogger::GetInstance()->Error( a_Format, argList ); - va_end(argList); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include +#include "cLog.h" + + + + + +cMCLogger* cMCLogger::s_MCLogger = 0; + +cMCLogger* cMCLogger::GetInstance() +{ + return s_MCLogger; +} + + + + + +cMCLogger::cMCLogger() +{ + AString FileName; + Printf(FileName, "LOG_%d.txt", (int)time(0) ); + m_Log = new cLog(FileName); + m_Log->Log("--- Started Log ---"); + + s_MCLogger = this; +} + + + + + +cMCLogger::cMCLogger( char* a_File ) +{ + m_Log = new cLog( a_File ); +} + + + + + +cMCLogger::~cMCLogger() +{ + m_Log->Log("--- Stopped Log ---"); + delete m_Log; + if (this == s_MCLogger) + s_MCLogger = NULL; +} + + + + + +void cMCLogger::LogSimple(const char* a_Text, int a_LogType /* = 0 */ ) +{ + switch( a_LogType ) + { + case 0: + LOG("%s", a_Text); + break; + case 1: + LOGINFO("%s", a_Text); + break; + case 2: + LOGWARN("%s", a_Text); + break; + case 3: + LOGERROR("%s", a_Text); + break; + default: + LOG("(#%d#: %s", a_LogType, a_Text); + break; + } +} + + + + + +void cMCLogger::Log(const char* a_Format, va_list a_ArgList) +{ + cCSLock Lock(m_CriticalSection); + SetColor( 0x7 ); // 0x7 is default grey color + m_Log->Log( a_Format, a_ArgList ); + SetColor(0x07); // revert color back +} + + + + + +void cMCLogger::Info(const char* a_Format, va_list a_ArgList) +{ + cCSLock Lock(m_CriticalSection); +// for( int i = 0; i < 16; i++) +// { +// for( int j = 0; j < 16; j++ ) +// { +// SetConsoleTextAttribute( hConsole, i | (j<<4) ); +// printf("0x%x", (i|j<<4)); +// } +// printf("\n"); +// } + + SetColor( 0xe ); // 0xe is yellow + m_Log->Log( a_Format, a_ArgList ); + SetColor(0x07); // revert color back +} + + + + + +void cMCLogger::Warn(const char* a_Format, va_list a_ArgList) +{ + cCSLock Lock(m_CriticalSection); + SetColor( 0xc ); // 0xc is red + m_Log->Log( a_Format, a_ArgList ); + SetColor(0x07); // revert color back +} + + + + + +void cMCLogger::Error(const char* a_Format, va_list a_ArgList) +{ + cCSLock Lock(m_CriticalSection); + SetColor( 0xc0 ); // 0xc0 is red bg and black text + m_Log->Log( a_Format, a_ArgList ); + SetColor(0x07); // revert color back +} + + + + + +void cMCLogger::SetColor( unsigned char a_Color ) +{ +#ifdef _WIN32 + HANDLE hConsole = GetStdHandle( STD_OUTPUT_HANDLE ); + SetConsoleTextAttribute( hConsole, a_Color ); +#else + (void)a_Color; +#endif +} + + + + + +////////////////////////////////////////////////////////////////////////// +// Global functions +void LOG(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cMCLogger::GetInstance()->Log( a_Format, argList ); + va_end(argList); +} + +void LOGINFO(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cMCLogger::GetInstance()->Info( a_Format, argList ); + va_end(argList); +} + +void LOGWARN(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cMCLogger::GetInstance()->Warn( a_Format, argList ); + va_end(argList); +} + +void LOGERROR(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cMCLogger::GetInstance()->Error( a_Format, argList ); + va_end(argList); +} + + + + diff --git a/source/cMCLogger.h b/source/cMCLogger.h index b483fb0b8..04ba732bf 100644 --- a/source/cMCLogger.h +++ b/source/cMCLogger.h @@ -1,60 +1,60 @@ - -#pragma once - - - - -class cLog; - - - - - -class cMCLogger //tolua_export -{ //tolua_export -public: //tolua_export - cMCLogger(); - cMCLogger( char* a_File ); //tolua_export - ~cMCLogger(); //tolua_export - - void Log(const char* a_Format, va_list a_ArgList); - void Info(const char* a_Format, va_list a_ArgList); - void Warn(const char* a_Format, va_list a_ArgList); - void Error(const char* a_Format, va_list a_ArgList); - - void LogSimple(const char* a_Text, int a_LogType = 0 ); //tolua_export - - static cMCLogger* GetInstance(); -private: - void SetColor( unsigned char a_Color ); - - cCriticalSection m_CriticalSection; - cLog* m_Log; - static cMCLogger* s_MCLogger; -}; //tolua_export - -extern void LOG(const char* a_Format, ...); -extern void LOGINFO(const char* a_Format, ...); -extern void LOGWARN(const char* a_Format, ...); -extern void LOGERROR(const char* a_Format, ...); - - - - - -// In debug builds, translate LOGD to LOG, otherwise leave it out altogether: -#ifdef _DEBUG - #define LOGD LOG -#else - #define LOGD(...) -#endif // _DEBUG - - - - - -#define LOGWARNING LOGWARN - - - - + +#pragma once + + + + +class cLog; + + + + + +class cMCLogger //tolua_export +{ //tolua_export +public: //tolua_export + cMCLogger(); + cMCLogger( char* a_File ); //tolua_export + ~cMCLogger(); //tolua_export + + void Log(const char* a_Format, va_list a_ArgList); + void Info(const char* a_Format, va_list a_ArgList); + void Warn(const char* a_Format, va_list a_ArgList); + void Error(const char* a_Format, va_list a_ArgList); + + void LogSimple(const char* a_Text, int a_LogType = 0 ); //tolua_export + + static cMCLogger* GetInstance(); +private: + void SetColor( unsigned char a_Color ); + + cCriticalSection m_CriticalSection; + cLog* m_Log; + static cMCLogger* s_MCLogger; +}; //tolua_export + +extern void LOG(const char* a_Format, ...); +extern void LOGINFO(const char* a_Format, ...); +extern void LOGWARN(const char* a_Format, ...); +extern void LOGERROR(const char* a_Format, ...); + + + + + +// In debug builds, translate LOGD to LOG, otherwise leave it out altogether: +#ifdef _DEBUG + #define LOGD LOG +#else + #define LOGD(...) +#endif // _DEBUG + + + + + +#define LOGWARNING LOGWARN + + + + diff --git a/source/cMakeDir.cpp b/source/cMakeDir.cpp index a28b3a088..a9e35cece 100644 --- a/source/cMakeDir.cpp +++ b/source/cMakeDir.cpp @@ -1,25 +1,25 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cMakeDir.h" - - - - - -void cMakeDir::MakeDir(const AString & a_Directory) -{ -#ifdef _WIN32 - SECURITY_ATTRIBUTES Attrib; - Attrib.nLength = sizeof(SECURITY_ATTRIBUTES); - Attrib.lpSecurityDescriptor = NULL; - Attrib.bInheritHandle = false; - ::CreateDirectory(a_Directory.c_str(), &Attrib); -#else - mkdir(a_Directory.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); -#endif -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cMakeDir.h" + + + + + +void cMakeDir::MakeDir(const AString & a_Directory) +{ +#ifdef _WIN32 + SECURITY_ATTRIBUTES Attrib; + Attrib.nLength = sizeof(SECURITY_ATTRIBUTES); + Attrib.lpSecurityDescriptor = NULL; + Attrib.bInheritHandle = false; + ::CreateDirectory(a_Directory.c_str(), &Attrib); +#else + mkdir(a_Directory.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); +#endif +} + + + + diff --git a/source/cMakeDir.h b/source/cMakeDir.h index f109e17dd..e66cf1071 100644 --- a/source/cMakeDir.h +++ b/source/cMakeDir.h @@ -1,16 +1,16 @@ - -#pragma once - - - - - -class cMakeDir -{ -public: - static void MakeDir(const AString & a_Directory); -}; - - - - + +#pragma once + + + + + +class cMakeDir +{ +public: + static void MakeDir(const AString & a_Directory); +}; + + + + diff --git a/source/cMonster.cpp b/source/cMonster.cpp index 7834b855a..3c73cae8a 100644 --- a/source/cMonster.cpp +++ b/source/cMonster.cpp @@ -1,560 +1,560 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cMonster.h" -#include "cRoot.h" -#include "cServer.h" -#include "cClientHandle.h" -#include "cWorld.h" -#include "cPlayer.h" -#include "Defines.h" -#include "cMonsterConfig.h" -#include "MersenneTwister.h" - -#include "packets/cPacket_SpawnMob.h" -#include "packets/cPacket_EntityLook.h" -#include "packets/cPacket_TeleportEntity.h" -#include "packets/cPacket_RelativeEntityMoveLook.h" -#include "packets/cPacket_RelativeEntityMove.h" -#include "packets/cPacket_Metadata.h" - -#include "Vector3f.h" -#include "Vector3i.h" -#include "Vector3d.h" - -#include "cTracer.h" -#include "../iniFile/iniFile.h" - -#ifndef _WIN32 - #include // rand - #include -#endif - - - - - -cMonster::cMonster() - : m_Target(0) - , m_bMovingToDestination(false) - , m_DestinationTime( 0 ) - , m_Gravity( -9.81f) - , m_bOnGround( false ) - , m_DestroyTimer( 0 ) - , m_Jump(0) - , m_MobType( 0 ) - , m_EMState(IDLE) - , m_SightDistance(25) - , m_SeePlayerInterval (0) - , m_EMPersonality(AGGRESSIVE) - , m_AttackDamage(1.0f) - , m_AttackRange(5.0f) - , m_AttackInterval(0) - , m_AttackRate(3) - , idle_interval(0) -{ - LOG("cMonster::cMonster()"); - LOG("In state: %s", GetState()); - - m_bBurnable = true; - m_MetaData = NORMAL; -} - -cMonster::~cMonster() -{ - LOG("cMonster::~cMonster()"); -} - -bool cMonster::IsA( const char* a_EntityType ) -{ - if( strcmp( a_EntityType, "cMonster" ) == 0 ) return true; - return cPawn::IsA( a_EntityType ); -} - - - - - -cPacket * cMonster::GetSpawnPacket(void) const -{ - cPacket_SpawnMob * Spawn = new cPacket_SpawnMob; - Spawn->m_UniqueID = GetUniqueID(); - Spawn->m_Type = m_MobType; - *Spawn->m_Pos = ((Vector3i)(m_Pos)) * 32; - Spawn->m_Yaw = 0; - Spawn->m_Pitch = 0; - Spawn->m_MetaDataSize = 1; - Spawn->m_MetaData = new char[Spawn->m_MetaDataSize]; - Spawn->m_MetaData[0] = 0x7f; // not on fire/crouching/riding - return Spawn; -} - - - - - -void cMonster::MoveToPosition( const Vector3f & a_Position ) -{ - m_bMovingToDestination = true; - - m_Destination = a_Position; -} - -bool cMonster::ReachedDestination() -{ - Vector3f Distance = (m_Destination) - Vector3f( m_Pos ); - if( Distance.SqrLength() < 2.f ) - return true; - - return false; -} - - - - - -void cMonster::Tick(float a_Dt) -{ - cPawn::Tick(a_Dt); - - if( m_Health <= 0 ) - { - m_DestroyTimer += a_Dt/1000; - if( m_DestroyTimer > 1 ) - { - Destroy(); - } - return; - } - - a_Dt /= 1000; - - if( m_bMovingToDestination ) - { - Vector3f Pos( m_Pos ); - Vector3f Distance = m_Destination - Pos; - if( !ReachedDestination() ) - { - Distance.y = 0; - Distance.Normalize(); - Distance *= 3; - m_Speed.x = Distance.x; - m_Speed.z = Distance.z; - - if (m_EMState == ESCAPING) - { //Runs Faster when escaping :D otherwise they just walk away - m_Speed.x *= 2.f; - m_Speed.z *= 2.f; - } - } - else - { - m_bMovingToDestination = false; - } - - if( m_Speed.SqrLength() > 0.f ) - { - if( m_bOnGround ) - { - Vector3f NormSpeed = m_Speed.NormalizeCopy(); - Vector3f NextBlock = Vector3f( m_Pos ) + NormSpeed; - double NextHeight = (double)GetWorld()->GetHeight( (int)NextBlock.x, (int)NextBlock.z ); - if( NextHeight > m_Pos.y - 1.2 && NextHeight - m_Pos.y < 2.5 ) - { - m_bOnGround = false; - m_Speed.y = 7.f; // Jump!! - } - } - } - } - - HandlePhysics( a_Dt ); - - ReplicateMovement(); - - Vector3f Distance = m_Destination - Vector3f( m_Pos ); - if( Distance.SqrLength() > 0.1f ) - { - float Rotation, Pitch; - Distance.Normalize(); - VectorToEuler( Distance.x, Distance.y, Distance.z, Rotation, Pitch ); - SetRotation( Rotation ); - SetPitch( Pitch ); - } - - if(m_EMState == IDLE) { //If enemy passive we ignore checks for player visibility - InStateIdle(a_Dt); - } - - if(m_EMState == CHASING) { //If we do not see a player anymore skip chasing action - InStateChasing(a_Dt); - } - - if(m_EMState == ESCAPING) { - InStateEscaping(a_Dt); - } - -} - - - - - -void cMonster::ReplicateMovement() -{ - if(m_bDirtyOrientation && !m_bDirtyPosition) - { - cPacket_EntityLook EntityLook(*this); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, EntityLook ); - m_bDirtyOrientation = false; - } - - if( m_bDirtyPosition ) - { - float DiffX = (float)(GetPosX() - m_LastPosX ); - float DiffY = (float)(GetPosY() - m_LastPosY ); - float DiffZ = (float)(GetPosZ() - m_LastPosZ ); - float SqrDist = DiffX*DiffX + DiffY*DiffY + DiffZ*DiffZ; - if ( - (SqrDist > 4 * 4) // 4 blocks is max Relative Move - || (cWorld::GetTime() - m_TimeLastTeleportPacket > 2 ) // Send an absolute position every 2 seconds - ) - { - //LOG("Teleported %f", sqrtf(SqrDist) ); - cPacket_TeleportEntity TeleportEntity( this ); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, TeleportEntity); - m_TimeLastTeleportPacket = cWorld::GetTime(); - } - else - { // Relative move sucks balls! It's always wrong wtf! - if( m_bDirtyOrientation ) - { - cPacket_RelativeEntityMoveLook RelativeEntityMoveLook; - RelativeEntityMoveLook.m_UniqueID = GetUniqueID(); - RelativeEntityMoveLook.m_MoveX = (char)(DiffX*32); - RelativeEntityMoveLook.m_MoveY = (char)(DiffY*32); - RelativeEntityMoveLook.m_MoveZ = (char)(DiffZ*32); - RelativeEntityMoveLook.m_Yaw = (char)((GetRotation()/360.f)*256); - RelativeEntityMoveLook.m_Pitch = (char)((GetPitch()/360.f)*256); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMoveLook ); - } - else - { - cPacket_RelativeEntityMove RelativeEntityMove; - RelativeEntityMove.m_UniqueID = GetUniqueID(); - RelativeEntityMove.m_MoveX = (char)(DiffX*32); - RelativeEntityMove.m_MoveY = (char)(DiffY*32); - RelativeEntityMove.m_MoveZ = (char)(DiffZ*32); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMove ); - } - } - m_LastPosX = GetPosX(); - m_LastPosY = GetPosY(); - m_LastPosZ = GetPosZ(); - m_bDirtyPosition = false; - } - - MoveToCorrectChunk(); -} - - - - - -void cMonster::HandlePhysics(float a_Dt) -{ - if( m_bOnGround ) // check if it's still on the ground - { - cWorld* World = GetWorld(); - if( World->GetBlock( (int)m_Pos.x, (int)m_Pos.y -1, (int)m_Pos.z ) == E_BLOCK_AIR ) - { - m_bOnGround = false; - } - if( World->GetBlock( (int)m_Pos.x, (int)m_Pos.y, (int)m_Pos.z ) != E_BLOCK_AIR ) // If in ground itself, push it out - { - m_bOnGround = true; - m_Pos.y += 0.2; - m_bDirtyPosition = true; - } - m_Speed.x *= 0.7f/(1+a_Dt); - if( fabs(m_Speed.x) < 0.05 ) m_Speed.x = 0; - m_Speed.z *= 0.7f/(1+a_Dt); - if( fabs(m_Speed.z) < 0.05 ) m_Speed.z = 0; - } - - if( !m_bOnGround ) - { - float Gravity = -9.81f*a_Dt; - m_Speed.y += Gravity; - } - - if( m_Speed.SqrLength() > 0.f ) - { - cTracer Tracer( GetWorld() ); - int Ret = Tracer.Trace( m_Pos, m_Speed, 2 ); - if( Ret ) // Oh noez! we hit something - { - // Set to hit position - if( (Tracer.RealHit - Vector3f(m_Pos)).SqrLength() <= ( m_Speed * a_Dt ).SqrLength() ) - { - if( Ret == 1 ) - { - - if( Tracer.HitNormal.x != 0.f ) m_Speed.x = 0.f; - if( Tracer.HitNormal.y != 0.f ) m_Speed.y = 0.f; - if( Tracer.HitNormal.z != 0.f ) m_Speed.z = 0.f; - - if( Tracer.HitNormal.y > 0 ) // means on ground - { - m_bOnGround = true; - } - } - m_Pos = Tracer.RealHit; - m_Pos += Tracer.HitNormal * 0.2f; - - } - else - m_Pos += m_Speed*a_Dt; - } - else - { // We didn't hit anything, so move =] - m_Pos += m_Speed*a_Dt; - } - - m_bDirtyPosition = true; - } -} - -void cMonster::TakeDamage(int a_Damage, cEntity* a_Instigator) -{ - cPawn::TakeDamage( a_Damage, a_Instigator ); - m_Target = a_Instigator; - AddReference( m_Target ); -} - -void cMonster::KilledBy( cEntity* a_Killer ) -{ - cPawn::KilledBy( a_Killer ); - m_DestroyTimer = 0; -} - -//----State Logic - -const char *cMonster::GetState() { - switch(m_EMState) { - case IDLE: - return "Idle"; - break; - case ATTACKING: - return "Attacking"; - break; - case CHASING: - return "Chasing"; - break; - default: - return "Unknown"; - break; - } -} - -//for debugging -void cMonster::SetState(const char* a_str) -{ - std::string str = a_str; - if(str.compare("Idle") == 0 ) { - m_EMState = IDLE; - } else if(str.compare("Attacking") == 0 ) { - m_EMState = ATTACKING; - } else if(str.compare("Chasing") == 0 ) { - m_EMState = CHASING; - } else { - printf("Invalid State"); - } -} - -//Checks to see if EventSeePlayer should be fired -//monster sez: Do I see the player -void cMonster::CheckEventSeePlayer() -{ - cPlayer *Closest = FindClosestPlayer(); - - if(Closest) - { - EventSeePlayer(Closest); - } -} - -void cMonster::CheckEventLostPlayer() -{ - Vector3f pos; - cTracer LineOfSight(GetWorld() ); - - if(m_Target != 0) { - pos = m_Target->GetPosition(); - if((pos - m_Pos).Length() > m_SightDistance || LineOfSight.Trace(m_Pos,(pos - m_Pos), (int)(pos - m_Pos).Length())) - { - EventLosePlayer(); - } - } else { - EventLosePlayer(); - } -} - -//What to do if player is seen -//default to change state to chasing -void cMonster::EventSeePlayer(cEntity *a_SeenPlayer) -{ - m_Target = a_SeenPlayer; - AddReference( m_Target ); -} - -void cMonster::EventLosePlayer(){ - Dereference(m_Target); - m_Target = 0; - m_EMState = IDLE; -} - -//What to do if in Idle State -void cMonster::InStateIdle(float a_Dt) { - idle_interval += a_Dt; - if(idle_interval > 1) { //at this interval the results are predictable - MTRand r1; - int rem = r1.randInt()%6 + 1; - //LOG("Moving: int: %3.3f rem: %i",idle_interval,rem); - idle_interval -= 1; //So nothing gets dropped when the server hangs for a few seconds - Vector3f Dist; - Dist.x = (float)((r1.randInt()%11)-5); - Dist.z = (float)((r1.randInt()%11)-5); - if( Dist.SqrLength() > 2 && rem >= 3) - { - m_Destination.x = (float)(m_Pos.x + Dist.x); - m_Destination.z = (float)(m_Pos.z + Dist.z); - m_Destination.y = (float)GetWorld()->GetHeight( (int)m_Destination.x, (int)m_Destination.z ) + 1.2f; - MoveToPosition( m_Destination ); - } - } -} - -//What to do if in Chasing State -//This state should always be defined in each child class -void cMonster::InStateChasing(float a_Dt) { - (void)a_Dt; -} - -//What to do if in Escaping State -void cMonster::InStateEscaping(float a_Dt) { - (void)a_Dt; - if(m_Target) { - Vector3d newloc = m_Pos; - newloc.x = (m_Target->GetPosition().x < newloc.x)? (newloc.x + m_SightDistance): (newloc.x - m_SightDistance); - newloc.z = (m_Target->GetPosition().z < newloc.z)? (newloc.z + m_SightDistance): (newloc.z - m_SightDistance); - MoveToPosition(newloc); - } else { - m_EMState = IDLE; //this shouldnt be required but just to be safe - } -} - - -//Do attack here -//a_Dt is passed so we can set attack rate -void cMonster::Attack(float a_Dt) { - m_AttackInterval += a_Dt * m_AttackRate; - if(m_Target != 0 && m_AttackInterval > 3.0) { //Setting this higher gives us more wiggle room for attackrate - m_AttackInterval = 0.0; - ((cPawn *)m_Target)->TakeDamage((int)m_AttackDamage,this); - } -} - - - - - -#if 0 -// TODO: Implement this debug function inside cWorld instead - the world owns the entities -void cMonster::ListMonsters() -{ - - cWorld::EntityList Entities = cRoot::Get()->GetWorld()->GetEntities(); - cRoot::Get()->GetWorld()->LockEntities(); - for( cWorld::EntityList::iterator itr = Entities.begin(); itr != Entities.end(); ++itr) { - if((*itr)->GetEntityType() == cEntity::E_ENTITY){ - LOG("In state: %s type: %i attack rate: %i",((cMonster *)(*itr))->GetState(), ((cMonster *)(*itr))->GetMobType(),((cMonster *)(*itr))->GetAttackRate()); - - } - } - cRoot::Get()->GetWorld()->UnlockEntities(); -} -#endif - - - - - -//Checks for Players close by and if they are visible return the closest -cPlayer * cMonster::FindClosestPlayer(void) -{ - return m_World->FindClosestPlayer(m_Pos, m_SightDistance); -} - - - - - -void cMonster::GetMonsterConfig(const char* pm_name) -{ - cRoot::Get()->GetMonsterConfig()->AssignAttributes(this, pm_name); -} - - - - - -void cMonster::SetAttackRate(int ar) -{ - m_AttackRate = (float)ar; -} - - - - - -void cMonster::SetAttackRange(float ar) -{ - m_AttackRange = ar; -} - - - - - -void cMonster::SetAttackDamage(float ad) -{ - m_AttackDamage = ad; -} - - - - - -void cMonster::SetSightDistance(float sd) -{ - m_SightDistance = sd; -} - - - - - -void cMonster::AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, ENUM_ITEM_ID a_Item, short a_ItemHealth) -{ - MTRand r1; - int Count = r1.randInt() % (a_Max + 1 - a_Min) + a_Min; - if (Count > 0) - { - a_Drops.push_back(cItem(a_Item, Count, a_ItemHealth)); - } -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cMonster.h" +#include "cRoot.h" +#include "cServer.h" +#include "cClientHandle.h" +#include "cWorld.h" +#include "cPlayer.h" +#include "Defines.h" +#include "cMonsterConfig.h" +#include "MersenneTwister.h" + +#include "packets/cPacket_SpawnMob.h" +#include "packets/cPacket_EntityLook.h" +#include "packets/cPacket_TeleportEntity.h" +#include "packets/cPacket_RelativeEntityMoveLook.h" +#include "packets/cPacket_RelativeEntityMove.h" +#include "packets/cPacket_Metadata.h" + +#include "Vector3f.h" +#include "Vector3i.h" +#include "Vector3d.h" + +#include "cTracer.h" +#include "../iniFile/iniFile.h" + +#ifndef _WIN32 + #include // rand + #include +#endif + + + + + +cMonster::cMonster() + : m_Target(0) + , m_bMovingToDestination(false) + , m_DestinationTime( 0 ) + , m_Gravity( -9.81f) + , m_bOnGround( false ) + , m_DestroyTimer( 0 ) + , m_Jump(0) + , m_MobType( 0 ) + , m_EMState(IDLE) + , m_SightDistance(25) + , m_SeePlayerInterval (0) + , m_EMPersonality(AGGRESSIVE) + , m_AttackDamage(1.0f) + , m_AttackRange(5.0f) + , m_AttackInterval(0) + , m_AttackRate(3) + , idle_interval(0) +{ + LOG("cMonster::cMonster()"); + LOG("In state: %s", GetState()); + + m_bBurnable = true; + m_MetaData = NORMAL; +} + +cMonster::~cMonster() +{ + LOG("cMonster::~cMonster()"); +} + +bool cMonster::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cMonster" ) == 0 ) return true; + return cPawn::IsA( a_EntityType ); +} + + + + + +cPacket * cMonster::GetSpawnPacket(void) const +{ + cPacket_SpawnMob * Spawn = new cPacket_SpawnMob; + Spawn->m_UniqueID = GetUniqueID(); + Spawn->m_Type = m_MobType; + *Spawn->m_Pos = ((Vector3i)(m_Pos)) * 32; + Spawn->m_Yaw = 0; + Spawn->m_Pitch = 0; + Spawn->m_MetaDataSize = 1; + Spawn->m_MetaData = new char[Spawn->m_MetaDataSize]; + Spawn->m_MetaData[0] = 0x7f; // not on fire/crouching/riding + return Spawn; +} + + + + + +void cMonster::MoveToPosition( const Vector3f & a_Position ) +{ + m_bMovingToDestination = true; + + m_Destination = a_Position; +} + +bool cMonster::ReachedDestination() +{ + Vector3f Distance = (m_Destination) - Vector3f( m_Pos ); + if( Distance.SqrLength() < 2.f ) + return true; + + return false; +} + + + + + +void cMonster::Tick(float a_Dt) +{ + cPawn::Tick(a_Dt); + + if( m_Health <= 0 ) + { + m_DestroyTimer += a_Dt/1000; + if( m_DestroyTimer > 1 ) + { + Destroy(); + } + return; + } + + a_Dt /= 1000; + + if( m_bMovingToDestination ) + { + Vector3f Pos( m_Pos ); + Vector3f Distance = m_Destination - Pos; + if( !ReachedDestination() ) + { + Distance.y = 0; + Distance.Normalize(); + Distance *= 3; + m_Speed.x = Distance.x; + m_Speed.z = Distance.z; + + if (m_EMState == ESCAPING) + { //Runs Faster when escaping :D otherwise they just walk away + m_Speed.x *= 2.f; + m_Speed.z *= 2.f; + } + } + else + { + m_bMovingToDestination = false; + } + + if( m_Speed.SqrLength() > 0.f ) + { + if( m_bOnGround ) + { + Vector3f NormSpeed = m_Speed.NormalizeCopy(); + Vector3f NextBlock = Vector3f( m_Pos ) + NormSpeed; + double NextHeight = (double)GetWorld()->GetHeight( (int)NextBlock.x, (int)NextBlock.z ); + if( NextHeight > m_Pos.y - 1.2 && NextHeight - m_Pos.y < 2.5 ) + { + m_bOnGround = false; + m_Speed.y = 7.f; // Jump!! + } + } + } + } + + HandlePhysics( a_Dt ); + + ReplicateMovement(); + + Vector3f Distance = m_Destination - Vector3f( m_Pos ); + if( Distance.SqrLength() > 0.1f ) + { + float Rotation, Pitch; + Distance.Normalize(); + VectorToEuler( Distance.x, Distance.y, Distance.z, Rotation, Pitch ); + SetRotation( Rotation ); + SetPitch( Pitch ); + } + + if(m_EMState == IDLE) { //If enemy passive we ignore checks for player visibility + InStateIdle(a_Dt); + } + + if(m_EMState == CHASING) { //If we do not see a player anymore skip chasing action + InStateChasing(a_Dt); + } + + if(m_EMState == ESCAPING) { + InStateEscaping(a_Dt); + } + +} + + + + + +void cMonster::ReplicateMovement() +{ + if(m_bDirtyOrientation && !m_bDirtyPosition) + { + cPacket_EntityLook EntityLook(*this); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, EntityLook ); + m_bDirtyOrientation = false; + } + + if( m_bDirtyPosition ) + { + float DiffX = (float)(GetPosX() - m_LastPosX ); + float DiffY = (float)(GetPosY() - m_LastPosY ); + float DiffZ = (float)(GetPosZ() - m_LastPosZ ); + float SqrDist = DiffX*DiffX + DiffY*DiffY + DiffZ*DiffZ; + if ( + (SqrDist > 4 * 4) // 4 blocks is max Relative Move + || (cWorld::GetTime() - m_TimeLastTeleportPacket > 2 ) // Send an absolute position every 2 seconds + ) + { + //LOG("Teleported %f", sqrtf(SqrDist) ); + cPacket_TeleportEntity TeleportEntity( this ); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, TeleportEntity); + m_TimeLastTeleportPacket = cWorld::GetTime(); + } + else + { // Relative move sucks balls! It's always wrong wtf! + if( m_bDirtyOrientation ) + { + cPacket_RelativeEntityMoveLook RelativeEntityMoveLook; + RelativeEntityMoveLook.m_UniqueID = GetUniqueID(); + RelativeEntityMoveLook.m_MoveX = (char)(DiffX*32); + RelativeEntityMoveLook.m_MoveY = (char)(DiffY*32); + RelativeEntityMoveLook.m_MoveZ = (char)(DiffZ*32); + RelativeEntityMoveLook.m_Yaw = (char)((GetRotation()/360.f)*256); + RelativeEntityMoveLook.m_Pitch = (char)((GetPitch()/360.f)*256); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMoveLook ); + } + else + { + cPacket_RelativeEntityMove RelativeEntityMove; + RelativeEntityMove.m_UniqueID = GetUniqueID(); + RelativeEntityMove.m_MoveX = (char)(DiffX*32); + RelativeEntityMove.m_MoveY = (char)(DiffY*32); + RelativeEntityMove.m_MoveZ = (char)(DiffZ*32); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMove ); + } + } + m_LastPosX = GetPosX(); + m_LastPosY = GetPosY(); + m_LastPosZ = GetPosZ(); + m_bDirtyPosition = false; + } + + MoveToCorrectChunk(); +} + + + + + +void cMonster::HandlePhysics(float a_Dt) +{ + if( m_bOnGround ) // check if it's still on the ground + { + cWorld* World = GetWorld(); + if( World->GetBlock( (int)m_Pos.x, (int)m_Pos.y -1, (int)m_Pos.z ) == E_BLOCK_AIR ) + { + m_bOnGround = false; + } + if( World->GetBlock( (int)m_Pos.x, (int)m_Pos.y, (int)m_Pos.z ) != E_BLOCK_AIR ) // If in ground itself, push it out + { + m_bOnGround = true; + m_Pos.y += 0.2; + m_bDirtyPosition = true; + } + m_Speed.x *= 0.7f/(1+a_Dt); + if( fabs(m_Speed.x) < 0.05 ) m_Speed.x = 0; + m_Speed.z *= 0.7f/(1+a_Dt); + if( fabs(m_Speed.z) < 0.05 ) m_Speed.z = 0; + } + + if( !m_bOnGround ) + { + float Gravity = -9.81f*a_Dt; + m_Speed.y += Gravity; + } + + if( m_Speed.SqrLength() > 0.f ) + { + cTracer Tracer( GetWorld() ); + int Ret = Tracer.Trace( m_Pos, m_Speed, 2 ); + if( Ret ) // Oh noez! we hit something + { + // Set to hit position + if( (Tracer.RealHit - Vector3f(m_Pos)).SqrLength() <= ( m_Speed * a_Dt ).SqrLength() ) + { + if( Ret == 1 ) + { + + if( Tracer.HitNormal.x != 0.f ) m_Speed.x = 0.f; + if( Tracer.HitNormal.y != 0.f ) m_Speed.y = 0.f; + if( Tracer.HitNormal.z != 0.f ) m_Speed.z = 0.f; + + if( Tracer.HitNormal.y > 0 ) // means on ground + { + m_bOnGround = true; + } + } + m_Pos = Tracer.RealHit; + m_Pos += Tracer.HitNormal * 0.2f; + + } + else + m_Pos += m_Speed*a_Dt; + } + else + { // We didn't hit anything, so move =] + m_Pos += m_Speed*a_Dt; + } + + m_bDirtyPosition = true; + } +} + +void cMonster::TakeDamage(int a_Damage, cEntity* a_Instigator) +{ + cPawn::TakeDamage( a_Damage, a_Instigator ); + m_Target = a_Instigator; + AddReference( m_Target ); +} + +void cMonster::KilledBy( cEntity* a_Killer ) +{ + cPawn::KilledBy( a_Killer ); + m_DestroyTimer = 0; +} + +//----State Logic + +const char *cMonster::GetState() { + switch(m_EMState) { + case IDLE: + return "Idle"; + break; + case ATTACKING: + return "Attacking"; + break; + case CHASING: + return "Chasing"; + break; + default: + return "Unknown"; + break; + } +} + +//for debugging +void cMonster::SetState(const char* a_str) +{ + std::string str = a_str; + if(str.compare("Idle") == 0 ) { + m_EMState = IDLE; + } else if(str.compare("Attacking") == 0 ) { + m_EMState = ATTACKING; + } else if(str.compare("Chasing") == 0 ) { + m_EMState = CHASING; + } else { + printf("Invalid State"); + } +} + +//Checks to see if EventSeePlayer should be fired +//monster sez: Do I see the player +void cMonster::CheckEventSeePlayer() +{ + cPlayer *Closest = FindClosestPlayer(); + + if(Closest) + { + EventSeePlayer(Closest); + } +} + +void cMonster::CheckEventLostPlayer() +{ + Vector3f pos; + cTracer LineOfSight(GetWorld() ); + + if(m_Target != 0) { + pos = m_Target->GetPosition(); + if((pos - m_Pos).Length() > m_SightDistance || LineOfSight.Trace(m_Pos,(pos - m_Pos), (int)(pos - m_Pos).Length())) + { + EventLosePlayer(); + } + } else { + EventLosePlayer(); + } +} + +//What to do if player is seen +//default to change state to chasing +void cMonster::EventSeePlayer(cEntity *a_SeenPlayer) +{ + m_Target = a_SeenPlayer; + AddReference( m_Target ); +} + +void cMonster::EventLosePlayer(){ + Dereference(m_Target); + m_Target = 0; + m_EMState = IDLE; +} + +//What to do if in Idle State +void cMonster::InStateIdle(float a_Dt) { + idle_interval += a_Dt; + if(idle_interval > 1) { //at this interval the results are predictable + MTRand r1; + int rem = r1.randInt()%6 + 1; + //LOG("Moving: int: %3.3f rem: %i",idle_interval,rem); + idle_interval -= 1; //So nothing gets dropped when the server hangs for a few seconds + Vector3f Dist; + Dist.x = (float)((r1.randInt()%11)-5); + Dist.z = (float)((r1.randInt()%11)-5); + if( Dist.SqrLength() > 2 && rem >= 3) + { + m_Destination.x = (float)(m_Pos.x + Dist.x); + m_Destination.z = (float)(m_Pos.z + Dist.z); + m_Destination.y = (float)GetWorld()->GetHeight( (int)m_Destination.x, (int)m_Destination.z ) + 1.2f; + MoveToPosition( m_Destination ); + } + } +} + +//What to do if in Chasing State +//This state should always be defined in each child class +void cMonster::InStateChasing(float a_Dt) { + (void)a_Dt; +} + +//What to do if in Escaping State +void cMonster::InStateEscaping(float a_Dt) { + (void)a_Dt; + if(m_Target) { + Vector3d newloc = m_Pos; + newloc.x = (m_Target->GetPosition().x < newloc.x)? (newloc.x + m_SightDistance): (newloc.x - m_SightDistance); + newloc.z = (m_Target->GetPosition().z < newloc.z)? (newloc.z + m_SightDistance): (newloc.z - m_SightDistance); + MoveToPosition(newloc); + } else { + m_EMState = IDLE; //this shouldnt be required but just to be safe + } +} + + +//Do attack here +//a_Dt is passed so we can set attack rate +void cMonster::Attack(float a_Dt) { + m_AttackInterval += a_Dt * m_AttackRate; + if(m_Target != 0 && m_AttackInterval > 3.0) { //Setting this higher gives us more wiggle room for attackrate + m_AttackInterval = 0.0; + ((cPawn *)m_Target)->TakeDamage((int)m_AttackDamage,this); + } +} + + + + + +#if 0 +// TODO: Implement this debug function inside cWorld instead - the world owns the entities +void cMonster::ListMonsters() +{ + + cWorld::EntityList Entities = cRoot::Get()->GetWorld()->GetEntities(); + cRoot::Get()->GetWorld()->LockEntities(); + for( cWorld::EntityList::iterator itr = Entities.begin(); itr != Entities.end(); ++itr) { + if((*itr)->GetEntityType() == cEntity::E_ENTITY){ + LOG("In state: %s type: %i attack rate: %i",((cMonster *)(*itr))->GetState(), ((cMonster *)(*itr))->GetMobType(),((cMonster *)(*itr))->GetAttackRate()); + + } + } + cRoot::Get()->GetWorld()->UnlockEntities(); +} +#endif + + + + + +//Checks for Players close by and if they are visible return the closest +cPlayer * cMonster::FindClosestPlayer(void) +{ + return m_World->FindClosestPlayer(m_Pos, m_SightDistance); +} + + + + + +void cMonster::GetMonsterConfig(const char* pm_name) +{ + cRoot::Get()->GetMonsterConfig()->AssignAttributes(this, pm_name); +} + + + + + +void cMonster::SetAttackRate(int ar) +{ + m_AttackRate = (float)ar; +} + + + + + +void cMonster::SetAttackRange(float ar) +{ + m_AttackRange = ar; +} + + + + + +void cMonster::SetAttackDamage(float ad) +{ + m_AttackDamage = ad; +} + + + + + +void cMonster::SetSightDistance(float sd) +{ + m_SightDistance = sd; +} + + + + + +void cMonster::AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, ENUM_ITEM_ID a_Item, short a_ItemHealth) +{ + MTRand r1; + int Count = r1.randInt() % (a_Max + 1 - a_Min) + a_Min; + if (Count > 0) + { + a_Drops.push_back(cItem(a_Item, Count, a_ItemHealth)); + } +} + + + + diff --git a/source/cMonster.h b/source/cMonster.h index b1e237d80..ab247fcfa 100644 --- a/source/cMonster.h +++ b/source/cMonster.h @@ -1,101 +1,101 @@ - -#pragma once - -#include "cPawn.h" -#include "Defines.h" -#include "cWorld.h" -#include "BlockID.h" -#include "cItem.h" -#include "BlockID.h" - - - - - -class Vector3f; -class cClientHandle; - - - - -class cMonster : public cPawn //tolua_export -{ //tolua_export -public: - - cMonster(); - virtual ~cMonster(); - - virtual bool IsA( const char* a_EntityType ); - - virtual cPacket * GetSpawnPacket(void) const override; - - virtual void Tick(float a_Dt) override; - - virtual void HandlePhysics(float a_Dt); - virtual void ReplicateMovement(); - - virtual void TakeDamage( int a_Damage, cEntity* a_Instigator ); - virtual void KilledBy( cEntity* a_Killer ); - - virtual void MoveToPosition( const Vector3f & a_Position ); - virtual bool ReachedDestination(); - - const char *GetState(); - void SetState(const char* str); - static void ListMonsters(); - - virtual void CheckEventSeePlayer(); - virtual void EventSeePlayer(cEntity *); - float m_SightDistance; - virtual cPlayer *FindClosestPlayer(); //non static is easier. also virtual so other mobs can implement their own searching algo - virtual void GetMonsterConfig(const char* pm_name); - virtual void EventLosePlayer(); - virtual void CheckEventLostPlayer(); - - virtual void InStateIdle(float a_Dt); - virtual void InStateChasing(float a_Dt); - virtual void InStateEscaping(float a_Dt); - - virtual void Attack(float a_Dt); - int GetMobType() {return m_MobType;} - int GetAttackRate(){return (int)m_AttackRate;} - void SetAttackRate(int ar); - void SetAttackRange(float ar); - void SetAttackDamage(float ad); - void SetSightDistance(float sd); - - enum MState{ATTACKING, IDLE, CHASING, ESCAPING} m_EMState; - enum MPersonality{PASSIVE,AGGRESSIVE,COWARDLY} m_EMPersonality; - -protected: - - cEntity* m_Target; - float m_AttackRate; - float idle_interval; - - Vector3f m_Destination; - bool m_bMovingToDestination; - bool m_bPassiveAggressive; - - Vector3f m_Speed; - float m_DestinationTime; - - float m_Gravity; - bool m_bOnGround; - - float m_DestroyTimer; - float m_Jump; - - char m_MobType; - - float m_SeePlayerInterval; - float m_AttackDamage; - float m_AttackRange; - float m_AttackInterval; - - void AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, ENUM_ITEM_ID a_Item, short a_ItemHealth = 0); -}; //tolua_export - - - - + +#pragma once + +#include "cPawn.h" +#include "Defines.h" +#include "cWorld.h" +#include "BlockID.h" +#include "cItem.h" +#include "BlockID.h" + + + + + +class Vector3f; +class cClientHandle; + + + + +class cMonster : public cPawn //tolua_export +{ //tolua_export +public: + + cMonster(); + virtual ~cMonster(); + + virtual bool IsA( const char* a_EntityType ); + + virtual cPacket * GetSpawnPacket(void) const override; + + virtual void Tick(float a_Dt) override; + + virtual void HandlePhysics(float a_Dt); + virtual void ReplicateMovement(); + + virtual void TakeDamage( int a_Damage, cEntity* a_Instigator ); + virtual void KilledBy( cEntity* a_Killer ); + + virtual void MoveToPosition( const Vector3f & a_Position ); + virtual bool ReachedDestination(); + + const char *GetState(); + void SetState(const char* str); + static void ListMonsters(); + + virtual void CheckEventSeePlayer(); + virtual void EventSeePlayer(cEntity *); + float m_SightDistance; + virtual cPlayer *FindClosestPlayer(); //non static is easier. also virtual so other mobs can implement their own searching algo + virtual void GetMonsterConfig(const char* pm_name); + virtual void EventLosePlayer(); + virtual void CheckEventLostPlayer(); + + virtual void InStateIdle(float a_Dt); + virtual void InStateChasing(float a_Dt); + virtual void InStateEscaping(float a_Dt); + + virtual void Attack(float a_Dt); + int GetMobType() {return m_MobType;} + int GetAttackRate(){return (int)m_AttackRate;} + void SetAttackRate(int ar); + void SetAttackRange(float ar); + void SetAttackDamage(float ad); + void SetSightDistance(float sd); + + enum MState{ATTACKING, IDLE, CHASING, ESCAPING} m_EMState; + enum MPersonality{PASSIVE,AGGRESSIVE,COWARDLY} m_EMPersonality; + +protected: + + cEntity* m_Target; + float m_AttackRate; + float idle_interval; + + Vector3f m_Destination; + bool m_bMovingToDestination; + bool m_bPassiveAggressive; + + Vector3f m_Speed; + float m_DestinationTime; + + float m_Gravity; + bool m_bOnGround; + + float m_DestroyTimer; + float m_Jump; + + char m_MobType; + + float m_SeePlayerInterval; + float m_AttackDamage; + float m_AttackRange; + float m_AttackInterval; + + void AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, ENUM_ITEM_ID a_Item, short a_ItemHealth = 0); +}; //tolua_export + + + + diff --git a/source/cMonsterConfig.cpp b/source/cMonsterConfig.cpp index 92f65aeec..f8bc9e16f 100644 --- a/source/cMonsterConfig.cpp +++ b/source/cMonsterConfig.cpp @@ -1,114 +1,114 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cMonsterConfig.h" -#include "cMonster.h" -#include "../iniFile/iniFile.h" -//#include - - - - - -struct cMonsterConfig::sAttributesStruct -{ - AString m_name; - float m_SightDistance; - float m_AttackDamage; - float m_AttackRange; - float m_AttackRate; - int m_MaxHealth; -}; - - - - - -struct cMonsterConfig::sMonsterConfigState -{ - AString MonsterTypes; - std::list< sAttributesStruct > AttributesList; -}; - - - - - -cMonsterConfig::cMonsterConfig(void) - : m_pState( new sMonsterConfigState ) -{ - Initialize(); -} - - - - - -cMonsterConfig::~cMonsterConfig() { - delete m_pState; -} - - - - - -void cMonsterConfig::Initialize() { - - sAttributesStruct Attributes; - cIniFile SettingsIniFile("settings.ini"); - cIniFile MonstersIniFile("monsters.ini"); - - if (!SettingsIniFile.ReadFile() || !MonstersIniFile.ReadFile()) - { - LOGWARNING("cMonsterConfig: Must have both settings.ini and monsters.ini to configure attributes\n\tusing default attributes \n"); - return; - } - - m_pState->MonsterTypes = SettingsIniFile.GetValue("Monsters","Types",""); - - if ( m_pState->MonsterTypes.empty() ) - { - LOGWARNING("cMonsterConfig: No Monster types listed in config file, using default attributes \n"); - return; - } - - AStringVector SplitList = StringSplit(m_pState->MonsterTypes,","); - for (unsigned int i = 0; i < SplitList.size(); ++i) - { - if (!SplitList[i].empty()) - { - Attributes.m_name = SplitList[i].c_str(); - Attributes.m_AttackDamage = (float)MonstersIniFile.GetValueF(SplitList[i].c_str(), "AttackDamage", 0); - Attributes.m_AttackRange = (float)MonstersIniFile.GetValueF(SplitList[i].c_str(), "AttackRange", 0); - Attributes.m_SightDistance = (float)MonstersIniFile.GetValueF(SplitList[i].c_str(), "SightDistance", 0); - Attributes.m_AttackRate = (float)MonstersIniFile.GetValueF(SplitList[i].c_str(), "AttackRate", 0); - Attributes.m_MaxHealth = MonstersIniFile.GetValueI(SplitList[i].c_str(), "MaxHealth", 0); - m_pState->AttributesList.push_front(Attributes); - } - } // for i - SplitList[] -} - - - - - -void cMonsterConfig::AssignAttributes(cMonster *m, const char* n) -{ - std::list::const_iterator itr; - for (itr = m_pState->AttributesList.begin(); itr != m_pState->AttributesList.end(); ++itr) - { - if(itr->m_name.compare(n) == 0) - { - m->SetAttackDamage (itr->m_AttackDamage); - m->SetAttackRange (itr->m_AttackRange); - m->SetSightDistance(itr->m_SightDistance); - m->SetAttackRate ((int)itr->m_AttackRate); - m->SetMaxHealth ((short)itr->m_MaxHealth); - } - } // for itr - m_pState->AttributesList[] -} - - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cMonsterConfig.h" +#include "cMonster.h" +#include "../iniFile/iniFile.h" +//#include + + + + + +struct cMonsterConfig::sAttributesStruct +{ + AString m_name; + float m_SightDistance; + float m_AttackDamage; + float m_AttackRange; + float m_AttackRate; + int m_MaxHealth; +}; + + + + + +struct cMonsterConfig::sMonsterConfigState +{ + AString MonsterTypes; + std::list< sAttributesStruct > AttributesList; +}; + + + + + +cMonsterConfig::cMonsterConfig(void) + : m_pState( new sMonsterConfigState ) +{ + Initialize(); +} + + + + + +cMonsterConfig::~cMonsterConfig() { + delete m_pState; +} + + + + + +void cMonsterConfig::Initialize() { + + sAttributesStruct Attributes; + cIniFile SettingsIniFile("settings.ini"); + cIniFile MonstersIniFile("monsters.ini"); + + if (!SettingsIniFile.ReadFile() || !MonstersIniFile.ReadFile()) + { + LOGWARNING("cMonsterConfig: Must have both settings.ini and monsters.ini to configure attributes\n\tusing default attributes \n"); + return; + } + + m_pState->MonsterTypes = SettingsIniFile.GetValue("Monsters","Types",""); + + if ( m_pState->MonsterTypes.empty() ) + { + LOGWARNING("cMonsterConfig: No Monster types listed in config file, using default attributes \n"); + return; + } + + AStringVector SplitList = StringSplit(m_pState->MonsterTypes,","); + for (unsigned int i = 0; i < SplitList.size(); ++i) + { + if (!SplitList[i].empty()) + { + Attributes.m_name = SplitList[i].c_str(); + Attributes.m_AttackDamage = (float)MonstersIniFile.GetValueF(SplitList[i].c_str(), "AttackDamage", 0); + Attributes.m_AttackRange = (float)MonstersIniFile.GetValueF(SplitList[i].c_str(), "AttackRange", 0); + Attributes.m_SightDistance = (float)MonstersIniFile.GetValueF(SplitList[i].c_str(), "SightDistance", 0); + Attributes.m_AttackRate = (float)MonstersIniFile.GetValueF(SplitList[i].c_str(), "AttackRate", 0); + Attributes.m_MaxHealth = MonstersIniFile.GetValueI(SplitList[i].c_str(), "MaxHealth", 0); + m_pState->AttributesList.push_front(Attributes); + } + } // for i - SplitList[] +} + + + + + +void cMonsterConfig::AssignAttributes(cMonster *m, const char* n) +{ + std::list::const_iterator itr; + for (itr = m_pState->AttributesList.begin(); itr != m_pState->AttributesList.end(); ++itr) + { + if(itr->m_name.compare(n) == 0) + { + m->SetAttackDamage (itr->m_AttackDamage); + m->SetAttackRange (itr->m_AttackRange); + m->SetSightDistance(itr->m_SightDistance); + m->SetAttackRate ((int)itr->m_AttackRate); + m->SetMaxHealth ((short)itr->m_MaxHealth); + } + } // for itr - m_pState->AttributesList[] +} + + + + + diff --git a/source/cMonsterConfig.h b/source/cMonsterConfig.h index fbe537802..d1a514b17 100644 --- a/source/cMonsterConfig.h +++ b/source/cMonsterConfig.h @@ -1,17 +1,17 @@ -#pragma once - -class cMonster; -class cMonsterConfig -{ -public: - cMonsterConfig(void); - ~cMonsterConfig(); - - void AssignAttributes(cMonster *m, const char* n); - -private: - struct sAttributesStruct; - struct sMonsterConfigState; - sMonsterConfigState* m_pState; - void Initialize(); +#pragma once + +class cMonster; +class cMonsterConfig +{ +public: + cMonsterConfig(void); + ~cMonsterConfig(); + + void AssignAttributes(cMonster *m, const char* n); + +private: + struct sAttributesStruct; + struct sMonsterConfigState; + sMonsterConfigState* m_pState; + void Initialize(); }; \ No newline at end of file diff --git a/source/cNoise.cpp b/source/cNoise.cpp index 653b9e95c..2dd26e5aa 100644 --- a/source/cNoise.cpp +++ b/source/cNoise.cpp @@ -1,305 +1,305 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cNoise.h" -#include - -#if NOISE_USE_SSE -#include //_mm_mul_epi32 -#endif - -#define FAST_FLOOR( x ) ( (x) < 0 ? ((int)x)-1 : ((int)x) ) - - - - - -cNoise::cNoise( unsigned int a_Seed ) - : m_Seed( a_Seed ) -{ -} - - -cNoise::~cNoise() -{ -} - -#if NOISE_USE_SSE -/**************** - * SSE Random value generator - **/ -__m128 cNoise::SSE_IntNoise2D( int a_X1, int a_Y1, int a_X2, int a_Y2, int a_X3, int a_Y3, int a_X4, int a_Y4 ) const -{ - const __m128i X4 = _mm_set_epi32(a_X4, a_X3, a_X2, a_X1); - const __m128i Y4 = _mm_set_epi32(a_Y4, a_Y3, a_Y2, a_Y1); - - const __m128 One4 = _mm_set_ps1( 1.f ); - const __m128i YScale4 = _mm_set1_epi32( 57 ); - - const __m128i i15731 = _mm_set1_epi32( 15731 ); - const __m128i i789221 = _mm_set1_epi32( 789221 ); - const __m128i i1376312589 = _mm_set1_epi32(1376312589); - const __m128i MaskValue4 = _mm_set1_epi32(0x7fffffff); - const __m128 f1073741824 = _mm_set_ps1( 1073741824.0f ); - - const __m128i Seed4 = _mm_mullo_epi32( _mm_mullo_epi32( _mm_set1_epi32( m_Seed ), YScale4 ), YScale4 ); - - const __m128i ScaledY4 = _mm_mullo_epi32( Y4, YScale4 ); - const __m128i n4 = _mm_add_epi32( _mm_add_epi32( X4, ScaledY4 ), Seed4 ); - const __m128i nn4 = _mm_slli_epi32( n4, 13 ); - const __m128i nnn4 = _mm_xor_si128( nn4, n4 ); - - const __m128i StepA4 = _mm_mullo_epi32( nnn4, nnn4 ); - const __m128i StepAA4 = _mm_add_epi32( _mm_mullo_epi32( StepA4, i15731 ), i789221 ); - const __m128i StepB4 = _mm_add_epi32( _mm_mullo_epi32( nnn4, StepAA4 ), i1376312589 ); - const __m128i StepC4 = _mm_and_si128( StepB4, MaskValue4 ); - const __m128 StepD4 = _mm_div_ps( _mm_cvtepi32_ps( StepC4 ), f1073741824 ); - const __m128 Result4 = _mm_sub_ps( One4, StepD4 ); - - return Result4; -} -#endif - - -/*************** - * Interpolated (and 1 smoothed) noise in 1-dimension - **/ -float cNoise::LinearNoise1D( float a_X ) const -{ - int BaseX = FAST_FLOOR( a_X ); - float FracX = (a_X) - BaseX; - return LinearInterpolate( IntNoise( BaseX ), IntNoise( BaseX+1 ), FracX); -} - -float cNoise::CosineNoise1D( float a_X ) const -{ - int BaseX = FAST_FLOOR( a_X ); - float FracX = (a_X) - BaseX; - return CosineInterpolate( IntNoise( BaseX ), IntNoise( BaseX+1 ), FracX); -} - -float cNoise::CubicNoise1D( float a_X ) const -{ - int BaseX = FAST_FLOOR( a_X ); - float FracX = (a_X) - BaseX; - return CubicInterpolate( IntNoise( BaseX-1 ), IntNoise( BaseX ), IntNoise( BaseX+1 ), IntNoise( BaseX+2 ), FracX); -} - -float cNoise::SmoothNoise1D( int a_X ) const -{ - return IntNoise(a_X)/2 + IntNoise(a_X-1)/4 + IntNoise(a_X+1)/4; -} - -/****************** - * Interpolated (and 1 smoothed) noise in 2-dimensions - **/ -float cNoise::LinearNoise2D( float a_X, float a_Y ) const -{ - const int BaseX = FAST_FLOOR( a_X ); - const int BaseY = FAST_FLOOR( a_Y ); - - const float tl = IntNoise2D( BaseX, BaseY ); - const float tr = IntNoise2D( BaseX+1, BaseY ); - const float bl = IntNoise2D( BaseX, BaseY+1 ); - const float br = IntNoise2D( BaseX+1, BaseY+1 ); - - const float FracX = (a_X) - BaseX; - const float interp1 = LinearInterpolate( tl, tr, FracX ); - const float interp2 = LinearInterpolate( bl, br, FracX ); - - const float FracY = (a_Y) - BaseY; - return LinearInterpolate( interp1, interp2, FracY ); -} - -float cNoise::CosineNoise2D( float a_X, float a_Y ) const -{ - const int BaseX = FAST_FLOOR( a_X ); - const int BaseY = FAST_FLOOR( a_Y ); - - const float tl = IntNoise2D( BaseX, BaseY ); - const float tr = IntNoise2D( BaseX+1, BaseY ); - const float bl = IntNoise2D( BaseX, BaseY+1 ); - const float br = IntNoise2D( BaseX+1, BaseY+1 ); - - const float FracX = (a_X) - BaseX; - const float interp1 = CosineInterpolate( tl, tr, FracX ); - const float interp2 = CosineInterpolate( bl, br, FracX ); - - const float FracY = (a_Y) - BaseY; - return CosineInterpolate( interp1, interp2, FracY ); -} - - - - - -float cNoise::CubicNoise2D( float a_X, float a_Y ) const -{ - const int BaseX = FAST_FLOOR( a_X ); - const int BaseY = FAST_FLOOR( a_Y ); - - const float points[4][4] = - { - IntNoise2D( BaseX-1, BaseY-1 ), IntNoise2D( BaseX, BaseY-1 ), IntNoise2D( BaseX+1, BaseY-1 ), IntNoise2D( BaseX+2, BaseY-1 ), - IntNoise2D( BaseX-1, BaseY ), IntNoise2D( BaseX, BaseY ), IntNoise2D( BaseX+1, BaseY ), IntNoise2D( BaseX+2, BaseY ), - IntNoise2D( BaseX-1, BaseY+1 ), IntNoise2D( BaseX, BaseY+1 ), IntNoise2D( BaseX+1, BaseY+1 ), IntNoise2D( BaseX+2, BaseY+1 ), - IntNoise2D( BaseX-1, BaseY+2 ), IntNoise2D( BaseX, BaseY+2 ), IntNoise2D( BaseX+1, BaseY+2 ), IntNoise2D( BaseX+2, BaseY+2 ), - }; - - const float FracX = (a_X) - BaseX; - const float interp1 = CubicInterpolate( points[0][0], points[0][1], points[0][2], points[0][3], FracX ); - const float interp2 = CubicInterpolate( points[1][0], points[1][1], points[1][2], points[1][3], FracX ); - const float interp3 = CubicInterpolate( points[2][0], points[2][1], points[2][2], points[2][3], FracX ); - const float interp4 = CubicInterpolate( points[3][0], points[3][1], points[3][2], points[3][3], FracX ); - - - const float FracY = (a_Y) - BaseY; - return CubicInterpolate( interp1, interp2, interp3, interp4, FracY ); -} - - - - - -#if NOISE_USE_SSE -float cNoise::SSE_CubicNoise2D( float a_X, float a_Y ) const -{ - const int BaseX = FAST_FLOOR( a_X ); - const int BaseY = FAST_FLOOR( a_Y ); - - __m128 points4[4] = { - SSE_IntNoise2D( BaseX-1, BaseY-1, BaseX-1, BaseY, BaseX-1, BaseY+1, BaseX-1, BaseY+2 ), - SSE_IntNoise2D( BaseX, BaseY-1, BaseX, BaseY, BaseX, BaseY+1, BaseX, BaseY+2 ), - SSE_IntNoise2D( BaseX+1, BaseY-1, BaseX+1, BaseY, BaseX+1, BaseY+1, BaseX+1, BaseY+2 ), - SSE_IntNoise2D( BaseX+2, BaseY-1, BaseX+2, BaseY, BaseX+2, BaseY+1, BaseX+2, BaseY+2 ), - }; - - const float FracX = (a_X) - BaseX; - union { __m128 p4; float p[4]; } - AllInterp = { CubicInterpolate4( points4[0], points4[1], points4[2], points4[3], FracX ) }; - - const float FracY = (a_Y) - BaseY; - return CubicInterpolate( AllInterp.p[0], AllInterp.p[1], AllInterp.p[2], AllInterp.p[3], FracY ); -} -#endif - -/****************** - * Interpolated (and 1 smoothed) noise in 3-dimensions - **/ -float cNoise::CosineNoise3D( float a_X, float a_Y, float a_Z ) const -{ - const int BaseX = FAST_FLOOR( a_X ); - const int BaseY = FAST_FLOOR( a_Y ); - const int BaseZ = FAST_FLOOR( a_Z ); - - const float ftl = IntNoise3D( BaseX, BaseY, BaseZ ); - const float ftr = IntNoise3D( BaseX+1, BaseY, BaseZ ); - const float fbl = IntNoise3D( BaseX, BaseY+1, BaseZ ); - const float fbr = IntNoise3D( BaseX+1, BaseY+1, BaseZ ); - - const float btl = IntNoise3D( BaseX, BaseY, BaseZ+1 ); - const float btr = IntNoise3D( BaseX+1, BaseY, BaseZ+1 ); - const float bbl = IntNoise3D( BaseX, BaseY+1, BaseZ+1 ); - const float bbr = IntNoise3D( BaseX+1, BaseY+1, BaseZ+1 ); - - const float FracX = (a_X) - BaseX; - const float finterp1 = CosineInterpolate( ftl, ftr, FracX ); - const float finterp2 = CosineInterpolate( fbl, fbr, FracX ); - const float binterp1 = CosineInterpolate( btl, btr, FracX ); - const float binterp2 = CosineInterpolate( bbl, bbr, FracX ); - - const float FracY = (a_Y) - BaseY; - const float interp1 = CosineInterpolate( finterp1, finterp2, FracY ); - const float interp2 = CosineInterpolate( binterp1, binterp2, FracY ); - - const float FracZ = (a_Z) - BaseZ; - return CosineInterpolate( interp1, interp2, FracZ ); -} - -float cNoise::CubicNoise3D( float a_X, float a_Y, float a_Z ) const -{ - const int BaseX = FAST_FLOOR( a_X ); - const int BaseY = FAST_FLOOR( a_Y ); - const int BaseZ = FAST_FLOOR( a_Z ); - - const float points1[4][4] = { - IntNoise3D( BaseX-1, BaseY-1, BaseZ-1 ), IntNoise3D( BaseX, BaseY-1, BaseZ-1 ), IntNoise3D( BaseX+1, BaseY-1, BaseZ-1 ), IntNoise3D( BaseX+2, BaseY-1, BaseZ-1 ), - IntNoise3D( BaseX-1, BaseY, BaseZ-1 ), IntNoise3D( BaseX, BaseY, BaseZ-1 ), IntNoise3D( BaseX+1, BaseY, BaseZ-1 ), IntNoise3D( BaseX+2, BaseY, BaseZ-1 ), - IntNoise3D( BaseX-1, BaseY+1, BaseZ-1 ), IntNoise3D( BaseX, BaseY+1, BaseZ-1 ), IntNoise3D( BaseX+1, BaseY+1, BaseZ-1 ), IntNoise3D( BaseX+2, BaseY+1, BaseZ-1 ), - IntNoise3D( BaseX-1, BaseY+2, BaseZ-1 ), IntNoise3D( BaseX, BaseY+2, BaseZ-1 ), IntNoise3D( BaseX+1, BaseY+2, BaseZ-1 ), IntNoise3D( BaseX+2, BaseY+2, BaseZ-1 ), - }; - - const float FracX = (a_X) - BaseX; - const float x1interp1 = CubicInterpolate( points1[0][0], points1[0][1], points1[0][2], points1[0][3], FracX ); - const float x1interp2 = CubicInterpolate( points1[1][0], points1[1][1], points1[1][2], points1[1][3], FracX ); - const float x1interp3 = CubicInterpolate( points1[2][0], points1[2][1], points1[2][2], points1[2][3], FracX ); - const float x1interp4 = CubicInterpolate( points1[3][0], points1[3][1], points1[3][2], points1[3][3], FracX ); - - const float points2[4][4] = { - IntNoise3D( BaseX-1, BaseY-1, BaseZ ), IntNoise3D( BaseX, BaseY-1, BaseZ ), IntNoise3D( BaseX+1, BaseY-1, BaseZ ), IntNoise3D( BaseX+2, BaseY-1, BaseZ ), - IntNoise3D( BaseX-1, BaseY, BaseZ ), IntNoise3D( BaseX, BaseY, BaseZ ), IntNoise3D( BaseX+1, BaseY, BaseZ ), IntNoise3D( BaseX+2, BaseY, BaseZ ), - IntNoise3D( BaseX-1, BaseY+1, BaseZ ), IntNoise3D( BaseX, BaseY+1, BaseZ ), IntNoise3D( BaseX+1, BaseY+1, BaseZ ), IntNoise3D( BaseX+2, BaseY+1, BaseZ ), - IntNoise3D( BaseX-1, BaseY+2, BaseZ ), IntNoise3D( BaseX, BaseY+2, BaseZ ), IntNoise3D( BaseX+1, BaseY+2, BaseZ ), IntNoise3D( BaseX+2, BaseY+2, BaseZ ), - }; - - const float x2interp1 = CubicInterpolate( points2[0][0], points2[0][1], points2[0][2], points2[0][3], FracX ); - const float x2interp2 = CubicInterpolate( points2[1][0], points2[1][1], points2[1][2], points2[1][3], FracX ); - const float x2interp3 = CubicInterpolate( points2[2][0], points2[2][1], points2[2][2], points2[2][3], FracX ); - const float x2interp4 = CubicInterpolate( points2[3][0], points2[3][1], points2[3][2], points2[3][3], FracX ); - - const float points3[4][4] = { - IntNoise3D( BaseX-1, BaseY-1, BaseZ+1 ), IntNoise3D( BaseX, BaseY-1, BaseZ+1 ), IntNoise3D( BaseX+1, BaseY-1, BaseZ+1 ), IntNoise3D( BaseX+2, BaseY-1, BaseZ+1 ), - IntNoise3D( BaseX-1, BaseY, BaseZ+1 ), IntNoise3D( BaseX, BaseY, BaseZ+1 ), IntNoise3D( BaseX+1, BaseY, BaseZ+1 ), IntNoise3D( BaseX+2, BaseY, BaseZ+1 ), - IntNoise3D( BaseX-1, BaseY+1, BaseZ+1 ), IntNoise3D( BaseX, BaseY+1, BaseZ+1 ), IntNoise3D( BaseX+1, BaseY+1, BaseZ+1 ), IntNoise3D( BaseX+2, BaseY+1, BaseZ+1 ), - IntNoise3D( BaseX-1, BaseY+2, BaseZ+1 ), IntNoise3D( BaseX, BaseY+2, BaseZ+1 ), IntNoise3D( BaseX+1, BaseY+2, BaseZ+1 ), IntNoise3D( BaseX+2, BaseY+2, BaseZ+1 ), - }; - - const float x3interp1 = CubicInterpolate( points3[0][0], points3[0][1], points3[0][2], points3[0][3], FracX ); - const float x3interp2 = CubicInterpolate( points3[1][0], points3[1][1], points3[1][2], points3[1][3], FracX ); - const float x3interp3 = CubicInterpolate( points3[2][0], points3[2][1], points3[2][2], points3[2][3], FracX ); - const float x3interp4 = CubicInterpolate( points3[3][0], points3[3][1], points3[3][2], points3[3][3], FracX ); - - const float points4[4][4] = { - IntNoise3D( BaseX-1, BaseY-1, BaseZ+2 ), IntNoise3D( BaseX, BaseY-1, BaseZ+2 ), IntNoise3D( BaseX+1, BaseY-1, BaseZ+2 ), IntNoise3D( BaseX+2, BaseY-1, BaseZ+2 ), - IntNoise3D( BaseX-1, BaseY, BaseZ+2 ), IntNoise3D( BaseX, BaseY, BaseZ+2 ), IntNoise3D( BaseX+1, BaseY, BaseZ+2 ), IntNoise3D( BaseX+2, BaseY, BaseZ+2 ), - IntNoise3D( BaseX-1, BaseY+1, BaseZ+2 ), IntNoise3D( BaseX, BaseY+1, BaseZ+2 ), IntNoise3D( BaseX+1, BaseY+1, BaseZ+2 ), IntNoise3D( BaseX+2, BaseY+1, BaseZ+2 ), - IntNoise3D( BaseX-1, BaseY+2, BaseZ+2 ), IntNoise3D( BaseX, BaseY+2, BaseZ+2 ), IntNoise3D( BaseX+1, BaseY+2, BaseZ+2 ), IntNoise3D( BaseX+2, BaseY+2, BaseZ+2 ), - }; - - const float x4interp1 = CubicInterpolate( points4[0][0], points4[0][1], points4[0][2], points4[0][3], FracX ); - const float x4interp2 = CubicInterpolate( points4[1][0], points4[1][1], points4[1][2], points4[1][3], FracX ); - const float x4interp3 = CubicInterpolate( points4[2][0], points4[2][1], points4[2][2], points4[2][3], FracX ); - const float x4interp4 = CubicInterpolate( points4[3][0], points4[3][1], points4[3][2], points4[3][3], FracX ); - - const float FracY = (a_Y) - BaseY; - const float yinterp1 = CubicInterpolate( x1interp1, x1interp2, x1interp3, x1interp4, FracY ); - const float yinterp2 = CubicInterpolate( x2interp1, x2interp2, x2interp3, x2interp4, FracY ); - const float yinterp3 = CubicInterpolate( x3interp1, x3interp2, x3interp3, x3interp4, FracY ); - const float yinterp4 = CubicInterpolate( x4interp1, x4interp2, x4interp3, x4interp4, FracY ); - - const float FracZ = (a_Z) - BaseZ; - return CubicInterpolate( yinterp1, yinterp2, yinterp3, yinterp4, FracZ ); -} - -/****************** - * Private - **/ - -#if NOISE_USE_SSE -__m128 cNoise::CubicInterpolate4( const __m128 & a_A, const __m128 & a_B, const __m128 & a_C, const __m128 & a_D, float a_Pct ) const -{ - const __m128 P = _mm_sub_ps( _mm_sub_ps( a_D, a_C ), _mm_sub_ps( a_A, a_B ) ); - const __m128 Q = _mm_sub_ps( _mm_sub_ps( a_A, a_B ), P ); - const __m128 R = _mm_sub_ps( a_C, a_A ); - - const __m128 Pct = _mm_set_ps1( a_Pct ); - const __m128 Pct2 = _mm_mul_ps( Pct, Pct ); - const __m128 Pct3 = _mm_mul_ps( Pct2, Pct ); - - return _mm_add_ps( _mm_add_ps( _mm_add_ps( _mm_mul_ps(P, Pct3), _mm_mul_ps( Q, Pct2 ) ), _mm_mul_ps( R, Pct ) ), a_B ); -} -#endif - -#if NOISE_USE_INLINE -# include "cNoise.inc" + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cNoise.h" +#include + +#if NOISE_USE_SSE +#include //_mm_mul_epi32 +#endif + +#define FAST_FLOOR( x ) ( (x) < 0 ? ((int)x)-1 : ((int)x) ) + + + + + +cNoise::cNoise( unsigned int a_Seed ) + : m_Seed( a_Seed ) +{ +} + + +cNoise::~cNoise() +{ +} + +#if NOISE_USE_SSE +/**************** + * SSE Random value generator + **/ +__m128 cNoise::SSE_IntNoise2D( int a_X1, int a_Y1, int a_X2, int a_Y2, int a_X3, int a_Y3, int a_X4, int a_Y4 ) const +{ + const __m128i X4 = _mm_set_epi32(a_X4, a_X3, a_X2, a_X1); + const __m128i Y4 = _mm_set_epi32(a_Y4, a_Y3, a_Y2, a_Y1); + + const __m128 One4 = _mm_set_ps1( 1.f ); + const __m128i YScale4 = _mm_set1_epi32( 57 ); + + const __m128i i15731 = _mm_set1_epi32( 15731 ); + const __m128i i789221 = _mm_set1_epi32( 789221 ); + const __m128i i1376312589 = _mm_set1_epi32(1376312589); + const __m128i MaskValue4 = _mm_set1_epi32(0x7fffffff); + const __m128 f1073741824 = _mm_set_ps1( 1073741824.0f ); + + const __m128i Seed4 = _mm_mullo_epi32( _mm_mullo_epi32( _mm_set1_epi32( m_Seed ), YScale4 ), YScale4 ); + + const __m128i ScaledY4 = _mm_mullo_epi32( Y4, YScale4 ); + const __m128i n4 = _mm_add_epi32( _mm_add_epi32( X4, ScaledY4 ), Seed4 ); + const __m128i nn4 = _mm_slli_epi32( n4, 13 ); + const __m128i nnn4 = _mm_xor_si128( nn4, n4 ); + + const __m128i StepA4 = _mm_mullo_epi32( nnn4, nnn4 ); + const __m128i StepAA4 = _mm_add_epi32( _mm_mullo_epi32( StepA4, i15731 ), i789221 ); + const __m128i StepB4 = _mm_add_epi32( _mm_mullo_epi32( nnn4, StepAA4 ), i1376312589 ); + const __m128i StepC4 = _mm_and_si128( StepB4, MaskValue4 ); + const __m128 StepD4 = _mm_div_ps( _mm_cvtepi32_ps( StepC4 ), f1073741824 ); + const __m128 Result4 = _mm_sub_ps( One4, StepD4 ); + + return Result4; +} +#endif + + +/*************** + * Interpolated (and 1 smoothed) noise in 1-dimension + **/ +float cNoise::LinearNoise1D( float a_X ) const +{ + int BaseX = FAST_FLOOR( a_X ); + float FracX = (a_X) - BaseX; + return LinearInterpolate( IntNoise( BaseX ), IntNoise( BaseX+1 ), FracX); +} + +float cNoise::CosineNoise1D( float a_X ) const +{ + int BaseX = FAST_FLOOR( a_X ); + float FracX = (a_X) - BaseX; + return CosineInterpolate( IntNoise( BaseX ), IntNoise( BaseX+1 ), FracX); +} + +float cNoise::CubicNoise1D( float a_X ) const +{ + int BaseX = FAST_FLOOR( a_X ); + float FracX = (a_X) - BaseX; + return CubicInterpolate( IntNoise( BaseX-1 ), IntNoise( BaseX ), IntNoise( BaseX+1 ), IntNoise( BaseX+2 ), FracX); +} + +float cNoise::SmoothNoise1D( int a_X ) const +{ + return IntNoise(a_X)/2 + IntNoise(a_X-1)/4 + IntNoise(a_X+1)/4; +} + +/****************** + * Interpolated (and 1 smoothed) noise in 2-dimensions + **/ +float cNoise::LinearNoise2D( float a_X, float a_Y ) const +{ + const int BaseX = FAST_FLOOR( a_X ); + const int BaseY = FAST_FLOOR( a_Y ); + + const float tl = IntNoise2D( BaseX, BaseY ); + const float tr = IntNoise2D( BaseX+1, BaseY ); + const float bl = IntNoise2D( BaseX, BaseY+1 ); + const float br = IntNoise2D( BaseX+1, BaseY+1 ); + + const float FracX = (a_X) - BaseX; + const float interp1 = LinearInterpolate( tl, tr, FracX ); + const float interp2 = LinearInterpolate( bl, br, FracX ); + + const float FracY = (a_Y) - BaseY; + return LinearInterpolate( interp1, interp2, FracY ); +} + +float cNoise::CosineNoise2D( float a_X, float a_Y ) const +{ + const int BaseX = FAST_FLOOR( a_X ); + const int BaseY = FAST_FLOOR( a_Y ); + + const float tl = IntNoise2D( BaseX, BaseY ); + const float tr = IntNoise2D( BaseX+1, BaseY ); + const float bl = IntNoise2D( BaseX, BaseY+1 ); + const float br = IntNoise2D( BaseX+1, BaseY+1 ); + + const float FracX = (a_X) - BaseX; + const float interp1 = CosineInterpolate( tl, tr, FracX ); + const float interp2 = CosineInterpolate( bl, br, FracX ); + + const float FracY = (a_Y) - BaseY; + return CosineInterpolate( interp1, interp2, FracY ); +} + + + + + +float cNoise::CubicNoise2D( float a_X, float a_Y ) const +{ + const int BaseX = FAST_FLOOR( a_X ); + const int BaseY = FAST_FLOOR( a_Y ); + + const float points[4][4] = + { + IntNoise2D( BaseX-1, BaseY-1 ), IntNoise2D( BaseX, BaseY-1 ), IntNoise2D( BaseX+1, BaseY-1 ), IntNoise2D( BaseX+2, BaseY-1 ), + IntNoise2D( BaseX-1, BaseY ), IntNoise2D( BaseX, BaseY ), IntNoise2D( BaseX+1, BaseY ), IntNoise2D( BaseX+2, BaseY ), + IntNoise2D( BaseX-1, BaseY+1 ), IntNoise2D( BaseX, BaseY+1 ), IntNoise2D( BaseX+1, BaseY+1 ), IntNoise2D( BaseX+2, BaseY+1 ), + IntNoise2D( BaseX-1, BaseY+2 ), IntNoise2D( BaseX, BaseY+2 ), IntNoise2D( BaseX+1, BaseY+2 ), IntNoise2D( BaseX+2, BaseY+2 ), + }; + + const float FracX = (a_X) - BaseX; + const float interp1 = CubicInterpolate( points[0][0], points[0][1], points[0][2], points[0][3], FracX ); + const float interp2 = CubicInterpolate( points[1][0], points[1][1], points[1][2], points[1][3], FracX ); + const float interp3 = CubicInterpolate( points[2][0], points[2][1], points[2][2], points[2][3], FracX ); + const float interp4 = CubicInterpolate( points[3][0], points[3][1], points[3][2], points[3][3], FracX ); + + + const float FracY = (a_Y) - BaseY; + return CubicInterpolate( interp1, interp2, interp3, interp4, FracY ); +} + + + + + +#if NOISE_USE_SSE +float cNoise::SSE_CubicNoise2D( float a_X, float a_Y ) const +{ + const int BaseX = FAST_FLOOR( a_X ); + const int BaseY = FAST_FLOOR( a_Y ); + + __m128 points4[4] = { + SSE_IntNoise2D( BaseX-1, BaseY-1, BaseX-1, BaseY, BaseX-1, BaseY+1, BaseX-1, BaseY+2 ), + SSE_IntNoise2D( BaseX, BaseY-1, BaseX, BaseY, BaseX, BaseY+1, BaseX, BaseY+2 ), + SSE_IntNoise2D( BaseX+1, BaseY-1, BaseX+1, BaseY, BaseX+1, BaseY+1, BaseX+1, BaseY+2 ), + SSE_IntNoise2D( BaseX+2, BaseY-1, BaseX+2, BaseY, BaseX+2, BaseY+1, BaseX+2, BaseY+2 ), + }; + + const float FracX = (a_X) - BaseX; + union { __m128 p4; float p[4]; } + AllInterp = { CubicInterpolate4( points4[0], points4[1], points4[2], points4[3], FracX ) }; + + const float FracY = (a_Y) - BaseY; + return CubicInterpolate( AllInterp.p[0], AllInterp.p[1], AllInterp.p[2], AllInterp.p[3], FracY ); +} +#endif + +/****************** + * Interpolated (and 1 smoothed) noise in 3-dimensions + **/ +float cNoise::CosineNoise3D( float a_X, float a_Y, float a_Z ) const +{ + const int BaseX = FAST_FLOOR( a_X ); + const int BaseY = FAST_FLOOR( a_Y ); + const int BaseZ = FAST_FLOOR( a_Z ); + + const float ftl = IntNoise3D( BaseX, BaseY, BaseZ ); + const float ftr = IntNoise3D( BaseX+1, BaseY, BaseZ ); + const float fbl = IntNoise3D( BaseX, BaseY+1, BaseZ ); + const float fbr = IntNoise3D( BaseX+1, BaseY+1, BaseZ ); + + const float btl = IntNoise3D( BaseX, BaseY, BaseZ+1 ); + const float btr = IntNoise3D( BaseX+1, BaseY, BaseZ+1 ); + const float bbl = IntNoise3D( BaseX, BaseY+1, BaseZ+1 ); + const float bbr = IntNoise3D( BaseX+1, BaseY+1, BaseZ+1 ); + + const float FracX = (a_X) - BaseX; + const float finterp1 = CosineInterpolate( ftl, ftr, FracX ); + const float finterp2 = CosineInterpolate( fbl, fbr, FracX ); + const float binterp1 = CosineInterpolate( btl, btr, FracX ); + const float binterp2 = CosineInterpolate( bbl, bbr, FracX ); + + const float FracY = (a_Y) - BaseY; + const float interp1 = CosineInterpolate( finterp1, finterp2, FracY ); + const float interp2 = CosineInterpolate( binterp1, binterp2, FracY ); + + const float FracZ = (a_Z) - BaseZ; + return CosineInterpolate( interp1, interp2, FracZ ); +} + +float cNoise::CubicNoise3D( float a_X, float a_Y, float a_Z ) const +{ + const int BaseX = FAST_FLOOR( a_X ); + const int BaseY = FAST_FLOOR( a_Y ); + const int BaseZ = FAST_FLOOR( a_Z ); + + const float points1[4][4] = { + IntNoise3D( BaseX-1, BaseY-1, BaseZ-1 ), IntNoise3D( BaseX, BaseY-1, BaseZ-1 ), IntNoise3D( BaseX+1, BaseY-1, BaseZ-1 ), IntNoise3D( BaseX+2, BaseY-1, BaseZ-1 ), + IntNoise3D( BaseX-1, BaseY, BaseZ-1 ), IntNoise3D( BaseX, BaseY, BaseZ-1 ), IntNoise3D( BaseX+1, BaseY, BaseZ-1 ), IntNoise3D( BaseX+2, BaseY, BaseZ-1 ), + IntNoise3D( BaseX-1, BaseY+1, BaseZ-1 ), IntNoise3D( BaseX, BaseY+1, BaseZ-1 ), IntNoise3D( BaseX+1, BaseY+1, BaseZ-1 ), IntNoise3D( BaseX+2, BaseY+1, BaseZ-1 ), + IntNoise3D( BaseX-1, BaseY+2, BaseZ-1 ), IntNoise3D( BaseX, BaseY+2, BaseZ-1 ), IntNoise3D( BaseX+1, BaseY+2, BaseZ-1 ), IntNoise3D( BaseX+2, BaseY+2, BaseZ-1 ), + }; + + const float FracX = (a_X) - BaseX; + const float x1interp1 = CubicInterpolate( points1[0][0], points1[0][1], points1[0][2], points1[0][3], FracX ); + const float x1interp2 = CubicInterpolate( points1[1][0], points1[1][1], points1[1][2], points1[1][3], FracX ); + const float x1interp3 = CubicInterpolate( points1[2][0], points1[2][1], points1[2][2], points1[2][3], FracX ); + const float x1interp4 = CubicInterpolate( points1[3][0], points1[3][1], points1[3][2], points1[3][3], FracX ); + + const float points2[4][4] = { + IntNoise3D( BaseX-1, BaseY-1, BaseZ ), IntNoise3D( BaseX, BaseY-1, BaseZ ), IntNoise3D( BaseX+1, BaseY-1, BaseZ ), IntNoise3D( BaseX+2, BaseY-1, BaseZ ), + IntNoise3D( BaseX-1, BaseY, BaseZ ), IntNoise3D( BaseX, BaseY, BaseZ ), IntNoise3D( BaseX+1, BaseY, BaseZ ), IntNoise3D( BaseX+2, BaseY, BaseZ ), + IntNoise3D( BaseX-1, BaseY+1, BaseZ ), IntNoise3D( BaseX, BaseY+1, BaseZ ), IntNoise3D( BaseX+1, BaseY+1, BaseZ ), IntNoise3D( BaseX+2, BaseY+1, BaseZ ), + IntNoise3D( BaseX-1, BaseY+2, BaseZ ), IntNoise3D( BaseX, BaseY+2, BaseZ ), IntNoise3D( BaseX+1, BaseY+2, BaseZ ), IntNoise3D( BaseX+2, BaseY+2, BaseZ ), + }; + + const float x2interp1 = CubicInterpolate( points2[0][0], points2[0][1], points2[0][2], points2[0][3], FracX ); + const float x2interp2 = CubicInterpolate( points2[1][0], points2[1][1], points2[1][2], points2[1][3], FracX ); + const float x2interp3 = CubicInterpolate( points2[2][0], points2[2][1], points2[2][2], points2[2][3], FracX ); + const float x2interp4 = CubicInterpolate( points2[3][0], points2[3][1], points2[3][2], points2[3][3], FracX ); + + const float points3[4][4] = { + IntNoise3D( BaseX-1, BaseY-1, BaseZ+1 ), IntNoise3D( BaseX, BaseY-1, BaseZ+1 ), IntNoise3D( BaseX+1, BaseY-1, BaseZ+1 ), IntNoise3D( BaseX+2, BaseY-1, BaseZ+1 ), + IntNoise3D( BaseX-1, BaseY, BaseZ+1 ), IntNoise3D( BaseX, BaseY, BaseZ+1 ), IntNoise3D( BaseX+1, BaseY, BaseZ+1 ), IntNoise3D( BaseX+2, BaseY, BaseZ+1 ), + IntNoise3D( BaseX-1, BaseY+1, BaseZ+1 ), IntNoise3D( BaseX, BaseY+1, BaseZ+1 ), IntNoise3D( BaseX+1, BaseY+1, BaseZ+1 ), IntNoise3D( BaseX+2, BaseY+1, BaseZ+1 ), + IntNoise3D( BaseX-1, BaseY+2, BaseZ+1 ), IntNoise3D( BaseX, BaseY+2, BaseZ+1 ), IntNoise3D( BaseX+1, BaseY+2, BaseZ+1 ), IntNoise3D( BaseX+2, BaseY+2, BaseZ+1 ), + }; + + const float x3interp1 = CubicInterpolate( points3[0][0], points3[0][1], points3[0][2], points3[0][3], FracX ); + const float x3interp2 = CubicInterpolate( points3[1][0], points3[1][1], points3[1][2], points3[1][3], FracX ); + const float x3interp3 = CubicInterpolate( points3[2][0], points3[2][1], points3[2][2], points3[2][3], FracX ); + const float x3interp4 = CubicInterpolate( points3[3][0], points3[3][1], points3[3][2], points3[3][3], FracX ); + + const float points4[4][4] = { + IntNoise3D( BaseX-1, BaseY-1, BaseZ+2 ), IntNoise3D( BaseX, BaseY-1, BaseZ+2 ), IntNoise3D( BaseX+1, BaseY-1, BaseZ+2 ), IntNoise3D( BaseX+2, BaseY-1, BaseZ+2 ), + IntNoise3D( BaseX-1, BaseY, BaseZ+2 ), IntNoise3D( BaseX, BaseY, BaseZ+2 ), IntNoise3D( BaseX+1, BaseY, BaseZ+2 ), IntNoise3D( BaseX+2, BaseY, BaseZ+2 ), + IntNoise3D( BaseX-1, BaseY+1, BaseZ+2 ), IntNoise3D( BaseX, BaseY+1, BaseZ+2 ), IntNoise3D( BaseX+1, BaseY+1, BaseZ+2 ), IntNoise3D( BaseX+2, BaseY+1, BaseZ+2 ), + IntNoise3D( BaseX-1, BaseY+2, BaseZ+2 ), IntNoise3D( BaseX, BaseY+2, BaseZ+2 ), IntNoise3D( BaseX+1, BaseY+2, BaseZ+2 ), IntNoise3D( BaseX+2, BaseY+2, BaseZ+2 ), + }; + + const float x4interp1 = CubicInterpolate( points4[0][0], points4[0][1], points4[0][2], points4[0][3], FracX ); + const float x4interp2 = CubicInterpolate( points4[1][0], points4[1][1], points4[1][2], points4[1][3], FracX ); + const float x4interp3 = CubicInterpolate( points4[2][0], points4[2][1], points4[2][2], points4[2][3], FracX ); + const float x4interp4 = CubicInterpolate( points4[3][0], points4[3][1], points4[3][2], points4[3][3], FracX ); + + const float FracY = (a_Y) - BaseY; + const float yinterp1 = CubicInterpolate( x1interp1, x1interp2, x1interp3, x1interp4, FracY ); + const float yinterp2 = CubicInterpolate( x2interp1, x2interp2, x2interp3, x2interp4, FracY ); + const float yinterp3 = CubicInterpolate( x3interp1, x3interp2, x3interp3, x3interp4, FracY ); + const float yinterp4 = CubicInterpolate( x4interp1, x4interp2, x4interp3, x4interp4, FracY ); + + const float FracZ = (a_Z) - BaseZ; + return CubicInterpolate( yinterp1, yinterp2, yinterp3, yinterp4, FracZ ); +} + +/****************** + * Private + **/ + +#if NOISE_USE_SSE +__m128 cNoise::CubicInterpolate4( const __m128 & a_A, const __m128 & a_B, const __m128 & a_C, const __m128 & a_D, float a_Pct ) const +{ + const __m128 P = _mm_sub_ps( _mm_sub_ps( a_D, a_C ), _mm_sub_ps( a_A, a_B ) ); + const __m128 Q = _mm_sub_ps( _mm_sub_ps( a_A, a_B ), P ); + const __m128 R = _mm_sub_ps( a_C, a_A ); + + const __m128 Pct = _mm_set_ps1( a_Pct ); + const __m128 Pct2 = _mm_mul_ps( Pct, Pct ); + const __m128 Pct3 = _mm_mul_ps( Pct2, Pct ); + + return _mm_add_ps( _mm_add_ps( _mm_add_ps( _mm_mul_ps(P, Pct3), _mm_mul_ps( Q, Pct2 ) ), _mm_mul_ps( R, Pct ) ), a_B ); +} +#endif + +#if NOISE_USE_INLINE +# include "cNoise.inc" #endif \ No newline at end of file diff --git a/source/cNoise.h b/source/cNoise.h index 2169e0a13..ddee427ad 100644 --- a/source/cNoise.h +++ b/source/cNoise.h @@ -1,81 +1,81 @@ -#pragma once - -// Some settings -#define NOISE_USE_INLINE 1 -#define NOISE_USE_SSE 0 - -// Do not touch -#if NOISE_USE_INLINE - #ifdef _MSC_VER - #define __NOISE_INLINE__ __forceinline - #else - #define __NOISE_INLINE__ inline - #endif // _MSC_VER -#else - #define __NOISE_INLINE__ -#endif - -#if NOISE_USE_SSE -# include -#endif - - - - - -class cNoise -{ -public: - cNoise( unsigned int a_Seed ); - ~cNoise(); - -#if NOISE_USE_SSE - __m128 SSE_IntNoise2D( int a_X1, int a_Y1, int a_X2, int a_Y2, int a_X3, int a_Y3, int a_X4, int a_Y4 ) const; -#endif - - __NOISE_INLINE__ float IntNoise( int a_X ) const; - __NOISE_INLINE__ float IntNoise2D( int a_X, int a_Y ) const; - __NOISE_INLINE__ float IntNoise3D( int a_X, int a_Y, int a_Z ) const; - - // Note: These functions have a mod8-irregular chance - each of the mod8 remainders has different chance of occurrence. Divide by 8 to rectify. - __NOISE_INLINE__ int IntNoise1DInt( int a_X ) const; - __NOISE_INLINE__ int IntNoise2DInt( int a_X, int a_Y ) const; - __NOISE_INLINE__ int IntNoise3DInt( int a_X, int a_Y, int a_Z ) const; - - float LinearNoise1D( float a_X ) const; - float CosineNoise1D( float a_X ) const; - float CubicNoise1D( float a_X ) const; - float SmoothNoise1D( int a_X ) const; - - float LinearNoise2D( float a_X, float a_Y ) const; - float CosineNoise2D( float a_X, float a_Y ) const; - float CubicNoise2D( float a_X, float a_Y ) const; - float SSE_CubicNoise2D( float a_X, float a_Y ) const; - - float CosineNoise3D( float a_X, float a_Y, float a_Z ) const; - float CubicNoise3D( float a_X, float a_Y, float a_Z ) const; - - void SetSeed( unsigned int a_Seed ) { m_Seed = a_Seed; } -private: - __NOISE_INLINE__ float CubicInterpolate( float a_A, float a_B, float a_C, float a_D, float a_Pct ) const; - __NOISE_INLINE__ float CosineInterpolate( float a_A, float a_B, float a_Pct ) const; - __NOISE_INLINE__ float LinearInterpolate( float a_A, float a_B, float a_Pct ) const; - -#if NOISE_USE_SSE - __m128 CubicInterpolate4( const __m128 & a_A, const __m128 & a_B, const __m128 & a_C, const __m128 & a_D, float a_Pct ) const; -#endif - - unsigned int m_Seed; -}; - - - - - -#if NOISE_USE_INLINE -# include "cNoise.inc" -#endif - - - - +#pragma once + +// Some settings +#define NOISE_USE_INLINE 1 +#define NOISE_USE_SSE 0 + +// Do not touch +#if NOISE_USE_INLINE + #ifdef _MSC_VER + #define __NOISE_INLINE__ __forceinline + #else + #define __NOISE_INLINE__ inline + #endif // _MSC_VER +#else + #define __NOISE_INLINE__ +#endif + +#if NOISE_USE_SSE +# include +#endif + + + + + +class cNoise +{ +public: + cNoise( unsigned int a_Seed ); + ~cNoise(); + +#if NOISE_USE_SSE + __m128 SSE_IntNoise2D( int a_X1, int a_Y1, int a_X2, int a_Y2, int a_X3, int a_Y3, int a_X4, int a_Y4 ) const; +#endif + + __NOISE_INLINE__ float IntNoise( int a_X ) const; + __NOISE_INLINE__ float IntNoise2D( int a_X, int a_Y ) const; + __NOISE_INLINE__ float IntNoise3D( int a_X, int a_Y, int a_Z ) const; + + // Note: These functions have a mod8-irregular chance - each of the mod8 remainders has different chance of occurrence. Divide by 8 to rectify. + __NOISE_INLINE__ int IntNoise1DInt( int a_X ) const; + __NOISE_INLINE__ int IntNoise2DInt( int a_X, int a_Y ) const; + __NOISE_INLINE__ int IntNoise3DInt( int a_X, int a_Y, int a_Z ) const; + + float LinearNoise1D( float a_X ) const; + float CosineNoise1D( float a_X ) const; + float CubicNoise1D( float a_X ) const; + float SmoothNoise1D( int a_X ) const; + + float LinearNoise2D( float a_X, float a_Y ) const; + float CosineNoise2D( float a_X, float a_Y ) const; + float CubicNoise2D( float a_X, float a_Y ) const; + float SSE_CubicNoise2D( float a_X, float a_Y ) const; + + float CosineNoise3D( float a_X, float a_Y, float a_Z ) const; + float CubicNoise3D( float a_X, float a_Y, float a_Z ) const; + + void SetSeed( unsigned int a_Seed ) { m_Seed = a_Seed; } +private: + __NOISE_INLINE__ float CubicInterpolate( float a_A, float a_B, float a_C, float a_D, float a_Pct ) const; + __NOISE_INLINE__ float CosineInterpolate( float a_A, float a_B, float a_Pct ) const; + __NOISE_INLINE__ float LinearInterpolate( float a_A, float a_B, float a_Pct ) const; + +#if NOISE_USE_SSE + __m128 CubicInterpolate4( const __m128 & a_A, const __m128 & a_B, const __m128 & a_C, const __m128 & a_D, float a_Pct ) const; +#endif + + unsigned int m_Seed; +}; + + + + + +#if NOISE_USE_INLINE +# include "cNoise.inc" +#endif + + + + diff --git a/source/cPassiveAggressiveMonster.cpp b/source/cPassiveAggressiveMonster.cpp index 09e7b6a25..946ef86e0 100644 --- a/source/cPassiveAggressiveMonster.cpp +++ b/source/cPassiveAggressiveMonster.cpp @@ -1,38 +1,38 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPassiveAggressiveMonster.h" - -#include "cPlayer.h" - - - - - -cPassiveAggressiveMonster::cPassiveAggressiveMonster() -{ - m_EMPersonality = PASSIVE; -} - -cPassiveAggressiveMonster::~cPassiveAggressiveMonster() -{ -} - -void cPassiveAggressiveMonster::TakeDamage(int a_Damage, cEntity* a_Instigator) -{ - cMonster::TakeDamage(a_Damage, a_Instigator); - if(m_Target->GetEntityType() == cEntity::eEntityType_Player) - { - cPlayer * Player = (cPlayer *) m_Target; - if(Player->GetGameMode() != 1) - { - m_EMState = CHASING; - } - } - -} - -void cPassiveAggressiveMonster::EventSeePlayer(cEntity *a_Entity) -{ - return cMonster::EventSeePlayer(a_Entity); + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPassiveAggressiveMonster.h" + +#include "cPlayer.h" + + + + + +cPassiveAggressiveMonster::cPassiveAggressiveMonster() +{ + m_EMPersonality = PASSIVE; +} + +cPassiveAggressiveMonster::~cPassiveAggressiveMonster() +{ +} + +void cPassiveAggressiveMonster::TakeDamage(int a_Damage, cEntity* a_Instigator) +{ + cMonster::TakeDamage(a_Damage, a_Instigator); + if(m_Target->GetEntityType() == cEntity::eEntityType_Player) + { + cPlayer * Player = (cPlayer *) m_Target; + if(Player->GetGameMode() != 1) + { + m_EMState = CHASING; + } + } + +} + +void cPassiveAggressiveMonster::EventSeePlayer(cEntity *a_Entity) +{ + return cMonster::EventSeePlayer(a_Entity); } \ No newline at end of file diff --git a/source/cPassiveMonster.cpp b/source/cPassiveMonster.cpp index ad6da16f7..7a4bc6979 100644 --- a/source/cPassiveMonster.cpp +++ b/source/cPassiveMonster.cpp @@ -1,46 +1,46 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPassiveMonster.h" -#include "MersenneTwister.h" - - - - - -cPassiveMonster::cPassiveMonster() -{ - m_EMPersonality = PASSIVE; -} - -cPassiveMonster::~cPassiveMonster() -{ -} - -void cPassiveMonster::TakeDamage(int a_Damage, cEntity* a_Instigator) -{ - cMonster::TakeDamage(a_Damage, a_Instigator); - if(a_Instigator != this) - m_EMState = ESCAPING; -} - -void cPassiveMonster::Tick(float a_Dt) -{ - cMonster::Tick(a_Dt); - - m_SeePlayerInterval += a_Dt; - - if(m_SeePlayerInterval > 1) - { - MTRand r1; - int rem = r1.randInt() % 3 + 1; //check most of the time but miss occasionally - - m_SeePlayerInterval = 0.0; - if(rem >= 2) { - if(m_EMState == ESCAPING) - { - CheckEventLostPlayer(); - } - } - } + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPassiveMonster.h" +#include "MersenneTwister.h" + + + + + +cPassiveMonster::cPassiveMonster() +{ + m_EMPersonality = PASSIVE; +} + +cPassiveMonster::~cPassiveMonster() +{ +} + +void cPassiveMonster::TakeDamage(int a_Damage, cEntity* a_Instigator) +{ + cMonster::TakeDamage(a_Damage, a_Instigator); + if(a_Instigator != this) + m_EMState = ESCAPING; +} + +void cPassiveMonster::Tick(float a_Dt) +{ + cMonster::Tick(a_Dt); + + m_SeePlayerInterval += a_Dt; + + if(m_SeePlayerInterval > 1) + { + MTRand r1; + int rem = r1.randInt() % 3 + 1; //check most of the time but miss occasionally + + m_SeePlayerInterval = 0.0; + if(rem >= 2) { + if(m_EMState == ESCAPING) + { + CheckEventLostPlayer(); + } + } + } } \ No newline at end of file diff --git a/source/cPawn.cpp b/source/cPawn.cpp index 986d8904c..0037e56e4 100644 --- a/source/cPawn.cpp +++ b/source/cPawn.cpp @@ -1,252 +1,252 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPawn.h" -#include "cRoot.h" -#include "cServer.h" -#include "cWorld.h" -#include "cPlayer.h" -#include "cPluginManager.h" -#include "Vector3d.h" -#include "BlockID.h" - -#include "Defines.h" - -#include "packets/cPacket_TeleportEntity.h" -#include "packets/cPacket_EntityStatus.h" -#include "packets/cPacket_Metadata.h" - - - - - -CLASS_DEFINITION( cPawn, cEntity ) - - - - - -cPawn::cPawn() - : cEntity( 0, 0, 0 ) - , m_LastPosX( 0.0 ) - , m_LastPosY( 0.0 ) - , m_LastPosZ( 0.0 ) - , m_TimeLastTeleportPacket( 0.f ) - , m_bBurnable(true) - , m_MetaData(NORMAL) - , m_FireDamageInterval(0.f) - , m_BurnPeriod(0.f) -{ - SetMaxHealth(20); - SetMaxFoodLevel(125); -} - - - - - -cPawn::~cPawn() -{ - -} - - - - - -void cPawn::Heal( int a_Health ) -{ - (void)a_Health; -} - - - - - -void cPawn::TakeDamage( int a_Damage, cEntity* a_Instigator ) -{ - TakeDamageInfo TDI; - TDI.Damage = a_Damage; - TDI.Instigator = a_Instigator; - cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_TAKE_DAMAGE, 2, this, &TDI ); - - if( TDI.Damage == 0 ) return; - if( m_Health <= 0 ) return; // Can't take damage if already dead - - m_Health -= (short)TDI.Damage; - if( m_Health < 0 ) m_Health = 0; - - cPacket_EntityStatus Status; - Status.m_UniqueID = GetUniqueID(); - Status.m_Status = cPacket_EntityStatus::STATUS_TAKEDAMAGE; - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, Status); - - if (m_Health <= 0) - { - KilledBy( TDI.Instigator ); - } -} - - - - - -void cPawn::KilledBy( cEntity* a_Killer ) -{ - m_Health = 0; - - if( cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_KILLED, 2, this, a_Killer ) ) - { - return; // Give plugins a chance to 'unkill' the pawn. - } - - cPacket_EntityStatus Status; - Status.m_UniqueID = GetUniqueID(); - Status.m_Status = cPacket_EntityStatus::STATUS_DIE; - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, Status); -} - - - - - -void cPawn::TeleportToEntity( cEntity* a_Entity ) -{ - TeleportTo( a_Entity->GetPosX(), a_Entity->GetPosY(), a_Entity->GetPosZ() ); -} - - - - - -void cPawn::TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ) -{ - SetPosition( a_PosX, a_PosY, a_PosZ ); - - cPacket_TeleportEntity TeleportEntity( this ); - - cRoot::Get()->GetServer()->Broadcast( TeleportEntity ); -} - - - - - -void cPawn::Tick(float a_Dt) -{ - CheckMetaDataBurn(); //Check to see if pawn should burn based on block they are on - - if (GetMetaData() == BURNING) - { - InStateBurning(a_Dt); - } -} - - - - - - -void cPawn::SetMetaData(MetaData a_MetaData) -{ - //Broadcast new status to clients in the chunk - m_MetaData = a_MetaData; - cPacket_Metadata md(a_MetaData, GetUniqueID()); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, md); -} - - - - - -//----Change Entity MetaData -void cPawn::CheckMetaDataBurn() -{ - char Block = GetWorld()->GetBlock((int) m_Pos.x, (int) m_Pos.y, (int) m_Pos.z); - char BlockAbove = GetWorld()->GetBlock((int) m_Pos.x, (int) m_Pos.y + 1, (int) m_Pos.z); - char BlockBelow = GetWorld()->GetBlock((int) m_Pos.x, (int) m_Pos.y - 1, (int) m_Pos.z); - - if ( - (GetMetaData() == BURNING) && - (IsBlockWater(Block) || IsBlockWater(BlockAbove) || IsBlockWater(BlockBelow)) - ) - { - SetMetaData(NORMAL); - } - else if ( - m_bBurnable && - (GetMetaData() != BURNING) && - ( - IsBlockLava(Block) || (Block == E_BLOCK_FIRE) || - IsBlockLava(BlockAbove) || (BlockAbove == E_BLOCK_FIRE) || - IsBlockLava(BlockBelow) || (BlockBelow == E_BLOCK_FIRE) - ) - ) - { - SetMetaData(BURNING); - } -} - - - - - -//What to do if On fire -void cPawn::InStateBurning(float a_Dt) -{ - m_FireDamageInterval += a_Dt; - char Block = GetWorld()->GetBlock( (int)m_Pos.x, (int)m_Pos.y, (int)m_Pos.z ); - char BlockAbove = GetWorld()->GetBlock( (int)m_Pos.x, (int)m_Pos.y + 1, (int)m_Pos.z ); - if (m_FireDamageInterval > 800) - { - - m_FireDamageInterval = 0; - TakeDamage(1, this); - - m_BurnPeriod++; - if (IsBlockLava(Block) || Block == E_BLOCK_FIRE - || IsBlockLava(BlockAbove) || BlockAbove == E_BLOCK_FIRE) - { - m_BurnPeriod = 0; - TakeDamage(6, this); - } - else - { - TakeDamage(1, this); - } - - if (m_BurnPeriod > 7) - { - SetMetaData(NORMAL); - m_BurnPeriod = 0; - } - } -} - - - - - -void cPawn::SetMaxHealth(short a_MaxHealth) -{ - this->m_MaxHealth = a_MaxHealth; - - //Reset health - m_Health = a_MaxHealth; -} - - - - - -void cPawn::SetMaxFoodLevel(short a_MaxFoodLevel) -{ - m_MaxFoodLevel = a_MaxFoodLevel; - - //Reset food level - m_FoodLevel = a_MaxFoodLevel; -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPawn.h" +#include "cRoot.h" +#include "cServer.h" +#include "cWorld.h" +#include "cPlayer.h" +#include "cPluginManager.h" +#include "Vector3d.h" +#include "BlockID.h" + +#include "Defines.h" + +#include "packets/cPacket_TeleportEntity.h" +#include "packets/cPacket_EntityStatus.h" +#include "packets/cPacket_Metadata.h" + + + + + +CLASS_DEFINITION( cPawn, cEntity ) + + + + + +cPawn::cPawn() + : cEntity( 0, 0, 0 ) + , m_LastPosX( 0.0 ) + , m_LastPosY( 0.0 ) + , m_LastPosZ( 0.0 ) + , m_TimeLastTeleportPacket( 0.f ) + , m_bBurnable(true) + , m_MetaData(NORMAL) + , m_FireDamageInterval(0.f) + , m_BurnPeriod(0.f) +{ + SetMaxHealth(20); + SetMaxFoodLevel(125); +} + + + + + +cPawn::~cPawn() +{ + +} + + + + + +void cPawn::Heal( int a_Health ) +{ + (void)a_Health; +} + + + + + +void cPawn::TakeDamage( int a_Damage, cEntity* a_Instigator ) +{ + TakeDamageInfo TDI; + TDI.Damage = a_Damage; + TDI.Instigator = a_Instigator; + cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_TAKE_DAMAGE, 2, this, &TDI ); + + if( TDI.Damage == 0 ) return; + if( m_Health <= 0 ) return; // Can't take damage if already dead + + m_Health -= (short)TDI.Damage; + if( m_Health < 0 ) m_Health = 0; + + cPacket_EntityStatus Status; + Status.m_UniqueID = GetUniqueID(); + Status.m_Status = cPacket_EntityStatus::STATUS_TAKEDAMAGE; + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, Status); + + if (m_Health <= 0) + { + KilledBy( TDI.Instigator ); + } +} + + + + + +void cPawn::KilledBy( cEntity* a_Killer ) +{ + m_Health = 0; + + if( cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_KILLED, 2, this, a_Killer ) ) + { + return; // Give plugins a chance to 'unkill' the pawn. + } + + cPacket_EntityStatus Status; + Status.m_UniqueID = GetUniqueID(); + Status.m_Status = cPacket_EntityStatus::STATUS_DIE; + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, Status); +} + + + + + +void cPawn::TeleportToEntity( cEntity* a_Entity ) +{ + TeleportTo( a_Entity->GetPosX(), a_Entity->GetPosY(), a_Entity->GetPosZ() ); +} + + + + + +void cPawn::TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ) +{ + SetPosition( a_PosX, a_PosY, a_PosZ ); + + cPacket_TeleportEntity TeleportEntity( this ); + + cRoot::Get()->GetServer()->Broadcast( TeleportEntity ); +} + + + + + +void cPawn::Tick(float a_Dt) +{ + CheckMetaDataBurn(); //Check to see if pawn should burn based on block they are on + + if (GetMetaData() == BURNING) + { + InStateBurning(a_Dt); + } +} + + + + + + +void cPawn::SetMetaData(MetaData a_MetaData) +{ + //Broadcast new status to clients in the chunk + m_MetaData = a_MetaData; + cPacket_Metadata md(a_MetaData, GetUniqueID()); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, md); +} + + + + + +//----Change Entity MetaData +void cPawn::CheckMetaDataBurn() +{ + char Block = GetWorld()->GetBlock((int) m_Pos.x, (int) m_Pos.y, (int) m_Pos.z); + char BlockAbove = GetWorld()->GetBlock((int) m_Pos.x, (int) m_Pos.y + 1, (int) m_Pos.z); + char BlockBelow = GetWorld()->GetBlock((int) m_Pos.x, (int) m_Pos.y - 1, (int) m_Pos.z); + + if ( + (GetMetaData() == BURNING) && + (IsBlockWater(Block) || IsBlockWater(BlockAbove) || IsBlockWater(BlockBelow)) + ) + { + SetMetaData(NORMAL); + } + else if ( + m_bBurnable && + (GetMetaData() != BURNING) && + ( + IsBlockLava(Block) || (Block == E_BLOCK_FIRE) || + IsBlockLava(BlockAbove) || (BlockAbove == E_BLOCK_FIRE) || + IsBlockLava(BlockBelow) || (BlockBelow == E_BLOCK_FIRE) + ) + ) + { + SetMetaData(BURNING); + } +} + + + + + +//What to do if On fire +void cPawn::InStateBurning(float a_Dt) +{ + m_FireDamageInterval += a_Dt; + char Block = GetWorld()->GetBlock( (int)m_Pos.x, (int)m_Pos.y, (int)m_Pos.z ); + char BlockAbove = GetWorld()->GetBlock( (int)m_Pos.x, (int)m_Pos.y + 1, (int)m_Pos.z ); + if (m_FireDamageInterval > 800) + { + + m_FireDamageInterval = 0; + TakeDamage(1, this); + + m_BurnPeriod++; + if (IsBlockLava(Block) || Block == E_BLOCK_FIRE + || IsBlockLava(BlockAbove) || BlockAbove == E_BLOCK_FIRE) + { + m_BurnPeriod = 0; + TakeDamage(6, this); + } + else + { + TakeDamage(1, this); + } + + if (m_BurnPeriod > 7) + { + SetMetaData(NORMAL); + m_BurnPeriod = 0; + } + } +} + + + + + +void cPawn::SetMaxHealth(short a_MaxHealth) +{ + this->m_MaxHealth = a_MaxHealth; + + //Reset health + m_Health = a_MaxHealth; +} + + + + + +void cPawn::SetMaxFoodLevel(short a_MaxFoodLevel) +{ + m_MaxFoodLevel = a_MaxFoodLevel; + + //Reset food level + m_FoodLevel = a_MaxFoodLevel; +} + + + + diff --git a/source/cPawn.h b/source/cPawn.h index 11b59575e..2c4444174 100644 --- a/source/cPawn.h +++ b/source/cPawn.h @@ -1,82 +1,82 @@ - -#pragma once - -#include "cEntity.h" - - - - - -struct TakeDamageInfo //tolua_export -{ //tolua_export - int Damage; //tolua_export - cEntity* Instigator; //tolua_export -}; //tolua_export - - - - - -class cPawn : public cEntity //tolua_export -{ //tolua_export -public: - CLASS_PROTOTYPE(); - - cPawn(); - virtual ~cPawn(); - - virtual void TeleportToEntity( cEntity* a_Entity ); //tolua_export - virtual void TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ); //tolua_export - - virtual void Tick(float a_Dt) override; - - void Heal( int a_Health ); //tolua_export - virtual void TakeDamage( int a_Damage, cEntity* a_Instigator ); //tolua_export - virtual void KilledBy( cEntity* a_Killer ); //tolua_export - int GetHealth() { return m_Health; } //tolua_export - - enum MetaData {NORMAL, BURNING, CROUCHED, RIDING, SPRINTING, EATING, BLOCKING}; - - virtual void SetMetaData(MetaData a_MetaData); - virtual MetaData GetMetaData() { return m_MetaData; } - - virtual void InStateBurning(float a_Dt); - - virtual void CheckMetaDataBurn(); - - virtual void SetMaxHealth(short a_MaxHealth); - virtual short GetMaxHealth() { return m_MaxHealth; } - - //virtual void SetMaxFood(short a_MaxFood); - virtual short GetMaxFood() { return m_MaxFoodLevel / 6; } - virtual short GetFood() { return m_FoodLevel / 6; } - - //virtual void SetMaxFoodSaturation(float a_MaxFoodSaturation); - virtual float GetMaxFoodSaturation() { return fmod(m_MaxFoodLevel, 6.f); } - virtual float GetFoodSaturation() { return fmod(m_FoodLevel, 6.f); } - - virtual void SetMaxFoodLevel(short a_MaxFoodLevel); - virtual short GetMaxFoodLevel() { return m_MaxFoodLevel; } - -protected: - - short m_Health; - short m_FoodLevel; - short m_MaxHealth; - short m_MaxFoodLevel; - - bool m_bBurnable; - - MetaData m_MetaData; - - double m_LastPosX, m_LastPosY, m_LastPosZ; - float m_TimeLastTeleportPacket; - - float m_FireDamageInterval; - float m_BurnPeriod; - -}; //tolua_export - - - - + +#pragma once + +#include "cEntity.h" + + + + + +struct TakeDamageInfo //tolua_export +{ //tolua_export + int Damage; //tolua_export + cEntity* Instigator; //tolua_export +}; //tolua_export + + + + + +class cPawn : public cEntity //tolua_export +{ //tolua_export +public: + CLASS_PROTOTYPE(); + + cPawn(); + virtual ~cPawn(); + + virtual void TeleportToEntity( cEntity* a_Entity ); //tolua_export + virtual void TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ); //tolua_export + + virtual void Tick(float a_Dt) override; + + void Heal( int a_Health ); //tolua_export + virtual void TakeDamage( int a_Damage, cEntity* a_Instigator ); //tolua_export + virtual void KilledBy( cEntity* a_Killer ); //tolua_export + int GetHealth() { return m_Health; } //tolua_export + + enum MetaData {NORMAL, BURNING, CROUCHED, RIDING, SPRINTING, EATING, BLOCKING}; + + virtual void SetMetaData(MetaData a_MetaData); + virtual MetaData GetMetaData() { return m_MetaData; } + + virtual void InStateBurning(float a_Dt); + + virtual void CheckMetaDataBurn(); + + virtual void SetMaxHealth(short a_MaxHealth); + virtual short GetMaxHealth() { return m_MaxHealth; } + + //virtual void SetMaxFood(short a_MaxFood); + virtual short GetMaxFood() { return m_MaxFoodLevel / 6; } + virtual short GetFood() { return m_FoodLevel / 6; } + + //virtual void SetMaxFoodSaturation(float a_MaxFoodSaturation); + virtual float GetMaxFoodSaturation() { return fmod(m_MaxFoodLevel, 6.f); } + virtual float GetFoodSaturation() { return fmod(m_FoodLevel, 6.f); } + + virtual void SetMaxFoodLevel(short a_MaxFoodLevel); + virtual short GetMaxFoodLevel() { return m_MaxFoodLevel; } + +protected: + + short m_Health; + short m_FoodLevel; + short m_MaxHealth; + short m_MaxFoodLevel; + + bool m_bBurnable; + + MetaData m_MetaData; + + double m_LastPosX, m_LastPosY, m_LastPosZ; + float m_TimeLastTeleportPacket; + + float m_FireDamageInterval; + float m_BurnPeriod; + +}; //tolua_export + + + + diff --git a/source/cPickup.cpp b/source/cPickup.cpp index 5b35f215f..2302c56a3 100644 --- a/source/cPickup.cpp +++ b/source/cPickup.cpp @@ -1,316 +1,316 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#ifndef _WIN32 -#include -#endif - -#include "cPickup.h" -#include "cClientHandle.h" -#include "cInventory.h" -#include "cWorld.h" -#include "cWaterSimulator.h" -#include "cServer.h" -#include "cPlayer.h" -#include "cPluginManager.h" -#include "cItem.h" -#include "cRoot.h" -#include "cTracer.h" - -#include "packets/cPacket_TeleportEntity.h" -#include "packets/cPacket_PickupSpawn.h" -#include "packets/cPacket_CollectItem.h" - -#include "Vector3d.h" -#include "Vector3f.h" - - - - - -CLASS_DEFINITION( cPickup, cEntity ) - -cPickup::~cPickup() -{ - delete m_Item; -} - -cPickup::cPickup(int a_X, int a_Y, int a_Z, const cItem & a_Item, float a_SpeedX /* = 0.f */, float a_SpeedY /* = 0.f */, float a_SpeedZ /* = 0.f */) - : cEntity( ((double)(a_X))/32, ((double)(a_Y))/32, ((double)(a_Z))/32 ) - , m_Speed( a_SpeedX, a_SpeedY, a_SpeedZ ) - , m_bOnGround( false ) - , m_bReplicated( false ) - , m_Timer( 0.f ) - , m_Item( new cItem( a_Item ) ) - , m_bCollected( false ) -{ - - //LOG("New pickup: ID(%i) Amount(%i) Health(%i)", m_Item.m_ItemID, m_Item.m_ItemCount, m_Item.m_ItemHealth ); - - // Spawn it on clients - if (!a_Item.IsEmpty()) - { - std::auto_ptr PickupSpawn(GetSpawnPacket()); - if (PickupSpawn.get() != NULL) - { - cRoot::Get()->GetServer()->Broadcast(*(PickupSpawn.get())); - } - } - - m_EntityType = eEntityType_Pickup; -} - - - - - -cPickup::cPickup(cPacket_PickupSpawn* a_PickupSpawnPacket) - : cEntity( ((double)a_PickupSpawnPacket->m_PosX)/32, ((double)a_PickupSpawnPacket->m_PosY)/32, ((double)a_PickupSpawnPacket->m_PosZ)/32 ) - , m_Speed( new Vector3f() ) - , m_ResultingSpeed(new Vector3f()) - , m_WaterSpeed(new Vector3f()) - , m_bOnGround( false ) - , m_bReplicated( false ) - , m_Timer( 0.f ) - , m_bCollected( false ) -{ - a_PickupSpawnPacket->m_UniqueID = m_UniqueID; - - m_Item = new cItem(); - m_Item->m_ItemID = (ENUM_ITEM_ID)a_PickupSpawnPacket->m_Item; - m_Item->m_ItemCount = a_PickupSpawnPacket->m_Count; - m_Item->m_ItemHealth = 0x0; - - m_Speed.x = (float)(a_PickupSpawnPacket->m_Rotation) / 8; - m_Speed.y = (float)(a_PickupSpawnPacket->m_Pitch) / 8; - m_Speed.z = (float)(a_PickupSpawnPacket->m_Roll) / 8; - - // Spawn it on clients - if (a_PickupSpawnPacket->m_Item != E_ITEM_EMPTY) - { - cRoot::Get()->GetServer()->Broadcast( *a_PickupSpawnPacket ); - } - - m_EntityType = eEntityType_Pickup; -} - - - - - -cPacket * cPickup::GetSpawnPacket(void) const -{ - if (m_Item->IsEmpty()) - { - return NULL; - } - - cPacket_PickupSpawn * PickupSpawn = new cPacket_PickupSpawn; - PickupSpawn->m_UniqueID = m_UniqueID; - PickupSpawn->m_Item = (short)m_Item->m_ItemID; - PickupSpawn->m_Count = m_Item->m_ItemCount; - PickupSpawn->m_Health = m_Item->m_ItemHealth; - PickupSpawn->m_PosX = (int) (m_Pos.x * 32); - PickupSpawn->m_PosY = (int) (m_Pos.y * 32); - PickupSpawn->m_PosZ = (int) (m_Pos.z * 32); - PickupSpawn->m_Rotation = (char)(m_Speed.x * 8); - PickupSpawn->m_Pitch = (char)(m_Speed.y * 8); - PickupSpawn->m_Roll = (char)(m_Speed.z * 8); - return PickupSpawn; -} - - - - - -void cPickup::Tick(float a_Dt) -{ - m_Timer += a_Dt; - a_Dt = a_Dt / 1000.f; - if(m_bCollected) - { - if(m_Timer > 500.f) // 0.5 second - { - Destroy(); - return; - } - } - - if( m_Timer > 1000*60*5 ) // 5 minutes - { - Destroy(); - return; - } - - if( m_Pos.y < 0 ) // Out of this world! - { - Destroy(); - return; - } - - if(!m_bCollected) - { - HandlePhysics( a_Dt ); - } - - if( !m_bReplicated || m_bDirtyPosition ) - { - MoveToCorrectChunk(); - m_bReplicated = true; - m_bDirtyPosition = false; - cPacket_TeleportEntity TeleportEntity( this ); - GetWorld()->BroadcastToChunk( m_ChunkX, m_ChunkY, m_ChunkZ, TeleportEntity ); - } -} - - - - - -void cPickup::HandlePhysics(float a_Dt) -{ - m_ResultingSpeed.Set(0.f, 0.f, 0.f); - cWorld * World = GetWorld(); - - if( m_bOnGround ) // check if it's still on the ground - { - int BlockX = (m_Pos.x)<0 ? (int)m_Pos.x-1 : (int)m_Pos.x; - int BlockZ = (m_Pos.z)<0 ? (int)m_Pos.z-1 : (int)m_Pos.z; - char BlockBelow = World->GetBlock( BlockX, (int)m_Pos.y -1, BlockZ ); - //Not only air, falls through water ;) - if( BlockBelow == E_BLOCK_AIR || IsBlockWater(BlockBelow)) - { - m_bOnGround = false; - } - char Block = World->GetBlock( BlockX, (int)m_Pos.y - (int)m_bOnGround, BlockZ ); - char BlockIn = World->GetBlock( BlockX, (int)m_Pos.y, BlockZ ); - - if( IsBlockLava(Block) || Block == E_BLOCK_FIRE - || IsBlockLava(BlockIn) || BlockIn == E_BLOCK_FIRE) - { - m_bCollected = true; - m_Timer = 0; - return; - } - - if( BlockIn != E_BLOCK_AIR && !IsBlockWater(BlockIn) ) // If in ground itself, push it out - { - m_bOnGround = true; - m_Pos.y += 0.2; - m_bReplicated = false; - } - m_Speed.x *= 0.7f/(1+a_Dt); - if( fabs(m_Speed.x) < 0.05 ) m_Speed.x = 0; - m_Speed.z *= 0.7f/(1+a_Dt); - if( fabs(m_Speed.z) < 0.05 ) m_Speed.z = 0; - } - - - //get flowing direction - Direction WaterDir = World->GetWaterSimulator()->GetFlowingDirection((int) m_Pos.x - 1, (int) m_Pos.y, (int) m_Pos.z - 1); - - - m_WaterSpeed *= 0.9f; //Keep old speed but lower it - - switch(WaterDir) - { - case X_PLUS: - m_WaterSpeed.x = 1.f; - m_bOnGround = false; - break; - case X_MINUS: - m_WaterSpeed.x = -1.f; - m_bOnGround = false; - break; - case Z_PLUS: - m_WaterSpeed.z = 1.f; - m_bOnGround = false; - break; - case Z_MINUS: - m_WaterSpeed.z = -1.f; - m_bOnGround = false; - break; - - default: - break; - } - - m_ResultingSpeed += m_WaterSpeed; - - - if( !m_bOnGround ) - { - - float Gravity = -9.81f*a_Dt; - m_Speed.y += Gravity; - - // Set to hit position - m_ResultingSpeed += m_Speed; - - cTracer Tracer( GetWorld() ); - int Ret = Tracer.Trace( m_Pos, m_Speed, 2 ); - if( Ret ) // Oh noez! we hit something - { - - - if( (Tracer.RealHit - Vector3f(m_Pos)).SqrLength() <= ( m_ResultingSpeed * a_Dt ).SqrLength() ) - { - m_bReplicated = false; // It's only interesting to replicate when we actually hit something... - if( Ret == 1 ) - { - - if( Tracer.HitNormal.x != 0.f ) m_Speed.x = 0.f; - if( Tracer.HitNormal.y != 0.f ) m_Speed.y = 0.f; - if( Tracer.HitNormal.z != 0.f ) m_Speed.z = 0.f; - - if( Tracer.HitNormal.y > 0 ) // means on ground - { - m_bOnGround = true; - } - } - m_Pos = Tracer.RealHit; - m_Pos += Tracer.HitNormal * 0.2f; - - } - else - m_Pos += m_ResultingSpeed*a_Dt; - } - else - { // We didn't hit anything, so move =] - m_Pos += m_ResultingSpeed * a_Dt; - } - } - //Usable for debugging - //SetPosition(m_Pos.x, m_Pos.y, m_Pos.z); -} - - - - - -bool cPickup::CollectedBy( cPlayer* a_Dest ) -{ - if(m_bCollected) return false; // It's already collected! - // 800 is to long - if(m_Timer < 500.f) return false; // Not old enough - - if( cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_COLLECT_ITEM, 2, this, a_Dest ) ) return false; - - if( a_Dest->GetInventory().AddItem( *m_Item ) ) - { - cPacket_CollectItem CollectItem; - CollectItem.m_CollectedID = m_UniqueID; - CollectItem.m_CollectorID = a_Dest->GetUniqueID(); - cRoot::Get()->GetServer()->Broadcast( CollectItem ); - - m_bCollected = true; - m_Timer = 0; - return true; - } - - return false; -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#ifndef _WIN32 +#include +#endif + +#include "cPickup.h" +#include "cClientHandle.h" +#include "cInventory.h" +#include "cWorld.h" +#include "cWaterSimulator.h" +#include "cServer.h" +#include "cPlayer.h" +#include "cPluginManager.h" +#include "cItem.h" +#include "cRoot.h" +#include "cTracer.h" + +#include "packets/cPacket_TeleportEntity.h" +#include "packets/cPacket_PickupSpawn.h" +#include "packets/cPacket_CollectItem.h" + +#include "Vector3d.h" +#include "Vector3f.h" + + + + + +CLASS_DEFINITION( cPickup, cEntity ) + +cPickup::~cPickup() +{ + delete m_Item; +} + +cPickup::cPickup(int a_X, int a_Y, int a_Z, const cItem & a_Item, float a_SpeedX /* = 0.f */, float a_SpeedY /* = 0.f */, float a_SpeedZ /* = 0.f */) + : cEntity( ((double)(a_X))/32, ((double)(a_Y))/32, ((double)(a_Z))/32 ) + , m_Speed( a_SpeedX, a_SpeedY, a_SpeedZ ) + , m_bOnGround( false ) + , m_bReplicated( false ) + , m_Timer( 0.f ) + , m_Item( new cItem( a_Item ) ) + , m_bCollected( false ) +{ + + //LOG("New pickup: ID(%i) Amount(%i) Health(%i)", m_Item.m_ItemID, m_Item.m_ItemCount, m_Item.m_ItemHealth ); + + // Spawn it on clients + if (!a_Item.IsEmpty()) + { + std::auto_ptr PickupSpawn(GetSpawnPacket()); + if (PickupSpawn.get() != NULL) + { + cRoot::Get()->GetServer()->Broadcast(*(PickupSpawn.get())); + } + } + + m_EntityType = eEntityType_Pickup; +} + + + + + +cPickup::cPickup(cPacket_PickupSpawn* a_PickupSpawnPacket) + : cEntity( ((double)a_PickupSpawnPacket->m_PosX)/32, ((double)a_PickupSpawnPacket->m_PosY)/32, ((double)a_PickupSpawnPacket->m_PosZ)/32 ) + , m_Speed( new Vector3f() ) + , m_ResultingSpeed(new Vector3f()) + , m_WaterSpeed(new Vector3f()) + , m_bOnGround( false ) + , m_bReplicated( false ) + , m_Timer( 0.f ) + , m_bCollected( false ) +{ + a_PickupSpawnPacket->m_UniqueID = m_UniqueID; + + m_Item = new cItem(); + m_Item->m_ItemID = (ENUM_ITEM_ID)a_PickupSpawnPacket->m_Item; + m_Item->m_ItemCount = a_PickupSpawnPacket->m_Count; + m_Item->m_ItemHealth = 0x0; + + m_Speed.x = (float)(a_PickupSpawnPacket->m_Rotation) / 8; + m_Speed.y = (float)(a_PickupSpawnPacket->m_Pitch) / 8; + m_Speed.z = (float)(a_PickupSpawnPacket->m_Roll) / 8; + + // Spawn it on clients + if (a_PickupSpawnPacket->m_Item != E_ITEM_EMPTY) + { + cRoot::Get()->GetServer()->Broadcast( *a_PickupSpawnPacket ); + } + + m_EntityType = eEntityType_Pickup; +} + + + + + +cPacket * cPickup::GetSpawnPacket(void) const +{ + if (m_Item->IsEmpty()) + { + return NULL; + } + + cPacket_PickupSpawn * PickupSpawn = new cPacket_PickupSpawn; + PickupSpawn->m_UniqueID = m_UniqueID; + PickupSpawn->m_Item = (short)m_Item->m_ItemID; + PickupSpawn->m_Count = m_Item->m_ItemCount; + PickupSpawn->m_Health = m_Item->m_ItemHealth; + PickupSpawn->m_PosX = (int) (m_Pos.x * 32); + PickupSpawn->m_PosY = (int) (m_Pos.y * 32); + PickupSpawn->m_PosZ = (int) (m_Pos.z * 32); + PickupSpawn->m_Rotation = (char)(m_Speed.x * 8); + PickupSpawn->m_Pitch = (char)(m_Speed.y * 8); + PickupSpawn->m_Roll = (char)(m_Speed.z * 8); + return PickupSpawn; +} + + + + + +void cPickup::Tick(float a_Dt) +{ + m_Timer += a_Dt; + a_Dt = a_Dt / 1000.f; + if(m_bCollected) + { + if(m_Timer > 500.f) // 0.5 second + { + Destroy(); + return; + } + } + + if( m_Timer > 1000*60*5 ) // 5 minutes + { + Destroy(); + return; + } + + if( m_Pos.y < 0 ) // Out of this world! + { + Destroy(); + return; + } + + if(!m_bCollected) + { + HandlePhysics( a_Dt ); + } + + if( !m_bReplicated || m_bDirtyPosition ) + { + MoveToCorrectChunk(); + m_bReplicated = true; + m_bDirtyPosition = false; + cPacket_TeleportEntity TeleportEntity( this ); + GetWorld()->BroadcastToChunk( m_ChunkX, m_ChunkY, m_ChunkZ, TeleportEntity ); + } +} + + + + + +void cPickup::HandlePhysics(float a_Dt) +{ + m_ResultingSpeed.Set(0.f, 0.f, 0.f); + cWorld * World = GetWorld(); + + if( m_bOnGround ) // check if it's still on the ground + { + int BlockX = (m_Pos.x)<0 ? (int)m_Pos.x-1 : (int)m_Pos.x; + int BlockZ = (m_Pos.z)<0 ? (int)m_Pos.z-1 : (int)m_Pos.z; + char BlockBelow = World->GetBlock( BlockX, (int)m_Pos.y -1, BlockZ ); + //Not only air, falls through water ;) + if( BlockBelow == E_BLOCK_AIR || IsBlockWater(BlockBelow)) + { + m_bOnGround = false; + } + char Block = World->GetBlock( BlockX, (int)m_Pos.y - (int)m_bOnGround, BlockZ ); + char BlockIn = World->GetBlock( BlockX, (int)m_Pos.y, BlockZ ); + + if( IsBlockLava(Block) || Block == E_BLOCK_FIRE + || IsBlockLava(BlockIn) || BlockIn == E_BLOCK_FIRE) + { + m_bCollected = true; + m_Timer = 0; + return; + } + + if( BlockIn != E_BLOCK_AIR && !IsBlockWater(BlockIn) ) // If in ground itself, push it out + { + m_bOnGround = true; + m_Pos.y += 0.2; + m_bReplicated = false; + } + m_Speed.x *= 0.7f/(1+a_Dt); + if( fabs(m_Speed.x) < 0.05 ) m_Speed.x = 0; + m_Speed.z *= 0.7f/(1+a_Dt); + if( fabs(m_Speed.z) < 0.05 ) m_Speed.z = 0; + } + + + //get flowing direction + Direction WaterDir = World->GetWaterSimulator()->GetFlowingDirection((int) m_Pos.x - 1, (int) m_Pos.y, (int) m_Pos.z - 1); + + + m_WaterSpeed *= 0.9f; //Keep old speed but lower it + + switch(WaterDir) + { + case X_PLUS: + m_WaterSpeed.x = 1.f; + m_bOnGround = false; + break; + case X_MINUS: + m_WaterSpeed.x = -1.f; + m_bOnGround = false; + break; + case Z_PLUS: + m_WaterSpeed.z = 1.f; + m_bOnGround = false; + break; + case Z_MINUS: + m_WaterSpeed.z = -1.f; + m_bOnGround = false; + break; + + default: + break; + } + + m_ResultingSpeed += m_WaterSpeed; + + + if( !m_bOnGround ) + { + + float Gravity = -9.81f*a_Dt; + m_Speed.y += Gravity; + + // Set to hit position + m_ResultingSpeed += m_Speed; + + cTracer Tracer( GetWorld() ); + int Ret = Tracer.Trace( m_Pos, m_Speed, 2 ); + if( Ret ) // Oh noez! we hit something + { + + + if( (Tracer.RealHit - Vector3f(m_Pos)).SqrLength() <= ( m_ResultingSpeed * a_Dt ).SqrLength() ) + { + m_bReplicated = false; // It's only interesting to replicate when we actually hit something... + if( Ret == 1 ) + { + + if( Tracer.HitNormal.x != 0.f ) m_Speed.x = 0.f; + if( Tracer.HitNormal.y != 0.f ) m_Speed.y = 0.f; + if( Tracer.HitNormal.z != 0.f ) m_Speed.z = 0.f; + + if( Tracer.HitNormal.y > 0 ) // means on ground + { + m_bOnGround = true; + } + } + m_Pos = Tracer.RealHit; + m_Pos += Tracer.HitNormal * 0.2f; + + } + else + m_Pos += m_ResultingSpeed*a_Dt; + } + else + { // We didn't hit anything, so move =] + m_Pos += m_ResultingSpeed * a_Dt; + } + } + //Usable for debugging + //SetPosition(m_Pos.x, m_Pos.y, m_Pos.z); +} + + + + + +bool cPickup::CollectedBy( cPlayer* a_Dest ) +{ + if(m_bCollected) return false; // It's already collected! + // 800 is to long + if(m_Timer < 500.f) return false; // Not old enough + + if( cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_COLLECT_ITEM, 2, this, a_Dest ) ) return false; + + if( a_Dest->GetInventory().AddItem( *m_Item ) ) + { + cPacket_CollectItem CollectItem; + CollectItem.m_CollectedID = m_UniqueID; + CollectItem.m_CollectorID = a_Dest->GetUniqueID(); + cRoot::Get()->GetServer()->Broadcast( CollectItem ); + + m_bCollected = true; + m_Timer = 0; + return true; + } + + return false; +} + + + + diff --git a/source/cPickup.h b/source/cPickup.h index 26bce5029..a13767738 100644 --- a/source/cPickup.h +++ b/source/cPickup.h @@ -1,53 +1,53 @@ - -#pragma once - -#include "cEntity.h" - - - - -class cPacket_PickupSpawn; -class cPlayer; -class cItem; - - - - - -class cPickup : public cEntity //tolua_export -{ //tolua_export -public: - CLASS_PROTOTYPE(); - - cPickup(int a_X, int a_Y, int a_Z, const cItem & a_Item, float a_SpeedX = 0.f, float a_SpeedY = 0.f, float a_SpeedZ = 0.f); //tolua_export - cPickup(cPacket_PickupSpawn * a_PickupSpawnPacket); //tolua_export - ~cPickup(); //tolua_export - - cItem * GetItem() { return m_Item; } //tolua_export - - virtual cPacket * GetSpawnPacket(void) const override; - - virtual bool CollectedBy( cPlayer* a_Dest ); //tolua_export - - void Tick(float a_Dt); - void HandlePhysics(float a_Dt); - -private: - - Vector3f m_Speed; - Vector3f m_ResultingSpeed; //Can be used to modify the resulting speed for the current tick ;) - - Vector3f m_WaterSpeed; - bool m_bOnGround; - bool m_bReplicated; - - float m_Timer; - - cItem* m_Item; - - bool m_bCollected; -}; //tolua_export - - - - + +#pragma once + +#include "cEntity.h" + + + + +class cPacket_PickupSpawn; +class cPlayer; +class cItem; + + + + + +class cPickup : public cEntity //tolua_export +{ //tolua_export +public: + CLASS_PROTOTYPE(); + + cPickup(int a_X, int a_Y, int a_Z, const cItem & a_Item, float a_SpeedX = 0.f, float a_SpeedY = 0.f, float a_SpeedZ = 0.f); //tolua_export + cPickup(cPacket_PickupSpawn * a_PickupSpawnPacket); //tolua_export + ~cPickup(); //tolua_export + + cItem * GetItem() { return m_Item; } //tolua_export + + virtual cPacket * GetSpawnPacket(void) const override; + + virtual bool CollectedBy( cPlayer* a_Dest ); //tolua_export + + void Tick(float a_Dt); + void HandlePhysics(float a_Dt); + +private: + + Vector3f m_Speed; + Vector3f m_ResultingSpeed; //Can be used to modify the resulting speed for the current tick ;) + + Vector3f m_WaterSpeed; + bool m_bOnGround; + bool m_bReplicated; + + float m_Timer; + + cItem* m_Item; + + bool m_bCollected; +}; //tolua_export + + + + diff --git a/source/cPig.cpp b/source/cPig.cpp index 2654b41cf..14a713954 100644 --- a/source/cPig.cpp +++ b/source/cPig.cpp @@ -1,51 +1,51 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPig.h" - - - - - -cPig::cPig() -{ - m_MobType = 90; - GetMonsterConfig("Pig"); -} - - - - - -cPig::~cPig() -{ -} - - - - - -bool cPig::IsA( const char* a_EntityType ) -{ - if( strcmp( a_EntityType, "cPig" ) == 0 ) return true; - return cMonster::IsA( a_EntityType ); -} - - - - - -void cPig::KilledBy( cEntity* a_Killer ) -{ - cItems Drops; - AddRandomDropItem(Drops, 0, 2, E_ITEM_RAW_MEAT); - m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); - - // TODO: Check for burning state - - cMonster::KilledBy( a_Killer ); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPig.h" + + + + + +cPig::cPig() +{ + m_MobType = 90; + GetMonsterConfig("Pig"); +} + + + + + +cPig::~cPig() +{ +} + + + + + +bool cPig::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cPig" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cPig::KilledBy( cEntity* a_Killer ) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_RAW_MEAT); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + // TODO: Check for burning state + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cPig.h b/source/cPig.h index 32947c2c1..481aa2969 100644 --- a/source/cPig.h +++ b/source/cPig.h @@ -1,14 +1,14 @@ -#pragma once - -#include "cPassiveMonster.h" - -class cPig : public cPassiveMonster -{ -public: - cPig(); - ~cPig(); - - virtual bool IsA( const char* a_EntityType ); - - virtual void KilledBy( cEntity* a_Killer ); -}; +#pragma once + +#include "cPassiveMonster.h" + +class cPig : public cPassiveMonster +{ +public: + cPig(); + ~cPig(); + + virtual bool IsA( const char* a_EntityType ); + + virtual void KilledBy( cEntity* a_Killer ); +}; diff --git a/source/cPiston.cpp b/source/cPiston.cpp index c89fb5077..8cf463c1b 100644 --- a/source/cPiston.cpp +++ b/source/cPiston.cpp @@ -1,165 +1,165 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPiston.h" -#include "cRedstone.h" -#include "ChunkDef.h" -#include "cPickup.h" -#include "cBlockToPickup.h" -#include "cItem.h" -#include "cRoot.h" -#include "cClientHandle.h" -#include "cWorld.h" -#include "BlockID.h" -#include "packets/cPacket_BlockAction.h" -#include "cServer.h" - -extern bool g_BlockPistonBreakable[]; - -#define AddDir( x, y, z, dir, amount ) switch(dir) { case 0: (y)-=(amount); break; case 1: (y)+=(amount); break;\ - case 2: (z)-=(amount); break; case 3: (z)+=(amount); break;\ - case 4: (x)-=(amount); break; case 5: (x)+=(amount); break; } - - - - - -cPiston::cPiston( cWorld* a_World ) - :m_World ( a_World ) -{ - -} - -unsigned short cPiston::FirstPassthroughBlock( int pistonX, int pistonY, int pistonZ, char pistonmeta ) { - unsigned short ret; - pistonmeta &= 7; - if(pistonmeta >= 6) { // just in case, it shouldn't happen but if it would, it'd case inf loop - printf("cPiston::FirstPassthroughBlock - piston has invalid meta data!\n"); - return 9001; - } - char currBlock; - for( ret = 0; ret < 24; ret++ ) { // push up to 24 blocks - AddDir( pistonX, pistonY, pistonZ, pistonmeta, 1 ) - currBlock = m_World->GetBlock( pistonX, pistonY, pistonZ ); - if(currBlock == E_BLOCK_BEDROCK || currBlock == E_BLOCK_OBSIDIAN || currBlock == E_BLOCK_PISTON_EXTENSION ) {return 9001;} - if(g_BlockPistonBreakable[currBlock]) {return ret;} - } - return 9001; -} - - - - - -void cPiston::ExtendPiston( int pistx, int pisty, int pistz ) -{ - char pistonBlock = m_World->GetBlock( pistx, pisty, pistz ); - char pistonMeta = m_World->GetBlockMeta( pistx, pisty, pistz ); - char isSticky = (char)(pistonBlock == E_BLOCK_STICKY_PISTON) * 8; - bool recalc = false; - if ( (pistonMeta & 0x8) == 0x0 ) // only extend if piston is not already extended - { - unsigned short dist = FirstPassthroughBlock(pistx, pisty, pistz, pistonMeta); - if (dist > 9000) return; // too many blocks - - AddDir( pistx, pisty, pistz, pistonMeta & 7, dist+1 ) - BLOCKTYPE currBlock = m_World->GetBlock (pistx, pisty, pistz); - NIBBLETYPE currMeta = m_World->GetBlockMeta(pistx, pisty, pistz); - if (currBlock != E_BLOCK_AIR) - { - cItems PickupItems; - cBlockToPickup::ToPickup(currBlock, currMeta, E_ITEM_EMPTY, PickupItems); - m_World->SpawnItemPickups(PickupItems, pistx, pisty, pistz); - recalc = true; - } - int oldx = pistx, oldy = pisty, oldz = pistz; - char currBlockMeta; - for (int i = dist+1; i>0; i--) - { - AddDir( pistx, pisty, pistz, pistonMeta & 7, -1 ) - currBlock = m_World->GetBlock( pistx, pisty, pistz ); - currBlockMeta = m_World->GetBlockMeta( pistx, pisty, pistz ); - m_World->SetBlock( oldx, oldy, oldz, currBlock, currBlockMeta ); - oldx = pistx; - oldy = pisty; - oldz = pistz; - } - cPacket_BlockAction Action; - Action.m_PosX = (int)pistx; - Action.m_PosY = (short)pisty; - Action.m_PosZ = (int)pistz; - Action.m_Byte1 = 0; - Action.m_Byte2 = pistonMeta; - - m_World->BroadcastToChunkOfBlock(pistx, pisty, pistz, &Action); - m_World->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta | 0x8 ); - - int extx = pistx; - int exty = pisty; - int extz = pistz; - - AddDir( extx, exty, extz, pistonMeta&7, 1 ) - - m_World->SetBlock( extx, exty, extz, E_BLOCK_PISTON_EXTENSION, isSticky+pistonMeta&7 ); - - if (recalc) { - cRedstone Redstone(m_World); - Redstone.ChangeRedstone( extx, exty, extz, false ); //recalculate redstone around current device. - Redstone.ChangeRedstone( pistx, pisty, pistz, false ); //recalculate redstone around current device. - } - } -} - - - - - -void cPiston::RetractPiston( int pistx, int pisty, int pistz ) -{ - char pistonBlock = m_World->GetBlock( pistx, pisty, pistz ); - char pistonMeta = m_World->GetBlockMeta( pistx, pisty, pistz ); - if (pistonMeta <= 6) // only retract if piston is not already retracted - { - return; - } - - //send blockaction packet - cPacket_BlockAction Action; - Action.m_PosX = (int)pistx; - Action.m_PosY = (short)pisty; - Action.m_PosZ = (int)pistz; - Action.m_Byte1 = 1; - Action.m_Byte2 = pistonMeta & ~(8); - m_World->BroadcastToChunkOfBlock(pistx, pisty, pistz, &Action ); - m_World->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta & ~(8) ); - - AddDir( pistx, pisty, pistz, pistonMeta & 7, 1 ) - if ( m_World->GetBlock( pistx, pisty, pistz ) == E_BLOCK_PISTON_EXTENSION ) - { - if ( pistonBlock == E_BLOCK_STICKY_PISTON ) - { - int tempx = pistx, tempy = pisty, tempz = pistz; - AddDir( tempx, tempy, tempz, pistonMeta & 7, 1 ) - char tempblock = m_World->GetBlock( tempx, tempy, tempz ); - if ( - (tempblock == E_BLOCK_OBSIDIAN) || - (tempblock == E_BLOCK_BEDROCK) || - (tempblock == E_BLOCK_PISTON_EXTENSION) - ) - { - // These cannot be moved by the sticky piston, bail out - return; - } - m_World->SetBlock( pistx, pisty, pistz, tempblock, m_World->GetBlockMeta( tempx, tempy, tempz ) ); - m_World->SetBlock( tempx, tempy, tempz, E_BLOCK_AIR, 0 ); - } - else - { - m_World->SetBlock( pistx, pisty, pistz, E_BLOCK_AIR, 0 ); - } - } -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPiston.h" +#include "cRedstone.h" +#include "ChunkDef.h" +#include "cPickup.h" +#include "cBlockToPickup.h" +#include "cItem.h" +#include "cRoot.h" +#include "cClientHandle.h" +#include "cWorld.h" +#include "BlockID.h" +#include "packets/cPacket_BlockAction.h" +#include "cServer.h" + +extern bool g_BlockPistonBreakable[]; + +#define AddDir( x, y, z, dir, amount ) switch(dir) { case 0: (y)-=(amount); break; case 1: (y)+=(amount); break;\ + case 2: (z)-=(amount); break; case 3: (z)+=(amount); break;\ + case 4: (x)-=(amount); break; case 5: (x)+=(amount); break; } + + + + + +cPiston::cPiston( cWorld* a_World ) + :m_World ( a_World ) +{ + +} + +unsigned short cPiston::FirstPassthroughBlock( int pistonX, int pistonY, int pistonZ, char pistonmeta ) { + unsigned short ret; + pistonmeta &= 7; + if(pistonmeta >= 6) { // just in case, it shouldn't happen but if it would, it'd case inf loop + printf("cPiston::FirstPassthroughBlock - piston has invalid meta data!\n"); + return 9001; + } + char currBlock; + for( ret = 0; ret < 24; ret++ ) { // push up to 24 blocks + AddDir( pistonX, pistonY, pistonZ, pistonmeta, 1 ) + currBlock = m_World->GetBlock( pistonX, pistonY, pistonZ ); + if(currBlock == E_BLOCK_BEDROCK || currBlock == E_BLOCK_OBSIDIAN || currBlock == E_BLOCK_PISTON_EXTENSION ) {return 9001;} + if(g_BlockPistonBreakable[currBlock]) {return ret;} + } + return 9001; +} + + + + + +void cPiston::ExtendPiston( int pistx, int pisty, int pistz ) +{ + char pistonBlock = m_World->GetBlock( pistx, pisty, pistz ); + char pistonMeta = m_World->GetBlockMeta( pistx, pisty, pistz ); + char isSticky = (char)(pistonBlock == E_BLOCK_STICKY_PISTON) * 8; + bool recalc = false; + if ( (pistonMeta & 0x8) == 0x0 ) // only extend if piston is not already extended + { + unsigned short dist = FirstPassthroughBlock(pistx, pisty, pistz, pistonMeta); + if (dist > 9000) return; // too many blocks + + AddDir( pistx, pisty, pistz, pistonMeta & 7, dist+1 ) + BLOCKTYPE currBlock = m_World->GetBlock (pistx, pisty, pistz); + NIBBLETYPE currMeta = m_World->GetBlockMeta(pistx, pisty, pistz); + if (currBlock != E_BLOCK_AIR) + { + cItems PickupItems; + cBlockToPickup::ToPickup(currBlock, currMeta, E_ITEM_EMPTY, PickupItems); + m_World->SpawnItemPickups(PickupItems, pistx, pisty, pistz); + recalc = true; + } + int oldx = pistx, oldy = pisty, oldz = pistz; + char currBlockMeta; + for (int i = dist+1; i>0; i--) + { + AddDir( pistx, pisty, pistz, pistonMeta & 7, -1 ) + currBlock = m_World->GetBlock( pistx, pisty, pistz ); + currBlockMeta = m_World->GetBlockMeta( pistx, pisty, pistz ); + m_World->SetBlock( oldx, oldy, oldz, currBlock, currBlockMeta ); + oldx = pistx; + oldy = pisty; + oldz = pistz; + } + cPacket_BlockAction Action; + Action.m_PosX = (int)pistx; + Action.m_PosY = (short)pisty; + Action.m_PosZ = (int)pistz; + Action.m_Byte1 = 0; + Action.m_Byte2 = pistonMeta; + + m_World->BroadcastToChunkOfBlock(pistx, pisty, pistz, &Action); + m_World->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta | 0x8 ); + + int extx = pistx; + int exty = pisty; + int extz = pistz; + + AddDir( extx, exty, extz, pistonMeta&7, 1 ) + + m_World->SetBlock( extx, exty, extz, E_BLOCK_PISTON_EXTENSION, isSticky+pistonMeta&7 ); + + if (recalc) { + cRedstone Redstone(m_World); + Redstone.ChangeRedstone( extx, exty, extz, false ); //recalculate redstone around current device. + Redstone.ChangeRedstone( pistx, pisty, pistz, false ); //recalculate redstone around current device. + } + } +} + + + + + +void cPiston::RetractPiston( int pistx, int pisty, int pistz ) +{ + char pistonBlock = m_World->GetBlock( pistx, pisty, pistz ); + char pistonMeta = m_World->GetBlockMeta( pistx, pisty, pistz ); + if (pistonMeta <= 6) // only retract if piston is not already retracted + { + return; + } + + //send blockaction packet + cPacket_BlockAction Action; + Action.m_PosX = (int)pistx; + Action.m_PosY = (short)pisty; + Action.m_PosZ = (int)pistz; + Action.m_Byte1 = 1; + Action.m_Byte2 = pistonMeta & ~(8); + m_World->BroadcastToChunkOfBlock(pistx, pisty, pistz, &Action ); + m_World->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta & ~(8) ); + + AddDir( pistx, pisty, pistz, pistonMeta & 7, 1 ) + if ( m_World->GetBlock( pistx, pisty, pistz ) == E_BLOCK_PISTON_EXTENSION ) + { + if ( pistonBlock == E_BLOCK_STICKY_PISTON ) + { + int tempx = pistx, tempy = pisty, tempz = pistz; + AddDir( tempx, tempy, tempz, pistonMeta & 7, 1 ) + char tempblock = m_World->GetBlock( tempx, tempy, tempz ); + if ( + (tempblock == E_BLOCK_OBSIDIAN) || + (tempblock == E_BLOCK_BEDROCK) || + (tempblock == E_BLOCK_PISTON_EXTENSION) + ) + { + // These cannot be moved by the sticky piston, bail out + return; + } + m_World->SetBlock( pistx, pisty, pistz, tempblock, m_World->GetBlockMeta( tempx, tempy, tempz ) ); + m_World->SetBlock( tempx, tempy, tempz, E_BLOCK_AIR, 0 ); + } + else + { + m_World->SetBlock( pistx, pisty, pistz, E_BLOCK_AIR, 0 ); + } + } +} + + + + diff --git a/source/cPiston.h b/source/cPiston.h index 54111f9d6..d74f0c0a4 100644 --- a/source/cPiston.h +++ b/source/cPiston.h @@ -1,60 +1,60 @@ - -#pragma once - - - - - -// fwd: "cWorld.h" -class cWorld; - - - - - -class cPiston -{ -public: - - cPiston( cWorld* a_World ); - - static char RotationPitchToMetaData( float a_Rotation, float a_Pitch ) - { - LOG("pre:a_Rotation %f \n",a_Rotation); - LOG("a_Pitch %f \n",a_Pitch); - - if (a_Pitch >= 50.f ){ - return 0x1; - } else if ( a_Pitch <= -50.f ) { - return 0x0; - } else { - - a_Rotation += 90 + 45; // So its not aligned with axis - std::printf("a_Rotation %f \n",a_Rotation); - - if( a_Rotation > 360.f ) a_Rotation -= 360.f; - if( a_Rotation >= 0.f && a_Rotation < 90.f ) - { LOG("1111\n");return 0x4;} - else if( a_Rotation >= 180 && a_Rotation < 270 ) - { LOG("2222\n");return 0x5;} - else if( a_Rotation >= 90 && a_Rotation < 180 ) - { LOG("3333\n");return 0x2;} - else - { LOG("4444\n");return 0x3;} - } - } - - void ExtendPiston( int, int, int ); - void RetractPiston( int, int, int ); - - cWorld* m_World; - -private: - void ChainMove( int, int, int, char, unsigned short * ); - unsigned short FirstPassthroughBlock( int, int, int, char ); - -}; - - - - + +#pragma once + + + + + +// fwd: "cWorld.h" +class cWorld; + + + + + +class cPiston +{ +public: + + cPiston( cWorld* a_World ); + + static char RotationPitchToMetaData( float a_Rotation, float a_Pitch ) + { + LOG("pre:a_Rotation %f \n",a_Rotation); + LOG("a_Pitch %f \n",a_Pitch); + + if (a_Pitch >= 50.f ){ + return 0x1; + } else if ( a_Pitch <= -50.f ) { + return 0x0; + } else { + + a_Rotation += 90 + 45; // So its not aligned with axis + std::printf("a_Rotation %f \n",a_Rotation); + + if( a_Rotation > 360.f ) a_Rotation -= 360.f; + if( a_Rotation >= 0.f && a_Rotation < 90.f ) + { LOG("1111\n");return 0x4;} + else if( a_Rotation >= 180 && a_Rotation < 270 ) + { LOG("2222\n");return 0x5;} + else if( a_Rotation >= 90 && a_Rotation < 180 ) + { LOG("3333\n");return 0x2;} + else + { LOG("4444\n");return 0x3;} + } + } + + void ExtendPiston( int, int, int ); + void RetractPiston( int, int, int ); + + cWorld* m_World; + +private: + void ChainMove( int, int, int, char, unsigned short * ); + unsigned short FirstPassthroughBlock( int, int, int, char ); + +}; + + + + diff --git a/source/cPlayer.cpp b/source/cPlayer.cpp index 60ae9f888..a7159b2cf 100644 --- a/source/cPlayer.cpp +++ b/source/cPlayer.cpp @@ -1,1062 +1,1062 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPlayer.h" -#include "cServer.h" -#include "cCreativeInventory.h" -#include "cSurvivalInventory.h" -#include "cClientHandle.h" -#include "cWorld.h" -#include "cPickup.h" -#include "cPluginManager.h" -#include "cWindow.h" -#include "cBlockEntity.h" -#include "cGroupManager.h" -#include "cGroup.h" -#include "cChatColor.h" -#include "cItem.h" -#include "cTracer.h" -#include "cRoot.h" -#include "cMakeDir.h" -#include "cTimer.h" -#include "MersenneTwister.h" - -#include "packets/cPacket_NamedEntitySpawn.h" -#include "packets/cPacket_EntityLook.h" -#include "packets/cPacket_TeleportEntity.h" -#include "packets/cPacket_RelativeEntityMove.h" -#include "packets/cPacket_RelativeEntityMoveLook.h" -#include "packets/cPacket_UpdateHealth.h" -#include "packets/cPacket_Respawn.h" -#include "packets/cPacket_DestroyEntity.h" -#include "packets/cPacket_Metadata.h" -#include "packets/cPacket_Chat.h" -#include "packets/cPacket_NewInvalidState.h" -#include "packets/cPacket_BlockAction.h" - -#include "Vector3d.h" -#include "Vector3f.h" - -#include "../iniFile/iniFile.h" -#include - -#define float2int(x) ((x)<0 ? ((int)(x))-1 : (int)(x)) - - - - - -CLASS_DEFINITION( cPlayer, cPawn ); - - - - - -cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) - : m_GameMode( eGameMode_Survival ) - , m_IP("") - , m_LastBlockActionTime( 0 ) - , m_LastBlockActionCnt( 0 ) - , m_bVisible( true ) - , m_LastGroundHeight( 0 ) - , m_bTouchGround( false ) - , m_Stance( 0.0 ) - , m_Inventory( 0 ) - , m_CurrentWindow( 0 ) - , m_TimeLastPickupCheck( 0.f ) - , m_Color('-') - , m_ClientHandle( a_Client ) -{ - LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d", - a_PlayerName.c_str(), a_Client->GetSocket().GetIPString().c_str(), - this, GetUniqueID() - ); - m_EntityType = eEntityType_Player; - SetMaxHealth(20); - SetMaxFoodLevel(125); - m_Inventory = new cSurvivalInventory( this ); - m_CreativeInventory = new cCreativeInventory(this); - cTimer t1; - m_LastPlayerListTime = t1.GetNowTime(); - - m_TimeLastTeleportPacket = cWorld::GetTime(); - m_TimeLastPickupCheck = cWorld::GetTime(); - - m_PlayerName = a_PlayerName; - m_bDirtyPosition = true; // So chunks are streamed to player at spawn - - if( !LoadFromDisk() ) - { - m_Inventory->Clear(); - m_CreativeInventory->Clear(); - m_Pos.x = cRoot::Get()->GetDefaultWorld()->GetSpawnX(); - m_Pos.y = cRoot::Get()->GetDefaultWorld()->GetSpawnY(); - m_Pos.z = cRoot::Get()->GetDefaultWorld()->GetSpawnZ(); - - LOGD("Player \"%s\" is connecting for the first time, spawning at default world spawn {%.2f, %.2f, %.2f}", - a_PlayerName.c_str(), m_Pos.x, m_Pos.y, m_Pos.z - ); - } -} - - - - - -void cPlayer::Initialize( cWorld* a_World ) -{ - cPawn::Initialize( a_World ); - GetWorld()->AddPlayer( this ); -} - - - - - -cPlayer::~cPlayer(void) -{ - LOG("Deleting cPlayer \"%s\" at %p, ID %d", m_PlayerName.c_str(), this, GetUniqueID()); - - SaveToDisk(); - - m_World->RemovePlayer( this ); - - m_ClientHandle = NULL; - - delete m_Inventory; - m_Inventory = NULL; - - delete m_CreativeInventory; - - LOG("Player %p deleted", this); -} - - - - - -void cPlayer::Destroyed() -{ - CloseWindow(-1); - m_ClientHandle = NULL; -} - - - - - -cPacket * cPlayer::GetSpawnPacket(void) const -{ - LOGD("cPlayer::GetSpawnPacket for \"%s\" at pos {%.2f, %.2f, %.2f}", - m_PlayerName.c_str(), m_Pos.x, m_Pos.y, m_Pos.z - ); - - if (!m_bVisible ) - { - return NULL; - } - - cPacket_NamedEntitySpawn * SpawnPacket = new cPacket_NamedEntitySpawn; - SpawnPacket->m_UniqueID = m_UniqueID; - SpawnPacket->m_PlayerName = m_PlayerName; - SpawnPacket->m_PosX = (int)(m_Pos.x * 32); - SpawnPacket->m_PosY = (int)(m_Pos.y * 32); - SpawnPacket->m_PosZ = (int)(m_Pos.z * 32); - SpawnPacket->m_Rotation = (char)((m_Rot.x / 360.f) * 256); - SpawnPacket->m_Pitch = (char)((m_Rot.y / 360.f) * 256); - short ItemID = (short)m_Inventory->GetEquippedItem().m_ItemID; - SpawnPacket->m_CurrentItem = (ItemID > 0) ? ItemID : 0; // Unlike -1 in inventory, the named entity packet uses 0 for "none" - return SpawnPacket; -} - - - - - -void cPlayer::Tick(float a_Dt) -{ - if (!m_ClientHandle->IsPlaying()) - { - // We're not yet in the game, ignore everything - return; - } - - cPawn::Tick(a_Dt); - - if (m_bDirtyOrientation && !m_bDirtyPosition) - { - cPacket_EntityLook EntityLook(*this); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, EntityLook, m_ClientHandle ); - cPacket_EntityHeadLook EntityHeadLook(*this); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, EntityHeadLook, m_ClientHandle); - m_bDirtyOrientation = false; - } - else if (m_bDirtyPosition ) - { - cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_PLAYER_MOVE, 1, this ); - - float DiffX = (float)(GetPosX() - m_LastPosX ); - float DiffY = (float)(GetPosY() - m_LastPosY ); - float DiffZ = (float)(GetPosZ() - m_LastPosZ ); - float SqrDist = DiffX * DiffX + DiffY * DiffY + DiffZ * DiffZ; - if ( - (SqrDist > 4 * 4) || // 4 blocks is max Relative Move - (cWorld::GetTime() - m_TimeLastTeleportPacket > 2 ) // Send an absolute position every 2 seconds - ) - { - //LOG("Teleported %f", sqrtf(SqrDist) ); - cPacket_TeleportEntity TeleportEntity( this ); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, TeleportEntity, m_ClientHandle); - m_TimeLastTeleportPacket = cWorld::GetTime(); - } - else - { // Relative move sucks balls! It's always wrong wtf! - if( m_bDirtyOrientation ) - { - cPacket_RelativeEntityMoveLook RelativeEntityMoveLook; - RelativeEntityMoveLook.m_UniqueID = GetUniqueID(); - RelativeEntityMoveLook.m_MoveX = (char)(DiffX*32); - RelativeEntityMoveLook.m_MoveY = (char)(DiffY*32); - RelativeEntityMoveLook.m_MoveZ = (char)(DiffZ*32); - RelativeEntityMoveLook.m_Yaw = (char)((GetRotation()/360.f)*256); - RelativeEntityMoveLook.m_Pitch = (char)((GetPitch()/360.f)*256); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMoveLook, m_ClientHandle ); - } - else - { - cPacket_RelativeEntityMove RelativeEntityMove; - RelativeEntityMove.m_UniqueID = GetUniqueID(); - RelativeEntityMove.m_MoveX = (char)(DiffX*32); - RelativeEntityMove.m_MoveY = (char)(DiffY*32); - RelativeEntityMove.m_MoveZ = (char)(DiffZ*32); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMove, m_ClientHandle ); - } - } - m_LastPosX = GetPosX(); - m_LastPosY = GetPosY(); - m_LastPosZ = GetPosZ(); - m_bDirtyPosition = false; - m_ClientHandle->StreamChunks(); - } - - if (m_Health > 0) // make sure player is alive - { - m_World->CollectPickupsByPlayer(this); - } - - cTimer t1; - // Send Player List (Once per m_LastPlayerListTime/1000 ms) - if (m_LastPlayerListTime + cPlayer::PLAYER_LIST_TIME_MS <= t1.GetNowTime()) - { - m_World->SendPlayerList(this); - m_LastPlayerListTime = t1.GetNowTime(); - } -} - - - - - -void cPlayer::SetTouchGround( bool a_bTouchGround ) -{ - m_bTouchGround = a_bTouchGround; - - if( !m_bTouchGround ) - { - cWorld* World = GetWorld(); - char BlockID = World->GetBlock( float2int(m_Pos.x), float2int(m_Pos.y), float2int(m_Pos.z) ); - if( BlockID != E_BLOCK_AIR ) - { - m_bTouchGround = true; - } - if( BlockID == E_BLOCK_WATER || BlockID == E_BLOCK_STATIONARY_WATER || BlockID == E_BLOCK_LADDER || BlockID == E_BLOCK_TORCH ) - { - m_LastGroundHeight = (float)m_Pos.y; - } - } - - if( m_bTouchGround ) - { - float Dist = (float)(m_LastGroundHeight - m_Pos.y); - if( Dist > 4.f ) // Player dropped - { - int Damage = (int)(Dist - 4.f); - if( Damage > 0 ) - { - TakeDamage( Damage, 0 ); - } - } - - m_LastGroundHeight = (float)m_Pos.y; - } -} - -void cPlayer::Heal( int a_Health ) -{ - if( m_Health < GetMaxHealth() ) - { - m_Health = (short) MIN(a_Health + m_Health, GetMaxHealth()); - - cPacket_UpdateHealth Health; - Health.m_Health = m_Health; - Health.m_Food = GetFood(); - Health.m_Saturation = GetFoodSaturation(); - m_ClientHandle->Send( Health ); - } -} - - - - - -bool cPlayer::Feed(short a_Food) -{ - if (m_FoodLevel >= GetMaxFoodLevel()) - { - return false; - } - - m_FoodLevel = MIN(a_Food + m_FoodLevel, GetMaxFoodLevel()); - - cPacket_UpdateHealth Health; - Health.m_Health = m_Health; - Health.m_Food = GetFood(); - Health.m_Saturation = GetFoodSaturation(); - m_ClientHandle->Send( Health ); - return true; -} - - - - - -void cPlayer::TakeDamage( int a_Damage, cEntity* a_Instigator ) -{ - if ( !(m_GameMode == 1) ) { - cPawn::TakeDamage( a_Damage, a_Instigator ); - - cPacket_UpdateHealth Health; - Health.m_Health = m_Health; - Health.m_Food = GetFood(); - Health.m_Saturation = GetFoodSaturation(); - //TODO: Causes problems sometimes O.o (E.G. Disconnecting when attacked) - if(m_ClientHandle != 0) - m_ClientHandle->Send( Health ); - } -} - - - - - -void cPlayer::KilledBy(cEntity * a_Killer) -{ - cPawn::KilledBy(a_Killer); - - if (m_Health > 0) - { - return; // not dead yet =] - } - - m_bVisible = false; // So new clients don't see the player - - // Puke out all the items - cItem* Items = m_Inventory->GetSlots(); - cItems Pickups; - for (unsigned int i = 1; i < m_Inventory->c_NumSlots; ++i) - { - if( !Items[i].IsEmpty() ) - { - Pickups.push_back(Items[i]); - } - Items[i].Empty(); - } - m_World->SpawnItemPickups(Pickups, m_Pos.x, m_Pos.y, m_Pos.z, 10); - SaveToDisk(); // Save it, yeah the world is a tough place ! -} - - - - - -void cPlayer::Respawn() -{ - m_Health = GetMaxHealth(); - - // Create Respawn player packet - cPacket_Respawn Packet; - //Set Gamemode for packet by looking at world's gamemode (Need to check players gamemode.) - //Packet.m_CreativeMode = (char)GetWorld()->GetGameMode(); - Packet.m_CreativeMode = (char)m_GameMode; //Set GameMode packet based on Player's GameMode; - - //Send Packet - m_ClientHandle->Send( Packet ); - - //Set non Burning - SetMetaData(NORMAL); - - TeleportTo( GetWorld()->GetSpawnX(), GetWorld()->GetSpawnY(), GetWorld()->GetSpawnZ() ); - - SetVisible( true ); -} - -double cPlayer::GetEyeHeight() -{ - return m_Stance; -} - -Vector3d cPlayer::GetEyePosition() -{ - return Vector3d( m_Pos.x, m_Stance, m_Pos.z ); -} - -void cPlayer::OpenWindow( cWindow* a_Window ) -{ - CloseWindow(m_CurrentWindow ? (char)m_CurrentWindow->GetWindowType() : 0); - a_Window->Open( *this ); - m_CurrentWindow = a_Window; -} - - - - - -void cPlayer::CloseWindow(char a_WindowType) -{ - if (a_WindowType == 0) - { - // Inventory - if ( - (m_Inventory->GetWindow()->GetDraggingItem() != NULL) && - (m_Inventory->GetWindow()->GetDraggingItem()->m_ItemCount > 0) - ) - { - LOG("Player holds item! Dropping it..."); - TossItem( true, m_Inventory->GetWindow()->GetDraggingItem()->m_ItemCount ); - } - - //Drop whats in the crafting slots (1, 2, 3, 4) - cItems Drops; - for (int i = 1; i <= 4; i++) - { - cItem* Item = m_Inventory->GetSlot( i ); - if (!Item->IsEmpty()) - { - Drops.push_back(*Item); - } - Item->Empty(); - } - float vX = 0, vY = 0, vZ = 0; - EulerToVector(-GetRotation(), GetPitch(), vZ, vX, vY); - vY = -vY*2 + 1.f; - m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY() + 1.6f, GetPosZ(), vX * 2, vY * 2, vZ * 2); - } - - if (m_CurrentWindow) - { - // FIXME: If the player entity is destroyed while having a chest window open, the chest will not close - if (a_WindowType == 1 && strcmp(m_CurrentWindow->GetWindowTitle().c_str(), "UberChest") == 0) { // Chest - cBlockEntity *block = m_CurrentWindow->GetOwner()->GetEntity(); - cPacket_BlockAction ChestClose; - ChestClose.m_PosX = block->GetPosX(); - ChestClose.m_PosY = (short)block->GetPosY(); - ChestClose.m_PosZ = block->GetPosZ(); - ChestClose.m_Byte1 = 1; - ChestClose.m_Byte2 = 0; - m_World->Broadcast(ChestClose); - } - - m_CurrentWindow->Close( *this ); - } - m_CurrentWindow = NULL; -} - - - - - -void cPlayer::SetLastBlockActionTime() -{ - if (m_World != NULL) - { - m_LastBlockActionTime = m_World->GetTime(); - } -} - - - - - -void cPlayer::SetLastBlockActionCnt( int a_LastBlockActionCnt ) -{ - m_LastBlockActionCnt = a_LastBlockActionCnt; -} - - - - - -void cPlayer::SetGameMode( eGameMode a_GameMode ) -{ - if ( (a_GameMode < 2) && (a_GameMode >= 0) ) - { - if (m_GameMode != a_GameMode) - { - cInventory *OldInventory = 0; - if(m_GameMode == eGameMode_Survival) - OldInventory = m_Inventory; - else - OldInventory = m_CreativeInventory; - - m_GameMode = a_GameMode; - cPacket_NewInvalidState GameModePacket; - GameModePacket.m_Reason = 3; //GameModeChange - GameModePacket.m_GameMode = (char)a_GameMode; //GameModeChange - m_ClientHandle->Send ( GameModePacket ); - GetInventory().SendWholeInventory(m_ClientHandle); - - OldInventory->SetEquippedSlot(GetInventory().GetEquippedSlot()); - } - } -} - - - - - -void cPlayer::LoginSetGameMode( eGameMode a_GameMode ) -{ - m_GameMode = a_GameMode; -} - - - - - -void cPlayer::SetIP( std::string a_IP ) -{ - m_IP = a_IP; -} - - - - - -void cPlayer::SendMessage( const char* a_Message ) -{ - m_ClientHandle->Send( cPacket_Chat( a_Message ) ); -} - - - - - -void cPlayer::TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ) -{ - SetPosition( a_PosX, a_PosY, a_PosZ ); - - cPacket_TeleportEntity TeleportEntity( this ); - cRoot::Get()->GetServer()->Broadcast( TeleportEntity, GetClientHandle() ); - - - cPacket_PlayerPosition PlayerPosition( this ); - - m_ClientHandle->Send( PlayerPosition ); -} - - - - - -void cPlayer::MoveTo( const Vector3d & a_NewPos ) -{ - // TODO: should do some checks to see if player is not moving through terrain - // TODO: Official server refuses position packets too far away from each other, kicking "hacked" clients; we should, too - - SetPosition( a_NewPos ); -} - - - - - -void cPlayer::SetVisible( bool a_bVisible ) -{ - if (a_bVisible && !m_bVisible) // Make visible - { - m_bVisible = true; - SpawnOn( NULL ); // Spawn on everybody - } - if (!a_bVisible && m_bVisible) - { - m_bVisible = false; - cPacket_DestroyEntity DestroyEntity( this ); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, DestroyEntity ); // Destroy on all clients - } -} - - - - - -void cPlayer::AddToGroup( const char* a_GroupName ) -{ - cGroup* Group = cRoot::Get()->GetGroupManager()->GetGroup( a_GroupName ); - m_Groups.push_back( Group ); - LOG("Added %s to group %s", m_PlayerName.c_str(), a_GroupName ); - ResolveGroups(); - ResolvePermissions(); -} - - - - - -bool cPlayer::CanUseCommand( const char* a_Command ) -{ - for( GroupList::iterator itr = m_Groups.begin(); itr != m_Groups.end(); ++itr ) - { - if( (*itr)->HasCommand( a_Command ) ) return true; - } - return false; -} - - - - - -bool cPlayer::HasPermission( const char* a_Permission ) -{ - AStringVector Split = StringSplit( a_Permission, "." ); - PermissionMap Possibilities = m_ResolvedPermissions; - // Now search the namespaces - while( Possibilities.begin() != Possibilities.end() ) - { - PermissionMap::iterator itr = Possibilities.begin(); - if( itr->second ) - { - AStringVector OtherSplit = StringSplit( itr->first, "." ); - if( OtherSplit.size() <= Split.size() ) - { - unsigned int i; - for( i = 0; i < OtherSplit.size(); ++i ) - { - if( OtherSplit[i].compare( Split[i] ) != 0 ) - { - if( OtherSplit[i].compare("*") == 0 ) return true; // WildCard man!! WildCard! - break; - } - } - if( i == Split.size() ) return true; - } - } - Possibilities.erase( itr ); - } - - // Nothing that matched :( - return false; -} - - - - - -bool cPlayer::IsInGroup( const char* a_Group ) -{ - for( GroupList::iterator itr = m_ResolvedGroups.begin(); itr != m_ResolvedGroups.end(); ++itr ) - { - if( strcmp( a_Group, (*itr)->GetName().c_str() ) == 0 ) - return true; - } - return false; -} - - - - - -void cPlayer::ResolvePermissions() -{ - m_ResolvedPermissions.clear(); // Start with an empty map yo~ - - // Copy all player specific permissions into the resolved permissions map - for( PermissionMap::iterator itr = m_Permissions.begin(); itr != m_Permissions.end(); ++itr ) - { - m_ResolvedPermissions[ itr->first ] = itr->second; - } - - for( GroupList::iterator GroupItr = m_ResolvedGroups.begin(); GroupItr != m_ResolvedGroups.end(); ++GroupItr ) - { - const cGroup::PermissionMap & Permissions = (*GroupItr)->GetPermissions(); - for( cGroup::PermissionMap::const_iterator itr = Permissions.begin(); itr != Permissions.end(); ++itr ) - { - m_ResolvedPermissions[ itr->first ] = itr->second; - } - } -} - - - - - -void cPlayer::ResolveGroups() -{ - // Clear resolved groups first - m_ResolvedGroups.clear(); - - // Get a complete resolved list of all groups the player is in - std::map< cGroup*, bool > AllGroups; // Use a map, because it's faster than iterating through a list to find duplicates - GroupList ToIterate; - for( GroupList::iterator GroupItr = m_Groups.begin(); GroupItr != m_Groups.end(); ++GroupItr ) - { - ToIterate.push_back( *GroupItr ); - } - while( ToIterate.begin() != ToIterate.end() ) - { - cGroup* CurrentGroup = *ToIterate.begin(); - if( AllGroups.find( CurrentGroup ) != AllGroups.end() ) - { - LOGWARNING("ERROR: Player \"%s\" is in the group multiple times (\"%s\"). Please fix your settings in users.ini!", - m_PlayerName.c_str(), CurrentGroup->GetName().c_str() - ); - } - else - { - AllGroups[ CurrentGroup ] = true; - m_ResolvedGroups.push_back( CurrentGroup ); // Add group to resolved list - const cGroup::GroupList & Inherits = CurrentGroup->GetInherits(); - for( cGroup::GroupList::const_iterator itr = Inherits.begin(); itr != Inherits.end(); ++itr ) - { - if( AllGroups.find( *itr ) != AllGroups.end() ) - { - LOGERROR("ERROR: Player %s is in the same group multiple times due to inheritance (%s). FIX IT!", m_PlayerName.c_str(), (*itr)->GetName().c_str() ); - continue; - } - ToIterate.push_back( *itr ); - } - } - ToIterate.erase( ToIterate.begin() ); - } -} - - - - - -AString cPlayer::GetColor(void) const -{ - if ( m_Color != '-' ) - { - return cChatColor::MakeColor( m_Color ); - } - - if ( m_Groups.size() < 1 ) - { - return cChatColor::White; - } - - return (*m_Groups.begin())->GetColor(); -} - - - - - -void cPlayer::TossItem( bool a_bDraggingItem, int a_Amount /* = 1 */ ) -{ - cItems Drops; - if (a_bDraggingItem) - { - cItem * Item = GetInventory().GetWindow()->GetDraggingItem(); - if (!Item->IsEmpty()) - { - Drops.push_back(*Item); - if( Item->m_ItemCount > a_Amount ) - Item->m_ItemCount -= (char)a_Amount; - else - Item->Empty(); - } - } - else - { - // Else drop equipped item - cItem DroppedItem = GetInventory().GetEquippedItem(); - if (!DroppedItem.IsEmpty()) - { - DroppedItem.m_ItemCount = 1; - if (GetInventory().RemoveItem(DroppedItem)) - { - DroppedItem.m_ItemCount = 1; // RemoveItem decreases the count, so set it to 1 again - Drops.push_back(DroppedItem); - } - } - } - float vX = 0, vY = 0, vZ = 0; - EulerToVector( -GetRotation(), GetPitch(), vZ, vX, vY ); - vY = -vY*2 + 1.f; - m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY() + 1.6f, GetPosZ(), vX * 2, vY * 2, vZ * 2); -} - - - - - -bool cPlayer::MoveToWorld( const char* a_WorldName ) -{ - cWorld * World = cRoot::Get()->GetWorld( a_WorldName ); - if ( World ) - { - /* Remove all links to the old world */ - m_World->RemovePlayer( this ); - m_ClientHandle->RemoveFromAllChunks(); - m_World->RemoveEntityFromChunk(this, m_ChunkX, m_ChunkY, m_ChunkZ); - - /* Add player to all the necessary parts of the new world */ - SetWorld( World ); - GetWorld()->AddPlayer( this ); - MoveToCorrectChunk(true); - GetClientHandle()->StreamChunks(); - - return true; - } - - return false; -} - - - - - -void cPlayer::LoadPermissionsFromDisk() -{ - m_Groups.clear(); - m_Permissions.clear(); - - cIniFile IniFile("users.ini"); - if( IniFile.ReadFile() ) - { - std::string Groups = IniFile.GetValue(m_PlayerName, "Groups", ""); - if( Groups.size() > 0 ) - { - AStringVector Split = StringSplit( Groups, "," ); - for( unsigned int i = 0; i < Split.size(); i++ ) - { - AddToGroup( Split[i].c_str() ); - } - } - else - { - AddToGroup("Default"); - } - - m_Color = IniFile.GetValue(m_PlayerName, "Color", "-")[0]; - } - else - { - LOGWARN("WARNING: Failed to read ini file users.ini"); - AddToGroup("Default"); - } - ResolvePermissions(); -} - - - - -bool cPlayer::LoadFromDisk() -{ - LoadPermissionsFromDisk(); - - // Log player permissions, cause it's what the cool kids do - LOGINFO("Player %s has permissions:", m_PlayerName.c_str() ); - for( PermissionMap::iterator itr = m_ResolvedPermissions.begin(); itr != m_ResolvedPermissions.end(); ++itr ) - { - if( itr->second ) LOGINFO("%s", itr->first.c_str() ); - } - - AString SourceFile; - Printf(SourceFile, "players/%s.json", m_PlayerName.c_str() ); - - cFile f; - if (!f.Open(SourceFile, cFile::fmRead)) - { - return false; - } - - AString buffer; - if (f.ReadRestOfFile(buffer) != f.GetSize()) - { - LOGERROR("ERROR READING FROM FILE \"%s\"", SourceFile.c_str()); - return false; - } - f.Close(); - - Json::Value root; - Json::Reader reader; - if (!reader.parse(buffer, root, false)) - { - LOGERROR("ERROR WHILE PARSING JSON FROM FILE %s", SourceFile.c_str()); - } - - Json::Value & JSON_PlayerPosition = root["position"]; - if( JSON_PlayerPosition.size() == 3 ) - { - m_Pos.x = JSON_PlayerPosition[(unsigned int)0].asDouble(); - m_Pos.y = JSON_PlayerPosition[(unsigned int)1].asDouble(); - m_Pos.z = JSON_PlayerPosition[(unsigned int)2].asDouble(); - } - - Json::Value & JSON_PlayerRotation = root["rotation"]; - if( JSON_PlayerRotation.size() == 3 ) - { - m_Rot.x = (float)JSON_PlayerRotation[(unsigned int)0].asDouble(); - m_Rot.y = (float)JSON_PlayerRotation[(unsigned int)1].asDouble(); - m_Rot.z = (float)JSON_PlayerRotation[(unsigned int)2].asDouble(); - } - - m_Health = (short)root.get("health", 0 ).asInt(); - m_FoodLevel = (short)root.get("food", 0 ).asInt(); - m_Inventory->LoadFromJson(root["inventory"]); - m_CreativeInventory->LoadFromJson(root["creativeinventory"]); - - m_LoadedWorldName = root.get("world", "world").asString(); - - LOGD("Player \"%s\" was read from file, spawning at {%.2f, %.2f, %.2f} in world \"%s\"", - m_PlayerName.c_str(), m_Pos.x, m_Pos.y, m_Pos.z, m_LoadedWorldName.c_str() - ); - - return true; -} - - - - - -bool cPlayer::SaveToDisk() -{ - cMakeDir::MakeDir("players"); - - // create the JSON data - Json::Value JSON_PlayerPosition; - JSON_PlayerPosition.append( Json::Value( m_Pos.x ) ); - JSON_PlayerPosition.append( Json::Value( m_Pos.y ) ); - JSON_PlayerPosition.append( Json::Value( m_Pos.z ) ); - - Json::Value JSON_PlayerRotation; - JSON_PlayerRotation.append( Json::Value( m_Rot.x ) ); - JSON_PlayerRotation.append( Json::Value( m_Rot.y ) ); - JSON_PlayerRotation.append( Json::Value( m_Rot.z ) ); - - Json::Value JSON_Inventory; - m_Inventory->SaveToJson( JSON_Inventory ); - - Json::Value JSON_CreativeInventory; - m_CreativeInventory->SaveToJson( JSON_CreativeInventory ); - - Json::Value root; - root["position"] = JSON_PlayerPosition; - root["rotation"] = JSON_PlayerRotation; - root["inventory"] = JSON_Inventory; - root["creativeinventory"] = JSON_CreativeInventory; - root["health"] = m_Health; - root["food"] = m_FoodLevel; - root["world"] = GetWorld()->GetName(); - - Json::StyledWriter writer; - std::string JsonData = writer.write( root ); - - AString SourceFile; - Printf(SourceFile, "players/%s.json", m_PlayerName.c_str() ); - - cFile f; - if (!f.Open(SourceFile, cFile::fmWrite)) - { - LOGERROR("ERROR WRITING PLAYER \"%s\" TO FILE \"%s\" - cannot open file", m_PlayerName.c_str(), SourceFile.c_str()); - return false; - } - if (f.Write(JsonData.c_str(), JsonData.size()) != (int)JsonData.size()) - { - LOGERROR("ERROR WRITING PLAYER JSON TO FILE \"%s\"", SourceFile.c_str()); - return false; - } - return true; -} - - - - - -cPlayer::StringList cPlayer::GetResolvedPermissions() -{ - StringList Permissions; - - const PermissionMap& ResolvedPermissions = m_ResolvedPermissions; - for( PermissionMap::const_iterator itr = ResolvedPermissions.begin(); itr != ResolvedPermissions.end(); ++itr ) - { - if( itr->second ) Permissions.push_back( itr->first ); - } - - return Permissions; -} - - - - - -void cPlayer::UseEquippedItem() -{ - if(GetGameMode() != 1) //No damage in creative - { - if (GetInventory().GetEquippedItem().DamageItem()) - { - LOG("Player %s Broke ID: %i", GetClientHandle()->GetUsername().c_str(), GetInventory().GetEquippedItem().m_ItemID); - GetInventory().RemoveItem( GetInventory().GetEquippedItem()); - } - } -} - - - - - -bool cPlayer::EatItem(int a_ItemType) -{ - // TODO: Handle hunger - switch (a_ItemType) - { - case E_ITEM_APPLE: return Feed(24); // 2 food bars - case E_ITEM_GOLDEN_APPLE: return Feed(60); // 5 food - case E_ITEM_MUSHROOM_SOUP: return Feed(48); // 4 food - case E_ITEM_BREAD: return Feed(30); // 2.5 food - case E_ITEM_RAW_MEAT: return Feed(18); // 1.5 food - case E_ITEM_COOKED_MEAT: return Feed(48); // 4 food - case E_ITEM_RAW_FISH: return Feed(12); // 1 food - case E_ITEM_COOKED_FISH: return Feed(30); // 2.5 food - case E_ITEM_COOKED_CHICKEN: return Feed(36); // 3 food - case E_ITEM_RAW_BEEF: return Feed(18); // 1.5 food - case E_ITEM_STEAK: return Feed(48); // 4 food - case E_ITEM_RAW_CHICKEN: - { - if (!Feed(12)) // 1 food - { - return false; - } - // TODO: A random chance to get food-poisoned - return true; - } - - case E_ITEM_ROTTEN_FLESH: - { - if (!Feed(24)) - { - return false; - } - // TODO: Food-poisoning - return true; - } - } - return false; -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPlayer.h" +#include "cServer.h" +#include "cCreativeInventory.h" +#include "cSurvivalInventory.h" +#include "cClientHandle.h" +#include "cWorld.h" +#include "cPickup.h" +#include "cPluginManager.h" +#include "cWindow.h" +#include "cBlockEntity.h" +#include "cGroupManager.h" +#include "cGroup.h" +#include "cChatColor.h" +#include "cItem.h" +#include "cTracer.h" +#include "cRoot.h" +#include "cMakeDir.h" +#include "cTimer.h" +#include "MersenneTwister.h" + +#include "packets/cPacket_NamedEntitySpawn.h" +#include "packets/cPacket_EntityLook.h" +#include "packets/cPacket_TeleportEntity.h" +#include "packets/cPacket_RelativeEntityMove.h" +#include "packets/cPacket_RelativeEntityMoveLook.h" +#include "packets/cPacket_UpdateHealth.h" +#include "packets/cPacket_Respawn.h" +#include "packets/cPacket_DestroyEntity.h" +#include "packets/cPacket_Metadata.h" +#include "packets/cPacket_Chat.h" +#include "packets/cPacket_NewInvalidState.h" +#include "packets/cPacket_BlockAction.h" + +#include "Vector3d.h" +#include "Vector3f.h" + +#include "../iniFile/iniFile.h" +#include + +#define float2int(x) ((x)<0 ? ((int)(x))-1 : (int)(x)) + + + + + +CLASS_DEFINITION( cPlayer, cPawn ); + + + + + +cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) + : m_GameMode( eGameMode_Survival ) + , m_IP("") + , m_LastBlockActionTime( 0 ) + , m_LastBlockActionCnt( 0 ) + , m_bVisible( true ) + , m_LastGroundHeight( 0 ) + , m_bTouchGround( false ) + , m_Stance( 0.0 ) + , m_Inventory( 0 ) + , m_CurrentWindow( 0 ) + , m_TimeLastPickupCheck( 0.f ) + , m_Color('-') + , m_ClientHandle( a_Client ) +{ + LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d", + a_PlayerName.c_str(), a_Client->GetSocket().GetIPString().c_str(), + this, GetUniqueID() + ); + m_EntityType = eEntityType_Player; + SetMaxHealth(20); + SetMaxFoodLevel(125); + m_Inventory = new cSurvivalInventory( this ); + m_CreativeInventory = new cCreativeInventory(this); + cTimer t1; + m_LastPlayerListTime = t1.GetNowTime(); + + m_TimeLastTeleportPacket = cWorld::GetTime(); + m_TimeLastPickupCheck = cWorld::GetTime(); + + m_PlayerName = a_PlayerName; + m_bDirtyPosition = true; // So chunks are streamed to player at spawn + + if( !LoadFromDisk() ) + { + m_Inventory->Clear(); + m_CreativeInventory->Clear(); + m_Pos.x = cRoot::Get()->GetDefaultWorld()->GetSpawnX(); + m_Pos.y = cRoot::Get()->GetDefaultWorld()->GetSpawnY(); + m_Pos.z = cRoot::Get()->GetDefaultWorld()->GetSpawnZ(); + + LOGD("Player \"%s\" is connecting for the first time, spawning at default world spawn {%.2f, %.2f, %.2f}", + a_PlayerName.c_str(), m_Pos.x, m_Pos.y, m_Pos.z + ); + } +} + + + + + +void cPlayer::Initialize( cWorld* a_World ) +{ + cPawn::Initialize( a_World ); + GetWorld()->AddPlayer( this ); +} + + + + + +cPlayer::~cPlayer(void) +{ + LOG("Deleting cPlayer \"%s\" at %p, ID %d", m_PlayerName.c_str(), this, GetUniqueID()); + + SaveToDisk(); + + m_World->RemovePlayer( this ); + + m_ClientHandle = NULL; + + delete m_Inventory; + m_Inventory = NULL; + + delete m_CreativeInventory; + + LOG("Player %p deleted", this); +} + + + + + +void cPlayer::Destroyed() +{ + CloseWindow(-1); + m_ClientHandle = NULL; +} + + + + + +cPacket * cPlayer::GetSpawnPacket(void) const +{ + LOGD("cPlayer::GetSpawnPacket for \"%s\" at pos {%.2f, %.2f, %.2f}", + m_PlayerName.c_str(), m_Pos.x, m_Pos.y, m_Pos.z + ); + + if (!m_bVisible ) + { + return NULL; + } + + cPacket_NamedEntitySpawn * SpawnPacket = new cPacket_NamedEntitySpawn; + SpawnPacket->m_UniqueID = m_UniqueID; + SpawnPacket->m_PlayerName = m_PlayerName; + SpawnPacket->m_PosX = (int)(m_Pos.x * 32); + SpawnPacket->m_PosY = (int)(m_Pos.y * 32); + SpawnPacket->m_PosZ = (int)(m_Pos.z * 32); + SpawnPacket->m_Rotation = (char)((m_Rot.x / 360.f) * 256); + SpawnPacket->m_Pitch = (char)((m_Rot.y / 360.f) * 256); + short ItemID = (short)m_Inventory->GetEquippedItem().m_ItemID; + SpawnPacket->m_CurrentItem = (ItemID > 0) ? ItemID : 0; // Unlike -1 in inventory, the named entity packet uses 0 for "none" + return SpawnPacket; +} + + + + + +void cPlayer::Tick(float a_Dt) +{ + if (!m_ClientHandle->IsPlaying()) + { + // We're not yet in the game, ignore everything + return; + } + + cPawn::Tick(a_Dt); + + if (m_bDirtyOrientation && !m_bDirtyPosition) + { + cPacket_EntityLook EntityLook(*this); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, EntityLook, m_ClientHandle ); + cPacket_EntityHeadLook EntityHeadLook(*this); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, EntityHeadLook, m_ClientHandle); + m_bDirtyOrientation = false; + } + else if (m_bDirtyPosition ) + { + cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_PLAYER_MOVE, 1, this ); + + float DiffX = (float)(GetPosX() - m_LastPosX ); + float DiffY = (float)(GetPosY() - m_LastPosY ); + float DiffZ = (float)(GetPosZ() - m_LastPosZ ); + float SqrDist = DiffX * DiffX + DiffY * DiffY + DiffZ * DiffZ; + if ( + (SqrDist > 4 * 4) || // 4 blocks is max Relative Move + (cWorld::GetTime() - m_TimeLastTeleportPacket > 2 ) // Send an absolute position every 2 seconds + ) + { + //LOG("Teleported %f", sqrtf(SqrDist) ); + cPacket_TeleportEntity TeleportEntity( this ); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, TeleportEntity, m_ClientHandle); + m_TimeLastTeleportPacket = cWorld::GetTime(); + } + else + { // Relative move sucks balls! It's always wrong wtf! + if( m_bDirtyOrientation ) + { + cPacket_RelativeEntityMoveLook RelativeEntityMoveLook; + RelativeEntityMoveLook.m_UniqueID = GetUniqueID(); + RelativeEntityMoveLook.m_MoveX = (char)(DiffX*32); + RelativeEntityMoveLook.m_MoveY = (char)(DiffY*32); + RelativeEntityMoveLook.m_MoveZ = (char)(DiffZ*32); + RelativeEntityMoveLook.m_Yaw = (char)((GetRotation()/360.f)*256); + RelativeEntityMoveLook.m_Pitch = (char)((GetPitch()/360.f)*256); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMoveLook, m_ClientHandle ); + } + else + { + cPacket_RelativeEntityMove RelativeEntityMove; + RelativeEntityMove.m_UniqueID = GetUniqueID(); + RelativeEntityMove.m_MoveX = (char)(DiffX*32); + RelativeEntityMove.m_MoveY = (char)(DiffY*32); + RelativeEntityMove.m_MoveZ = (char)(DiffZ*32); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMove, m_ClientHandle ); + } + } + m_LastPosX = GetPosX(); + m_LastPosY = GetPosY(); + m_LastPosZ = GetPosZ(); + m_bDirtyPosition = false; + m_ClientHandle->StreamChunks(); + } + + if (m_Health > 0) // make sure player is alive + { + m_World->CollectPickupsByPlayer(this); + } + + cTimer t1; + // Send Player List (Once per m_LastPlayerListTime/1000 ms) + if (m_LastPlayerListTime + cPlayer::PLAYER_LIST_TIME_MS <= t1.GetNowTime()) + { + m_World->SendPlayerList(this); + m_LastPlayerListTime = t1.GetNowTime(); + } +} + + + + + +void cPlayer::SetTouchGround( bool a_bTouchGround ) +{ + m_bTouchGround = a_bTouchGround; + + if( !m_bTouchGround ) + { + cWorld* World = GetWorld(); + char BlockID = World->GetBlock( float2int(m_Pos.x), float2int(m_Pos.y), float2int(m_Pos.z) ); + if( BlockID != E_BLOCK_AIR ) + { + m_bTouchGround = true; + } + if( BlockID == E_BLOCK_WATER || BlockID == E_BLOCK_STATIONARY_WATER || BlockID == E_BLOCK_LADDER || BlockID == E_BLOCK_TORCH ) + { + m_LastGroundHeight = (float)m_Pos.y; + } + } + + if( m_bTouchGround ) + { + float Dist = (float)(m_LastGroundHeight - m_Pos.y); + if( Dist > 4.f ) // Player dropped + { + int Damage = (int)(Dist - 4.f); + if( Damage > 0 ) + { + TakeDamage( Damage, 0 ); + } + } + + m_LastGroundHeight = (float)m_Pos.y; + } +} + +void cPlayer::Heal( int a_Health ) +{ + if( m_Health < GetMaxHealth() ) + { + m_Health = (short) MIN(a_Health + m_Health, GetMaxHealth()); + + cPacket_UpdateHealth Health; + Health.m_Health = m_Health; + Health.m_Food = GetFood(); + Health.m_Saturation = GetFoodSaturation(); + m_ClientHandle->Send( Health ); + } +} + + + + + +bool cPlayer::Feed(short a_Food) +{ + if (m_FoodLevel >= GetMaxFoodLevel()) + { + return false; + } + + m_FoodLevel = MIN(a_Food + m_FoodLevel, GetMaxFoodLevel()); + + cPacket_UpdateHealth Health; + Health.m_Health = m_Health; + Health.m_Food = GetFood(); + Health.m_Saturation = GetFoodSaturation(); + m_ClientHandle->Send( Health ); + return true; +} + + + + + +void cPlayer::TakeDamage( int a_Damage, cEntity* a_Instigator ) +{ + if ( !(m_GameMode == 1) ) { + cPawn::TakeDamage( a_Damage, a_Instigator ); + + cPacket_UpdateHealth Health; + Health.m_Health = m_Health; + Health.m_Food = GetFood(); + Health.m_Saturation = GetFoodSaturation(); + //TODO: Causes problems sometimes O.o (E.G. Disconnecting when attacked) + if(m_ClientHandle != 0) + m_ClientHandle->Send( Health ); + } +} + + + + + +void cPlayer::KilledBy(cEntity * a_Killer) +{ + cPawn::KilledBy(a_Killer); + + if (m_Health > 0) + { + return; // not dead yet =] + } + + m_bVisible = false; // So new clients don't see the player + + // Puke out all the items + cItem* Items = m_Inventory->GetSlots(); + cItems Pickups; + for (unsigned int i = 1; i < m_Inventory->c_NumSlots; ++i) + { + if( !Items[i].IsEmpty() ) + { + Pickups.push_back(Items[i]); + } + Items[i].Empty(); + } + m_World->SpawnItemPickups(Pickups, m_Pos.x, m_Pos.y, m_Pos.z, 10); + SaveToDisk(); // Save it, yeah the world is a tough place ! +} + + + + + +void cPlayer::Respawn() +{ + m_Health = GetMaxHealth(); + + // Create Respawn player packet + cPacket_Respawn Packet; + //Set Gamemode for packet by looking at world's gamemode (Need to check players gamemode.) + //Packet.m_CreativeMode = (char)GetWorld()->GetGameMode(); + Packet.m_CreativeMode = (char)m_GameMode; //Set GameMode packet based on Player's GameMode; + + //Send Packet + m_ClientHandle->Send( Packet ); + + //Set non Burning + SetMetaData(NORMAL); + + TeleportTo( GetWorld()->GetSpawnX(), GetWorld()->GetSpawnY(), GetWorld()->GetSpawnZ() ); + + SetVisible( true ); +} + +double cPlayer::GetEyeHeight() +{ + return m_Stance; +} + +Vector3d cPlayer::GetEyePosition() +{ + return Vector3d( m_Pos.x, m_Stance, m_Pos.z ); +} + +void cPlayer::OpenWindow( cWindow* a_Window ) +{ + CloseWindow(m_CurrentWindow ? (char)m_CurrentWindow->GetWindowType() : 0); + a_Window->Open( *this ); + m_CurrentWindow = a_Window; +} + + + + + +void cPlayer::CloseWindow(char a_WindowType) +{ + if (a_WindowType == 0) + { + // Inventory + if ( + (m_Inventory->GetWindow()->GetDraggingItem() != NULL) && + (m_Inventory->GetWindow()->GetDraggingItem()->m_ItemCount > 0) + ) + { + LOG("Player holds item! Dropping it..."); + TossItem( true, m_Inventory->GetWindow()->GetDraggingItem()->m_ItemCount ); + } + + //Drop whats in the crafting slots (1, 2, 3, 4) + cItems Drops; + for (int i = 1; i <= 4; i++) + { + cItem* Item = m_Inventory->GetSlot( i ); + if (!Item->IsEmpty()) + { + Drops.push_back(*Item); + } + Item->Empty(); + } + float vX = 0, vY = 0, vZ = 0; + EulerToVector(-GetRotation(), GetPitch(), vZ, vX, vY); + vY = -vY*2 + 1.f; + m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY() + 1.6f, GetPosZ(), vX * 2, vY * 2, vZ * 2); + } + + if (m_CurrentWindow) + { + // FIXME: If the player entity is destroyed while having a chest window open, the chest will not close + if (a_WindowType == 1 && strcmp(m_CurrentWindow->GetWindowTitle().c_str(), "UberChest") == 0) { // Chest + cBlockEntity *block = m_CurrentWindow->GetOwner()->GetEntity(); + cPacket_BlockAction ChestClose; + ChestClose.m_PosX = block->GetPosX(); + ChestClose.m_PosY = (short)block->GetPosY(); + ChestClose.m_PosZ = block->GetPosZ(); + ChestClose.m_Byte1 = 1; + ChestClose.m_Byte2 = 0; + m_World->Broadcast(ChestClose); + } + + m_CurrentWindow->Close( *this ); + } + m_CurrentWindow = NULL; +} + + + + + +void cPlayer::SetLastBlockActionTime() +{ + if (m_World != NULL) + { + m_LastBlockActionTime = m_World->GetTime(); + } +} + + + + + +void cPlayer::SetLastBlockActionCnt( int a_LastBlockActionCnt ) +{ + m_LastBlockActionCnt = a_LastBlockActionCnt; +} + + + + + +void cPlayer::SetGameMode( eGameMode a_GameMode ) +{ + if ( (a_GameMode < 2) && (a_GameMode >= 0) ) + { + if (m_GameMode != a_GameMode) + { + cInventory *OldInventory = 0; + if(m_GameMode == eGameMode_Survival) + OldInventory = m_Inventory; + else + OldInventory = m_CreativeInventory; + + m_GameMode = a_GameMode; + cPacket_NewInvalidState GameModePacket; + GameModePacket.m_Reason = 3; //GameModeChange + GameModePacket.m_GameMode = (char)a_GameMode; //GameModeChange + m_ClientHandle->Send ( GameModePacket ); + GetInventory().SendWholeInventory(m_ClientHandle); + + OldInventory->SetEquippedSlot(GetInventory().GetEquippedSlot()); + } + } +} + + + + + +void cPlayer::LoginSetGameMode( eGameMode a_GameMode ) +{ + m_GameMode = a_GameMode; +} + + + + + +void cPlayer::SetIP( std::string a_IP ) +{ + m_IP = a_IP; +} + + + + + +void cPlayer::SendMessage( const char* a_Message ) +{ + m_ClientHandle->Send( cPacket_Chat( a_Message ) ); +} + + + + + +void cPlayer::TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ) +{ + SetPosition( a_PosX, a_PosY, a_PosZ ); + + cPacket_TeleportEntity TeleportEntity( this ); + cRoot::Get()->GetServer()->Broadcast( TeleportEntity, GetClientHandle() ); + + + cPacket_PlayerPosition PlayerPosition( this ); + + m_ClientHandle->Send( PlayerPosition ); +} + + + + + +void cPlayer::MoveTo( const Vector3d & a_NewPos ) +{ + // TODO: should do some checks to see if player is not moving through terrain + // TODO: Official server refuses position packets too far away from each other, kicking "hacked" clients; we should, too + + SetPosition( a_NewPos ); +} + + + + + +void cPlayer::SetVisible( bool a_bVisible ) +{ + if (a_bVisible && !m_bVisible) // Make visible + { + m_bVisible = true; + SpawnOn( NULL ); // Spawn on everybody + } + if (!a_bVisible && m_bVisible) + { + m_bVisible = false; + cPacket_DestroyEntity DestroyEntity( this ); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, DestroyEntity ); // Destroy on all clients + } +} + + + + + +void cPlayer::AddToGroup( const char* a_GroupName ) +{ + cGroup* Group = cRoot::Get()->GetGroupManager()->GetGroup( a_GroupName ); + m_Groups.push_back( Group ); + LOG("Added %s to group %s", m_PlayerName.c_str(), a_GroupName ); + ResolveGroups(); + ResolvePermissions(); +} + + + + + +bool cPlayer::CanUseCommand( const char* a_Command ) +{ + for( GroupList::iterator itr = m_Groups.begin(); itr != m_Groups.end(); ++itr ) + { + if( (*itr)->HasCommand( a_Command ) ) return true; + } + return false; +} + + + + + +bool cPlayer::HasPermission( const char* a_Permission ) +{ + AStringVector Split = StringSplit( a_Permission, "." ); + PermissionMap Possibilities = m_ResolvedPermissions; + // Now search the namespaces + while( Possibilities.begin() != Possibilities.end() ) + { + PermissionMap::iterator itr = Possibilities.begin(); + if( itr->second ) + { + AStringVector OtherSplit = StringSplit( itr->first, "." ); + if( OtherSplit.size() <= Split.size() ) + { + unsigned int i; + for( i = 0; i < OtherSplit.size(); ++i ) + { + if( OtherSplit[i].compare( Split[i] ) != 0 ) + { + if( OtherSplit[i].compare("*") == 0 ) return true; // WildCard man!! WildCard! + break; + } + } + if( i == Split.size() ) return true; + } + } + Possibilities.erase( itr ); + } + + // Nothing that matched :( + return false; +} + + + + + +bool cPlayer::IsInGroup( const char* a_Group ) +{ + for( GroupList::iterator itr = m_ResolvedGroups.begin(); itr != m_ResolvedGroups.end(); ++itr ) + { + if( strcmp( a_Group, (*itr)->GetName().c_str() ) == 0 ) + return true; + } + return false; +} + + + + + +void cPlayer::ResolvePermissions() +{ + m_ResolvedPermissions.clear(); // Start with an empty map yo~ + + // Copy all player specific permissions into the resolved permissions map + for( PermissionMap::iterator itr = m_Permissions.begin(); itr != m_Permissions.end(); ++itr ) + { + m_ResolvedPermissions[ itr->first ] = itr->second; + } + + for( GroupList::iterator GroupItr = m_ResolvedGroups.begin(); GroupItr != m_ResolvedGroups.end(); ++GroupItr ) + { + const cGroup::PermissionMap & Permissions = (*GroupItr)->GetPermissions(); + for( cGroup::PermissionMap::const_iterator itr = Permissions.begin(); itr != Permissions.end(); ++itr ) + { + m_ResolvedPermissions[ itr->first ] = itr->second; + } + } +} + + + + + +void cPlayer::ResolveGroups() +{ + // Clear resolved groups first + m_ResolvedGroups.clear(); + + // Get a complete resolved list of all groups the player is in + std::map< cGroup*, bool > AllGroups; // Use a map, because it's faster than iterating through a list to find duplicates + GroupList ToIterate; + for( GroupList::iterator GroupItr = m_Groups.begin(); GroupItr != m_Groups.end(); ++GroupItr ) + { + ToIterate.push_back( *GroupItr ); + } + while( ToIterate.begin() != ToIterate.end() ) + { + cGroup* CurrentGroup = *ToIterate.begin(); + if( AllGroups.find( CurrentGroup ) != AllGroups.end() ) + { + LOGWARNING("ERROR: Player \"%s\" is in the group multiple times (\"%s\"). Please fix your settings in users.ini!", + m_PlayerName.c_str(), CurrentGroup->GetName().c_str() + ); + } + else + { + AllGroups[ CurrentGroup ] = true; + m_ResolvedGroups.push_back( CurrentGroup ); // Add group to resolved list + const cGroup::GroupList & Inherits = CurrentGroup->GetInherits(); + for( cGroup::GroupList::const_iterator itr = Inherits.begin(); itr != Inherits.end(); ++itr ) + { + if( AllGroups.find( *itr ) != AllGroups.end() ) + { + LOGERROR("ERROR: Player %s is in the same group multiple times due to inheritance (%s). FIX IT!", m_PlayerName.c_str(), (*itr)->GetName().c_str() ); + continue; + } + ToIterate.push_back( *itr ); + } + } + ToIterate.erase( ToIterate.begin() ); + } +} + + + + + +AString cPlayer::GetColor(void) const +{ + if ( m_Color != '-' ) + { + return cChatColor::MakeColor( m_Color ); + } + + if ( m_Groups.size() < 1 ) + { + return cChatColor::White; + } + + return (*m_Groups.begin())->GetColor(); +} + + + + + +void cPlayer::TossItem( bool a_bDraggingItem, int a_Amount /* = 1 */ ) +{ + cItems Drops; + if (a_bDraggingItem) + { + cItem * Item = GetInventory().GetWindow()->GetDraggingItem(); + if (!Item->IsEmpty()) + { + Drops.push_back(*Item); + if( Item->m_ItemCount > a_Amount ) + Item->m_ItemCount -= (char)a_Amount; + else + Item->Empty(); + } + } + else + { + // Else drop equipped item + cItem DroppedItem = GetInventory().GetEquippedItem(); + if (!DroppedItem.IsEmpty()) + { + DroppedItem.m_ItemCount = 1; + if (GetInventory().RemoveItem(DroppedItem)) + { + DroppedItem.m_ItemCount = 1; // RemoveItem decreases the count, so set it to 1 again + Drops.push_back(DroppedItem); + } + } + } + float vX = 0, vY = 0, vZ = 0; + EulerToVector( -GetRotation(), GetPitch(), vZ, vX, vY ); + vY = -vY*2 + 1.f; + m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY() + 1.6f, GetPosZ(), vX * 2, vY * 2, vZ * 2); +} + + + + + +bool cPlayer::MoveToWorld( const char* a_WorldName ) +{ + cWorld * World = cRoot::Get()->GetWorld( a_WorldName ); + if ( World ) + { + /* Remove all links to the old world */ + m_World->RemovePlayer( this ); + m_ClientHandle->RemoveFromAllChunks(); + m_World->RemoveEntityFromChunk(this, m_ChunkX, m_ChunkY, m_ChunkZ); + + /* Add player to all the necessary parts of the new world */ + SetWorld( World ); + GetWorld()->AddPlayer( this ); + MoveToCorrectChunk(true); + GetClientHandle()->StreamChunks(); + + return true; + } + + return false; +} + + + + + +void cPlayer::LoadPermissionsFromDisk() +{ + m_Groups.clear(); + m_Permissions.clear(); + + cIniFile IniFile("users.ini"); + if( IniFile.ReadFile() ) + { + std::string Groups = IniFile.GetValue(m_PlayerName, "Groups", ""); + if( Groups.size() > 0 ) + { + AStringVector Split = StringSplit( Groups, "," ); + for( unsigned int i = 0; i < Split.size(); i++ ) + { + AddToGroup( Split[i].c_str() ); + } + } + else + { + AddToGroup("Default"); + } + + m_Color = IniFile.GetValue(m_PlayerName, "Color", "-")[0]; + } + else + { + LOGWARN("WARNING: Failed to read ini file users.ini"); + AddToGroup("Default"); + } + ResolvePermissions(); +} + + + + +bool cPlayer::LoadFromDisk() +{ + LoadPermissionsFromDisk(); + + // Log player permissions, cause it's what the cool kids do + LOGINFO("Player %s has permissions:", m_PlayerName.c_str() ); + for( PermissionMap::iterator itr = m_ResolvedPermissions.begin(); itr != m_ResolvedPermissions.end(); ++itr ) + { + if( itr->second ) LOGINFO("%s", itr->first.c_str() ); + } + + AString SourceFile; + Printf(SourceFile, "players/%s.json", m_PlayerName.c_str() ); + + cFile f; + if (!f.Open(SourceFile, cFile::fmRead)) + { + return false; + } + + AString buffer; + if (f.ReadRestOfFile(buffer) != f.GetSize()) + { + LOGERROR("ERROR READING FROM FILE \"%s\"", SourceFile.c_str()); + return false; + } + f.Close(); + + Json::Value root; + Json::Reader reader; + if (!reader.parse(buffer, root, false)) + { + LOGERROR("ERROR WHILE PARSING JSON FROM FILE %s", SourceFile.c_str()); + } + + Json::Value & JSON_PlayerPosition = root["position"]; + if( JSON_PlayerPosition.size() == 3 ) + { + m_Pos.x = JSON_PlayerPosition[(unsigned int)0].asDouble(); + m_Pos.y = JSON_PlayerPosition[(unsigned int)1].asDouble(); + m_Pos.z = JSON_PlayerPosition[(unsigned int)2].asDouble(); + } + + Json::Value & JSON_PlayerRotation = root["rotation"]; + if( JSON_PlayerRotation.size() == 3 ) + { + m_Rot.x = (float)JSON_PlayerRotation[(unsigned int)0].asDouble(); + m_Rot.y = (float)JSON_PlayerRotation[(unsigned int)1].asDouble(); + m_Rot.z = (float)JSON_PlayerRotation[(unsigned int)2].asDouble(); + } + + m_Health = (short)root.get("health", 0 ).asInt(); + m_FoodLevel = (short)root.get("food", 0 ).asInt(); + m_Inventory->LoadFromJson(root["inventory"]); + m_CreativeInventory->LoadFromJson(root["creativeinventory"]); + + m_LoadedWorldName = root.get("world", "world").asString(); + + LOGD("Player \"%s\" was read from file, spawning at {%.2f, %.2f, %.2f} in world \"%s\"", + m_PlayerName.c_str(), m_Pos.x, m_Pos.y, m_Pos.z, m_LoadedWorldName.c_str() + ); + + return true; +} + + + + + +bool cPlayer::SaveToDisk() +{ + cMakeDir::MakeDir("players"); + + // create the JSON data + Json::Value JSON_PlayerPosition; + JSON_PlayerPosition.append( Json::Value( m_Pos.x ) ); + JSON_PlayerPosition.append( Json::Value( m_Pos.y ) ); + JSON_PlayerPosition.append( Json::Value( m_Pos.z ) ); + + Json::Value JSON_PlayerRotation; + JSON_PlayerRotation.append( Json::Value( m_Rot.x ) ); + JSON_PlayerRotation.append( Json::Value( m_Rot.y ) ); + JSON_PlayerRotation.append( Json::Value( m_Rot.z ) ); + + Json::Value JSON_Inventory; + m_Inventory->SaveToJson( JSON_Inventory ); + + Json::Value JSON_CreativeInventory; + m_CreativeInventory->SaveToJson( JSON_CreativeInventory ); + + Json::Value root; + root["position"] = JSON_PlayerPosition; + root["rotation"] = JSON_PlayerRotation; + root["inventory"] = JSON_Inventory; + root["creativeinventory"] = JSON_CreativeInventory; + root["health"] = m_Health; + root["food"] = m_FoodLevel; + root["world"] = GetWorld()->GetName(); + + Json::StyledWriter writer; + std::string JsonData = writer.write( root ); + + AString SourceFile; + Printf(SourceFile, "players/%s.json", m_PlayerName.c_str() ); + + cFile f; + if (!f.Open(SourceFile, cFile::fmWrite)) + { + LOGERROR("ERROR WRITING PLAYER \"%s\" TO FILE \"%s\" - cannot open file", m_PlayerName.c_str(), SourceFile.c_str()); + return false; + } + if (f.Write(JsonData.c_str(), JsonData.size()) != (int)JsonData.size()) + { + LOGERROR("ERROR WRITING PLAYER JSON TO FILE \"%s\"", SourceFile.c_str()); + return false; + } + return true; +} + + + + + +cPlayer::StringList cPlayer::GetResolvedPermissions() +{ + StringList Permissions; + + const PermissionMap& ResolvedPermissions = m_ResolvedPermissions; + for( PermissionMap::const_iterator itr = ResolvedPermissions.begin(); itr != ResolvedPermissions.end(); ++itr ) + { + if( itr->second ) Permissions.push_back( itr->first ); + } + + return Permissions; +} + + + + + +void cPlayer::UseEquippedItem() +{ + if(GetGameMode() != 1) //No damage in creative + { + if (GetInventory().GetEquippedItem().DamageItem()) + { + LOG("Player %s Broke ID: %i", GetClientHandle()->GetUsername().c_str(), GetInventory().GetEquippedItem().m_ItemID); + GetInventory().RemoveItem( GetInventory().GetEquippedItem()); + } + } +} + + + + + +bool cPlayer::EatItem(int a_ItemType) +{ + // TODO: Handle hunger + switch (a_ItemType) + { + case E_ITEM_APPLE: return Feed(24); // 2 food bars + case E_ITEM_GOLDEN_APPLE: return Feed(60); // 5 food + case E_ITEM_MUSHROOM_SOUP: return Feed(48); // 4 food + case E_ITEM_BREAD: return Feed(30); // 2.5 food + case E_ITEM_RAW_MEAT: return Feed(18); // 1.5 food + case E_ITEM_COOKED_MEAT: return Feed(48); // 4 food + case E_ITEM_RAW_FISH: return Feed(12); // 1 food + case E_ITEM_COOKED_FISH: return Feed(30); // 2.5 food + case E_ITEM_COOKED_CHICKEN: return Feed(36); // 3 food + case E_ITEM_RAW_BEEF: return Feed(18); // 1.5 food + case E_ITEM_STEAK: return Feed(48); // 4 food + case E_ITEM_RAW_CHICKEN: + { + if (!Feed(12)) // 1 food + { + return false; + } + // TODO: A random chance to get food-poisoned + return true; + } + + case E_ITEM_ROTTEN_FLESH: + { + if (!Feed(24)) + { + return false; + } + // TODO: Food-poisoning + return true; + } + } + return false; +} + + + + diff --git a/source/cPlayer.h b/source/cPlayer.h index 815c31316..ef85a1d4e 100644 --- a/source/cPlayer.h +++ b/source/cPlayer.h @@ -1,146 +1,146 @@ - -#pragma once - -#include "cPawn.h" -#include "cSurvivalInventory.h" -#include "cCreativeInventory.h" -#include "Defines.h" - - - - - -class cGroup; -class cWindow; -class cInventory; -class cClientHandle; - - - - - -class cPlayer : public cPawn //tolua_export -{ //tolua_export -public: - typedef cPawn super; - CLASS_PROTOTYPE(); - - cPlayer(cClientHandle * a_Client, const AString & a_PlayerName); - virtual ~cPlayer(); - - virtual void Initialize( cWorld* a_World ); //tolua_export - - virtual cPacket * GetSpawnPacket(void) const override; - virtual void Tick(float a_Dt) override; - - void SetTouchGround( bool a_bTouchGround ); - inline void SetStance( const double & a_Stance ) { m_Stance = a_Stance; } - double GetEyeHeight(); //tolua_export - Vector3d GetEyePosition(); //tolua_export - inline bool GetFlying() { return m_bTouchGround; } //tolua_export - inline const double & GetStance() { return m_Stance; } //tolua_export - inline cInventory & GetInventory() { if(GetGameMode() == eGameMode_Survival) return *m_Inventory; else return *m_CreativeInventory; } //tolua_export - - virtual void TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ); //tolua_export - - eGameMode GetGameMode() { return m_GameMode; } //tolua_export - std::string GetIP() { return m_IP; } //tolua_export - float GetLastBlockActionTime() { return m_LastBlockActionTime; } //tolua_export - int GetLastBlockActionCnt() { return m_LastBlockActionCnt; } //tolua_export - void SetLastBlockActionCnt( int ); //tolua_export - void SetLastBlockActionTime(); //tolua_export - void SetGameMode( eGameMode a_GameMode ); //tolua_export - void LoginSetGameMode( eGameMode a_GameMode ); - void SetIP( std::string a_IP ); - - // Tries to move to a new position, with collision checks and stuff - virtual void MoveTo( const Vector3d & a_NewPos ); //tolua_export - - cWindow* GetWindow() { return m_CurrentWindow; } - void OpenWindow( cWindow* a_Window ); - void CloseWindow(char a_WindowType); - - cClientHandle * GetClientHandle() { return m_ClientHandle; } //tolua_export - - void SendMessage( const char* a_Message ); //tolua_export - - const AString & GetName(void) const { return m_PlayerName; } //tolua_export - void SetName(const AString & a_Name) { m_PlayerName = a_Name; } //tolua_export - - typedef std::list< cGroup* > GroupList; - typedef std::list< std::string > StringList; - void AddToGroup( const char* a_GroupName ); //tolua_export - bool CanUseCommand( const char* a_Command ); //tolua_export - bool HasPermission( const char* a_Permission ); //tolua_export - const GroupList & GetGroups() { return m_Groups; } // >> EXPORTED IN MANUALBINDINGS << - StringList GetResolvedPermissions(); // >> EXPORTED IN MANUALBINDINGS << - bool IsInGroup( const char* a_Group ); //tolua_export - - AString GetColor(void) const; //tolua_export - - void TossItem( bool a_bDraggingItem, int a_Amount = 1 ); //tolua_export - - void Heal( int a_Health ); //tolua_export - - /// Returns true if any food has been consumed, false if player "full" - bool Feed(short a_Food); - - void TakeDamage( int a_Damage, cEntity* a_Instigator ); //tolua_export - void KilledBy( cEntity* a_Killer ); //tolua_export - void Respawn(); //tolua_export - - void SetVisible( bool a_bVisible ); //tolua_export - bool IsVisible() { return m_bVisible; } //tolua_export - - bool MoveToWorld( const char* a_WorldName ); //tolua_export - - bool SaveToDisk(); - bool LoadFromDisk(); - void LoadPermissionsFromDisk(); //tolua_export - - const AString & GetLoadedWorldName() { return m_LoadedWorldName; } - - void UseEquippedItem(void); - - /// Returns true if the item type is edible && it has been consumed, false otherwise - bool EatItem(int a_ItemType); - -protected: - virtual void Destroyed(); - - typedef std::map< std::string, bool > PermissionMap; - PermissionMap m_ResolvedPermissions; - PermissionMap m_Permissions; - - GroupList m_ResolvedGroups; - GroupList m_Groups; - - std::string m_PlayerName; - std::string m_LoadedWorldName; - - bool m_bVisible; - - float m_LastGroundHeight; - bool m_bTouchGround; - double m_Stance; - cSurvivalInventory* m_Inventory; - cCreativeInventory* m_CreativeInventory; - cWindow* m_CurrentWindow; - - float m_TimeLastPickupCheck; - - void ResolvePermissions(); - - void ResolveGroups(); - char m_Color; - - float m_LastBlockActionTime; - int m_LastBlockActionCnt; - eGameMode m_GameMode; - std::string m_IP; - - long long m_LastPlayerListTime; - static const unsigned short PLAYER_LIST_TIME_MS = 1000; // 1000 = once per second - - cClientHandle* m_ClientHandle; -}; //tolua_export + +#pragma once + +#include "cPawn.h" +#include "cSurvivalInventory.h" +#include "cCreativeInventory.h" +#include "Defines.h" + + + + + +class cGroup; +class cWindow; +class cInventory; +class cClientHandle; + + + + + +class cPlayer : public cPawn //tolua_export +{ //tolua_export +public: + typedef cPawn super; + CLASS_PROTOTYPE(); + + cPlayer(cClientHandle * a_Client, const AString & a_PlayerName); + virtual ~cPlayer(); + + virtual void Initialize( cWorld* a_World ); //tolua_export + + virtual cPacket * GetSpawnPacket(void) const override; + virtual void Tick(float a_Dt) override; + + void SetTouchGround( bool a_bTouchGround ); + inline void SetStance( const double & a_Stance ) { m_Stance = a_Stance; } + double GetEyeHeight(); //tolua_export + Vector3d GetEyePosition(); //tolua_export + inline bool GetFlying() { return m_bTouchGround; } //tolua_export + inline const double & GetStance() { return m_Stance; } //tolua_export + inline cInventory & GetInventory() { if(GetGameMode() == eGameMode_Survival) return *m_Inventory; else return *m_CreativeInventory; } //tolua_export + + virtual void TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ); //tolua_export + + eGameMode GetGameMode() { return m_GameMode; } //tolua_export + std::string GetIP() { return m_IP; } //tolua_export + float GetLastBlockActionTime() { return m_LastBlockActionTime; } //tolua_export + int GetLastBlockActionCnt() { return m_LastBlockActionCnt; } //tolua_export + void SetLastBlockActionCnt( int ); //tolua_export + void SetLastBlockActionTime(); //tolua_export + void SetGameMode( eGameMode a_GameMode ); //tolua_export + void LoginSetGameMode( eGameMode a_GameMode ); + void SetIP( std::string a_IP ); + + // Tries to move to a new position, with collision checks and stuff + virtual void MoveTo( const Vector3d & a_NewPos ); //tolua_export + + cWindow* GetWindow() { return m_CurrentWindow; } + void OpenWindow( cWindow* a_Window ); + void CloseWindow(char a_WindowType); + + cClientHandle * GetClientHandle() { return m_ClientHandle; } //tolua_export + + void SendMessage( const char* a_Message ); //tolua_export + + const AString & GetName(void) const { return m_PlayerName; } //tolua_export + void SetName(const AString & a_Name) { m_PlayerName = a_Name; } //tolua_export + + typedef std::list< cGroup* > GroupList; + typedef std::list< std::string > StringList; + void AddToGroup( const char* a_GroupName ); //tolua_export + bool CanUseCommand( const char* a_Command ); //tolua_export + bool HasPermission( const char* a_Permission ); //tolua_export + const GroupList & GetGroups() { return m_Groups; } // >> EXPORTED IN MANUALBINDINGS << + StringList GetResolvedPermissions(); // >> EXPORTED IN MANUALBINDINGS << + bool IsInGroup( const char* a_Group ); //tolua_export + + AString GetColor(void) const; //tolua_export + + void TossItem( bool a_bDraggingItem, int a_Amount = 1 ); //tolua_export + + void Heal( int a_Health ); //tolua_export + + /// Returns true if any food has been consumed, false if player "full" + bool Feed(short a_Food); + + void TakeDamage( int a_Damage, cEntity* a_Instigator ); //tolua_export + void KilledBy( cEntity* a_Killer ); //tolua_export + void Respawn(); //tolua_export + + void SetVisible( bool a_bVisible ); //tolua_export + bool IsVisible() { return m_bVisible; } //tolua_export + + bool MoveToWorld( const char* a_WorldName ); //tolua_export + + bool SaveToDisk(); + bool LoadFromDisk(); + void LoadPermissionsFromDisk(); //tolua_export + + const AString & GetLoadedWorldName() { return m_LoadedWorldName; } + + void UseEquippedItem(void); + + /// Returns true if the item type is edible && it has been consumed, false otherwise + bool EatItem(int a_ItemType); + +protected: + virtual void Destroyed(); + + typedef std::map< std::string, bool > PermissionMap; + PermissionMap m_ResolvedPermissions; + PermissionMap m_Permissions; + + GroupList m_ResolvedGroups; + GroupList m_Groups; + + std::string m_PlayerName; + std::string m_LoadedWorldName; + + bool m_bVisible; + + float m_LastGroundHeight; + bool m_bTouchGround; + double m_Stance; + cSurvivalInventory* m_Inventory; + cCreativeInventory* m_CreativeInventory; + cWindow* m_CurrentWindow; + + float m_TimeLastPickupCheck; + + void ResolvePermissions(); + + void ResolveGroups(); + char m_Color; + + float m_LastBlockActionTime; + int m_LastBlockActionCnt; + eGameMode m_GameMode; + std::string m_IP; + + long long m_LastPlayerListTime; + static const unsigned short PLAYER_LIST_TIME_MS = 1000; // 1000 = once per second + + cClientHandle* m_ClientHandle; +}; //tolua_export diff --git a/source/cPlugin.cpp b/source/cPlugin.cpp index aa8dab01e..61471d8f0 100644 --- a/source/cPlugin.cpp +++ b/source/cPlugin.cpp @@ -1,84 +1,84 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPlugin.h" - - - - - -cPlugin::cPlugin() - : m_Version( 0 ) - , m_Language( E_CPP ) - , m_bCanBindCommands( false ) -{ -} - -cPlugin::~cPlugin() -{ -} - -// bool cPlugin::Initialize() -// { -// LOG("cPlugin::Initialize()"); -// return false; -// } - -void cPlugin::Tick(float a_Dt) -{ - (void)a_Dt; -} - -bool cPlugin::OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player ) -{ - (void)a_PacketData; - (void)a_Player; - return false; -} - -bool cPlugin::OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player ) -{ - (void)a_Pickup; - (void)a_Player; - return false; -} - -bool cPlugin::OnDisconnect(const AString & a_Reason, cPlayer* a_Player ) -{ - (void)a_Reason; - (void)a_Player; - return false; -} - -bool cPlugin::OnChat( const char* a_Chat, cPlayer* a_Player ) -{ - (void)a_Chat; - (void)a_Player; - return false; -} - -bool cPlugin::OnLogin( cPacket_Login* a_PacketData ) -{ - (void)a_PacketData; - return false; -} - -void cPlugin::OnPlayerSpawn( cPlayer* a_Player ) -{ - (void)a_Player; -} - -bool cPlugin::OnPlayerJoin( cPlayer* a_Player ) -{ - (void)a_Player; - return false; -} - -void cPlugin::AddCommand( std::string & a_Command, std::string & a_Description, std::string & a_Permission ) -{ - CommandStruct Command; - Command.Command = a_Command; - Command.Description = a_Description; - Command.Permission = a_Permission; - m_Commands.push_back( Command ); -} + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPlugin.h" + + + + + +cPlugin::cPlugin() + : m_Version( 0 ) + , m_Language( E_CPP ) + , m_bCanBindCommands( false ) +{ +} + +cPlugin::~cPlugin() +{ +} + +// bool cPlugin::Initialize() +// { +// LOG("cPlugin::Initialize()"); +// return false; +// } + +void cPlugin::Tick(float a_Dt) +{ + (void)a_Dt; +} + +bool cPlugin::OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player ) +{ + (void)a_PacketData; + (void)a_Player; + return false; +} + +bool cPlugin::OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player ) +{ + (void)a_Pickup; + (void)a_Player; + return false; +} + +bool cPlugin::OnDisconnect(const AString & a_Reason, cPlayer* a_Player ) +{ + (void)a_Reason; + (void)a_Player; + return false; +} + +bool cPlugin::OnChat( const char* a_Chat, cPlayer* a_Player ) +{ + (void)a_Chat; + (void)a_Player; + return false; +} + +bool cPlugin::OnLogin( cPacket_Login* a_PacketData ) +{ + (void)a_PacketData; + return false; +} + +void cPlugin::OnPlayerSpawn( cPlayer* a_Player ) +{ + (void)a_Player; +} + +bool cPlugin::OnPlayerJoin( cPlayer* a_Player ) +{ + (void)a_Player; + return false; +} + +void cPlugin::AddCommand( std::string & a_Command, std::string & a_Description, std::string & a_Permission ) +{ + CommandStruct Command; + Command.Command = a_Command; + Command.Description = a_Description; + Command.Permission = a_Permission; + m_Commands.push_back( Command ); +} diff --git a/source/cPlugin.h b/source/cPlugin.h index 4c72b300e..4d32396e8 100644 --- a/source/cPlugin.h +++ b/source/cPlugin.h @@ -1,113 +1,113 @@ - -#pragma once - -#include "cItem.h" - -class cPacket_BlockPlace; -class cPacket_PickupSpawn; -class cPacket_EntityEquipment; -class cPacket_Disconnect; -class cPacket_Chat; -class cPacket_BlockDig; -class cPacket_Login; -class cClientHandle; -class cPlayer; -class cPickup; -class cItem; -class cEntity; -class cPawn; -class cWorld; -class cLuaChunk; -struct TakeDamageInfo; - -// fwd: cPlayer.h -class cPlayer; - -// fwd: CraftingRecipes.h -class cCraftingGrid; -class cCraftingRecipe; - - - - - -// tolua_begin -class cPlugin -{ -public: - cPlugin(); - virtual ~cPlugin(); - - virtual void OnDisable() {} - virtual bool Initialize() = 0; - - // Called each tick - virtual void Tick(float a_Dt); - - /** - * On all these functions, return true if you want to override default behavior - * You can also return false, so default behavior is used, but with changed PacketData - **/ - virtual bool OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player ); - virtual bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player ); - virtual bool OnBlockPlace (cPacket_BlockPlace* a_PacketData, cPlayer* a_Player ); - virtual bool OnBlockDig (cPacket_BlockDig * a_PacketData, cPlayer* a_Player, cItem* a_PickupItem ) { (void)a_PacketData; (void)a_Player; (void)a_PickupItem; return false; } - virtual bool OnChat (const char * a_Chat, cPlayer* a_Player ); - virtual bool OnLogin (cPacket_Login* a_PacketData ); - virtual void OnPlayerSpawn (cPlayer* a_Player ); - virtual bool OnPlayerJoin (cPlayer* a_Player ); - virtual void OnPlayerMove (cPlayer* a_Player ) { (void)a_Player; } - virtual void OnTakeDamage (cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo ) { (void)a_Pawn; (void)a_TakeDamageInfo; } - virtual bool OnKilled (cPawn* a_Killed, cEntity* a_Killer ) { (void)a_Killed; (void)a_Killer; return false; } - virtual void OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ) {} - virtual bool OnChunkGenerating (int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) { return false; } - virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) {return false; } - virtual bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) {return false; } - virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) {return false; } - virtual bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups) {return false; } - - // Accessors - const char* GetName() const { return m_Name.c_str(); } - void SetName( const char* a_Name ) { m_Name = a_Name; } - - int GetVersion() const { return m_Version; } - void SetVersion( int a_Version ) { m_Version = a_Version; } - - struct CommandStruct - { - std::string Command; - std::string Description; - std::string Permission; - }; - - void AddCommand( std::string & a_Command, std::string & a_Description, std::string & a_Permission ); - // tolua_end - typedef bool (FuncCommandHandler)( std::string & a_Command, std::vector< std::string > & a_Split ); - void BindCommand( FuncCommandHandler* a_Function, std::string & a_Command ); // >> EXPORTED IN MANUALBINDINGS << - const std::vector< CommandStruct > & GetCommands() const { return m_Commands; } // >> EXPORTED IN MANUALBINDINGS << - - - /* This should not be exposed to scripting languages */ - enum PluginLanguage - { - E_CPP, - E_LUA, - E_SQUIRREL, - }; - PluginLanguage GetLanguage() { return m_Language; } - void SetLanguage( PluginLanguage a_Language ) { m_Language = a_Language; } - - bool CanBindCommands() { return m_bCanBindCommands; } -private: - friend class cPluginManager; - bool m_bCanBindCommands; // Only changed by cPluginManager - - PluginLanguage m_Language; - std::vector< CommandStruct > m_Commands; - std::string m_Name; - int m_Version; -}; //tolua_export - - - - + +#pragma once + +#include "cItem.h" + +class cPacket_BlockPlace; +class cPacket_PickupSpawn; +class cPacket_EntityEquipment; +class cPacket_Disconnect; +class cPacket_Chat; +class cPacket_BlockDig; +class cPacket_Login; +class cClientHandle; +class cPlayer; +class cPickup; +class cItem; +class cEntity; +class cPawn; +class cWorld; +class cLuaChunk; +struct TakeDamageInfo; + +// fwd: cPlayer.h +class cPlayer; + +// fwd: CraftingRecipes.h +class cCraftingGrid; +class cCraftingRecipe; + + + + + +// tolua_begin +class cPlugin +{ +public: + cPlugin(); + virtual ~cPlugin(); + + virtual void OnDisable() {} + virtual bool Initialize() = 0; + + // Called each tick + virtual void Tick(float a_Dt); + + /** + * On all these functions, return true if you want to override default behavior + * You can also return false, so default behavior is used, but with changed PacketData + **/ + virtual bool OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player ); + virtual bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player ); + virtual bool OnBlockPlace (cPacket_BlockPlace* a_PacketData, cPlayer* a_Player ); + virtual bool OnBlockDig (cPacket_BlockDig * a_PacketData, cPlayer* a_Player, cItem* a_PickupItem ) { (void)a_PacketData; (void)a_Player; (void)a_PickupItem; return false; } + virtual bool OnChat (const char * a_Chat, cPlayer* a_Player ); + virtual bool OnLogin (cPacket_Login* a_PacketData ); + virtual void OnPlayerSpawn (cPlayer* a_Player ); + virtual bool OnPlayerJoin (cPlayer* a_Player ); + virtual void OnPlayerMove (cPlayer* a_Player ) { (void)a_Player; } + virtual void OnTakeDamage (cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo ) { (void)a_Pawn; (void)a_TakeDamageInfo; } + virtual bool OnKilled (cPawn* a_Killed, cEntity* a_Killer ) { (void)a_Killed; (void)a_Killer; return false; } + virtual void OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ) {} + virtual bool OnChunkGenerating (int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) { return false; } + virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) {return false; } + virtual bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) {return false; } + virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) {return false; } + virtual bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups) {return false; } + + // Accessors + const char* GetName() const { return m_Name.c_str(); } + void SetName( const char* a_Name ) { m_Name = a_Name; } + + int GetVersion() const { return m_Version; } + void SetVersion( int a_Version ) { m_Version = a_Version; } + + struct CommandStruct + { + std::string Command; + std::string Description; + std::string Permission; + }; + + void AddCommand( std::string & a_Command, std::string & a_Description, std::string & a_Permission ); + // tolua_end + typedef bool (FuncCommandHandler)( std::string & a_Command, std::vector< std::string > & a_Split ); + void BindCommand( FuncCommandHandler* a_Function, std::string & a_Command ); // >> EXPORTED IN MANUALBINDINGS << + const std::vector< CommandStruct > & GetCommands() const { return m_Commands; } // >> EXPORTED IN MANUALBINDINGS << + + + /* This should not be exposed to scripting languages */ + enum PluginLanguage + { + E_CPP, + E_LUA, + E_SQUIRREL, + }; + PluginLanguage GetLanguage() { return m_Language; } + void SetLanguage( PluginLanguage a_Language ) { m_Language = a_Language; } + + bool CanBindCommands() { return m_bCanBindCommands; } +private: + friend class cPluginManager; + bool m_bCanBindCommands; // Only changed by cPluginManager + + PluginLanguage m_Language; + std::vector< CommandStruct > m_Commands; + std::string m_Name; + int m_Version; +}; //tolua_export + + + + diff --git a/source/cPluginManager.cpp b/source/cPluginManager.cpp index 19518bc9b..c686c9976 100644 --- a/source/cPluginManager.cpp +++ b/source/cPluginManager.cpp @@ -1,749 +1,749 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPluginManager.h" -#include "cPlugin.h" -#include "cPlugin_Lua.h" -#include "cPlugin_NewLua.h" -#include "cWebAdmin.h" -#include "cItem.h" -#include "cRoot.h" -#include "cLuaCommandBinder.h" -#include "../iniFile/iniFile.h" -#include "tolua++.h" - -#include "SquirrelBindings.h" -#if USE_SQUIRREL - #pragma warning(disable:4100;disable:4127;disable:4510;disable:4610;disable:4244;disable:4512) // Getting A LOT of these warnings from SqPlus - #include - #pragma warning(default:4100;default:4127;default:4510;default:4610;default:4244;default:4512) -#endif - - - - - -cPluginManager* cPluginManager::GetPluginManager() -{ - LOGWARN("WARNING: Using deprecated function cPluginManager::GetPluginManager() use cRoot::Get()->GetPluginManager() instead!"); - return cRoot::Get()->GetPluginManager(); -} - - - - - -cPluginManager::cPluginManager() - : m_LuaCommandBinder( new cLuaCommandBinder() ) - , m_bReloadPlugins(false) -{ -} - - - - - -cPluginManager::~cPluginManager() -{ - UnloadPluginsNow(); - - delete m_LuaCommandBinder; -} - - - - - -void cPluginManager::ReloadPlugins() -{ - m_bReloadPlugins = true; -} - - - - - -void cPluginManager::ReloadPluginsNow() -{ - LOG("Loading plugins"); - m_bReloadPlugins = false; - UnloadPluginsNow(); - - #if USE_SQUIRREL - if( !SquirrelBindings::IsBound ) // Can only do this once apparently, or we're making ambiguous calls in the script - { - SquirrelVM::Init(); - SquirrelBindings::Bind( SquirrelVM::GetVMPtr() ); - } - #endif // USE_SQUIRREL - - cIniFile IniFile("settings.ini"); - if (!IniFile.ReadFile() ) - { - LOGWARNING("cPluginManager: Can't find settings.ini, so can't load any plugins."); - } - - unsigned int KeyNum = IniFile.FindKey("Plugins"); - unsigned int NumPlugins = IniFile.GetNumValues( KeyNum ); - if( NumPlugins > 0 ) - { - for(unsigned int i = 0; i < NumPlugins; i++) - { - AString ValueName = IniFile.GetValueName(KeyNum, i ); - if( ValueName.compare("Plugin") == 0 ) // It's a Lua plugin - { - AString PluginFile = IniFile.GetValue(KeyNum, i ); - if( !PluginFile.empty() ) - { - // allow for comma separated plugin list - // degrades and works fine for the plugin - // per line - AStringVector split = StringSplit( PluginFile, "," ); - for (unsigned int j = 0; j < split.size(); j++) - { - cPlugin_Lua* Plugin = new cPlugin_Lua( (split[j] + AString(".lua") ).c_str() ); - if( !AddLuaPlugin( Plugin ) ) - { - delete Plugin; - } - } - } - } - else if( ValueName.compare("NewPlugin") == 0 ) // New plugin style - { - AString PluginFile = IniFile.GetValue(KeyNum, i ); - if( !PluginFile.empty() ) - { - cPlugin_NewLua* Plugin = new cPlugin_NewLua( PluginFile.c_str() ); - if( !AddPlugin( Plugin ) ) - { - delete Plugin; - } - } - } - - #if USE_SQUIRREL - else if( ValueName.compare("Squirrel") == 0 ) // Squirrel plugin - { - AString PluginFile = IniFile.GetValue(KeyNum, i ); - if( !PluginFile.empty() ) - { - LOGINFO("Loading Squirrel plugin: %s", PluginFile.c_str() ); - try - { - SquirrelObject SquirrelScript = SquirrelVM::CompileScript( (AString("Plugins/") + PluginFile + ".nut").c_str() ); - try - { - SquirrelVM::RunScript( SquirrelScript ); - } - catch (SquirrelError & e) - { - LOGERROR("SquirrelScript error: %s, %s\n", e.desc, "SquirrelVM::RunScript"); - } - } - catch (SquirrelError & e) - { - LOGERROR("SquirrelScript error: %s, %s\n", e.desc, "SquirrelVM::CompileScript"); - } - } - } - #endif // USE_SQUIRREL - - } - } - - if( GetNumPlugins() == 0 ) - { - LOG("No plugins loaded"); - } - else - { - LOG("Loaded %i plugin(s)", GetNumPlugins() ); - } -} - - - - - -void cPluginManager::Tick(float a_Dt) -{ - if( m_bReloadPlugins ) - { - ReloadPluginsNow(); - } - - HookMap::iterator Plugins = m_Hooks.find( E_PLUGIN_TICK ); - if( Plugins != m_Hooks.end() ) - { - for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) - { - (*itr)->Tick( a_Dt ); - } - } -} - - - - - -bool cPluginManager::CallHook(PluginHook a_Hook, unsigned int a_NumArgs, ...) -{ - HookMap::iterator Plugins = m_Hooks.find( a_Hook ); - - // Special case for chat hook, since you can also bind commands (bound commands don't use chat hook) - if (a_Hook == HOOK_CHAT) - { - if (a_NumArgs != 2) - { - return false; - } - va_list argptr; - va_start( argptr, a_NumArgs); - const char * Message = va_arg(argptr, const char* ); - cPlayer * Player = va_arg(argptr, cPlayer * ); - va_end (argptr); - - if (m_LuaCommandBinder->HandleCommand( std::string( Message ), Player)) - { - return true; - } - - if (Plugins == m_Hooks.end()) - { - return false; - } - - for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) - { - if ((*itr)->OnChat(Message, Player)) - { - return true; - } - } - return false; - } - - if (Plugins == m_Hooks.end()) - { - return false; - } - - switch( a_Hook ) - { - case HOOK_COLLECT_ITEM: - { - if( a_NumArgs != 2 ) break; - va_list argptr; - va_start( argptr, a_NumArgs); - cPickup* Pickup = va_arg(argptr, cPickup* ); - cPlayer* Player = va_arg(argptr, cPlayer* ); - va_end (argptr); - for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) - { - if( (*itr)->OnCollectItem( Pickup, Player ) ) - return true; - } - break; - } - - case HOOK_BLOCK_DIG: - { - if( a_NumArgs != 2 ) break; - va_list argptr; - va_start( argptr, a_NumArgs); - cPacket_BlockDig* Packet = va_arg(argptr, cPacket_BlockDig* ); - cPlayer* Player = va_arg(argptr, cPlayer* ); - cItem* Item = va_arg( argptr, cItem* ); - va_end (argptr); - for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) - { - if( (*itr)->OnBlockDig( Packet, Player, Item ) ) - return true; - } - break; - } - - case HOOK_BLOCK_PLACE: - { - if( a_NumArgs != 2 ) break; - va_list argptr; - va_start( argptr, a_NumArgs); - cPacket_BlockPlace* Packet = va_arg(argptr, cPacket_BlockPlace* ); - cPlayer* Player = va_arg(argptr, cPlayer* ); - va_end (argptr); - for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) - { - if( (*itr)->OnBlockPlace( Packet, Player ) ) - return true; - } - break; - } - - case HOOK_DISCONNECT: - { - if( a_NumArgs != 2 ) break; - va_list argptr; - va_start( argptr, a_NumArgs); - const char* Reason = va_arg(argptr, const char* ); - cPlayer* Player = va_arg(argptr, cPlayer* ); - va_end (argptr); - for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) - { - if( (*itr)->OnDisconnect( Reason, Player ) ) - return true; - } - break; - } - - case HOOK_LOGIN: - { - if( a_NumArgs != 1 ) break; - va_list argptr; - va_start( argptr, a_NumArgs); - cPacket_Login* Packet = va_arg(argptr, cPacket_Login* ); - va_end (argptr); - for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) - { - if( (*itr)->OnLogin( Packet ) ) - return true; - } - break; - } - - case HOOK_PLAYER_JOIN: - { - if( a_NumArgs != 1 ) break; - va_list argptr; - va_start( argptr, a_NumArgs); - cPlayer* Player = va_arg(argptr, cPlayer* ); - va_end (argptr); - for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) - { - if( (*itr)->OnPlayerJoin( Player ) ) - return true; - } - break; - } - - case HOOK_PLAYER_MOVE: - { - if( a_NumArgs != 1 ) break; - va_list argptr; - va_start( argptr, a_NumArgs); - cPlayer* Player = va_arg(argptr, cPlayer* ); - va_end (argptr); - for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) - { - (*itr)->OnPlayerMove( Player ); - } - break; - } - - case HOOK_TAKE_DAMAGE: - { - if( a_NumArgs != 2 ) break; - va_list argptr; - va_start( argptr, a_NumArgs); - cPawn* Pawn = va_arg(argptr, cPawn* ); - TakeDamageInfo* TDI = va_arg(argptr, TakeDamageInfo* ); - va_end (argptr); - for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) - { - (*itr)->OnTakeDamage( Pawn, TDI ); - } - break; - } - - case HOOK_KILLED: - { - if( a_NumArgs != 2 ) break; - va_list argptr; - va_start( argptr, a_NumArgs); - cPawn* Killed = va_arg(argptr, cPawn* ); - cEntity* Killer = va_arg(argptr, cEntity* ); - va_end (argptr); - for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) - { - if( (*itr)->OnKilled( Killed, Killer ) ) - return true; - } - break; - } - - case HOOK_CHUNK_GENERATED: - { - if (a_NumArgs != 3) - { - break; - } - va_list argptr; - va_start( argptr, a_NumArgs); - cWorld * World = va_arg(argptr, cWorld *); - int ChunkX = va_arg(argptr, int); - int ChunkZ = va_arg(argptr, int); - va_end (argptr); - for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) - { - (*itr)->OnChunkGenerated(World, ChunkX, ChunkZ); - } - break; - } - - case HOOK_CHUNK_GENERATING: - { - if (a_NumArgs != 3) - { - break; - } - va_list argptr; - va_start( argptr, a_NumArgs); - int ChunkX = va_arg(argptr, int); - int ChunkZ = va_arg(argptr, int); - cLuaChunk * LuaChunk = va_arg(argptr, cLuaChunk *); - va_end (argptr); - for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) - { - if ((*itr)->OnChunkGenerating(ChunkX, ChunkZ, LuaChunk)) - { - return true; - } - } - break; - } - - default: - { - LOGWARNING("cPluginManager: Calling Unknown hook: %i", a_Hook ); - ASSERT(!"Calling an unknown hook"); - break; - } - } // switch (a_Hook) - return false; -} - - - - - -bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) -{ - HookMap::iterator Plugins = m_Hooks.find(HOOK_PRE_CRAFTING); - if (Plugins == m_Hooks.end()) - { - return false; - } - for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) - { - if ((*itr)->OnPreCrafting(a_Player, a_Grid, a_Recipe)) - { - return true; - } - } - return false; -} - - - - - -bool cPluginManager::CallHookCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) -{ - HookMap::iterator Plugins = m_Hooks.find(HOOK_CRAFTING_NO_RECIPE); - if (Plugins == m_Hooks.end()) - { - return false; - } - for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) - { - if ((*itr)->OnCraftingNoRecipe(a_Player, a_Grid, a_Recipe)) - { - return true; - } - } - return false; -} - - - - - -bool cPluginManager::CallHookPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) -{ - HookMap::iterator Plugins = m_Hooks.find(HOOK_POST_CRAFTING); - if (Plugins == m_Hooks.end()) - { - return false; - } - for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) - { - if ((*itr)->OnPostCrafting(a_Player, a_Grid, a_Recipe)) - { - return true; - } - } - return false; -} - - - - - -bool cPluginManager::CallHookBlockToPickup( - BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, - const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups -) -{ - HookMap::iterator Plugins = m_Hooks.find(HOOK_POST_CRAFTING); - if (Plugins == m_Hooks.end()) - { - return false; - } - for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) - { - if ((*itr)->OnBlockToPickup(a_BlockType, a_BlockMeta, a_Player, a_EquippedItem, a_Pickups)) - { - return true; - } - } - return false; -} - - - - - -cPlugin* cPluginManager::GetPlugin( const char* a_Plugin ) const -{ - for( PluginList::const_iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); ++itr ) - { - if (strcmp((*itr)->GetName(), a_Plugin) == 0 ) - { - return *itr; - } - } - return 0; -} - - - - - -const cPluginManager::PluginList & cPluginManager::GetAllPlugins() const -{ - return m_Plugins; -} - - - - - -void cPluginManager::UnloadPluginsNow() -{ - m_Hooks.clear(); - - while( m_LuaPlugins.size() > 0 ) - { - cPlugin_Lua* LuaPlugin = *m_LuaPlugins.begin(); - if( LuaPlugin ) - { - cWebAdmin* WebAdmin = cRoot::Get()->GetWebAdmin(); - if( WebAdmin ) WebAdmin->RemovePlugin( LuaPlugin->GetLuaState() ); - delete LuaPlugin; - } - m_LuaPlugins.remove( LuaPlugin ); - } - - while( m_Plugins.size() > 0 ) - { - RemovePlugin( *m_Plugins.begin(), true ); - } - - //SquirrelVM::Shutdown(); // This breaks shit -} - - - - - -void cPluginManager::RemoveHooks( cPlugin* a_Plugin ) -{ - m_Hooks[ E_PLUGIN_TICK].remove ( a_Plugin ); - m_Hooks[ E_PLUGIN_CHAT].remove ( a_Plugin ); - m_Hooks[ E_PLUGIN_COLLECT_ITEM].remove ( a_Plugin ); - m_Hooks[ E_PLUGIN_BLOCK_DIG].remove ( a_Plugin ); - m_Hooks[ E_PLUGIN_BLOCK_PLACE].remove ( a_Plugin ); - m_Hooks[ E_PLUGIN_DISCONNECT].remove ( a_Plugin ); - m_Hooks[ E_PLUGIN_HANDSHAKE].remove ( a_Plugin ); - m_Hooks[ E_PLUGIN_LOGIN].remove ( a_Plugin ); - m_Hooks[ E_PLUGIN_PLAYER_SPAWN].remove ( a_Plugin ); - m_Hooks[ E_PLUGIN_PLAYER_JOIN].remove ( a_Plugin ); - m_Hooks[ E_PLUGIN_PLAYER_MOVE].remove ( a_Plugin ); - m_Hooks[ E_PLUGIN_TAKE_DAMAGE].remove ( a_Plugin ); - m_Hooks[ E_PLUGIN_KILLED].remove ( a_Plugin ); - m_Hooks[ E_PLUGIN_CHUNK_GENERATED ].remove ( a_Plugin ); - m_Hooks[ E_PLUGIN_CHUNK_GENERATING ].remove( a_Plugin ); - m_Hooks[ E_PLUGIN_BLOCK_TO_DROPS ].remove ( a_Plugin ); -} - - - - - -void cPluginManager::RemovePlugin( cPlugin* a_Plugin, bool a_bDelete /* = false */ ) -{ - if( a_bDelete ) - { - m_LuaCommandBinder->RemoveBindingsForPlugin( a_Plugin ); - m_Plugins.remove( a_Plugin ); - RemoveHooks( a_Plugin ); - a_Plugin->OnDisable(); - if( a_Plugin->GetLanguage() != cPlugin::E_SQUIRREL ) // Squirrel needs to clean it up himself! - { - delete a_Plugin; - } - } - else - { - for( LuaPluginList::iterator itr = m_LuaPlugins.begin(); itr != m_LuaPlugins.end(); ++itr ) - { - (*itr)->RemovePlugin( a_Plugin ); - } - } -} - - - - - -bool cPluginManager::AddPlugin( cPlugin* a_Plugin ) -{ - a_Plugin->m_bCanBindCommands = true; - if( a_Plugin->Initialize() ) - { - m_Plugins.remove( a_Plugin ); - m_Plugins.push_back( a_Plugin ); - return true; - } - - a_Plugin->m_bCanBindCommands = false; - RemoveHooks( a_Plugin ); // Undo any damage the Initialize() might have done - return false; -} - - - - - -bool cPluginManager::AddPlugin( lua_State* a_LuaState, cPlugin* a_Plugin ) -{ - a_Plugin->SetLanguage( cPlugin::E_LUA ); - cPlugin_Lua* LuaPlugin = GetLuaPlugin( a_LuaState ); - if( LuaPlugin == NULL ) - { - lua_Debug ar; - lua_getstack(a_LuaState, 1, &ar); - lua_getinfo(a_LuaState, "nSl", &ar); - LOGERROR("ERROR: Trying to add an 'old style' plugin from within a 'new style' plugin.\nIn file: %s at line: %i", ar.source, ar.currentline); - } - a_Plugin->m_bCanBindCommands = true; - if( LuaPlugin && a_Plugin->Initialize() ) - { - m_Plugins.remove( a_Plugin ); - m_Plugins.push_back( a_Plugin ); - LuaPlugin->AddPlugin( a_Plugin ); - return true; - } - - a_Plugin->m_bCanBindCommands = false; - return false; -} - - - - - -bool cPluginManager::AddLuaPlugin( cPlugin_Lua* a_Plugin ) -{ - m_LuaPlugins.push_back( a_Plugin ); // It HAS to be in here before calling Initialize, so it can be found by AddPlugin() - if(a_Plugin->Initialize() ) - { - return true; - } - LOG(">>>>>>> Could not initialize a plugin! "); - m_LuaPlugins.remove( a_Plugin ); - return false; -} - - - - - -void cPluginManager::RemoveLuaPlugin( std::string a_FileName ) -{ - for( LuaPluginList::iterator itr = m_LuaPlugins.begin(); itr != m_LuaPlugins.end(); ++itr ) - { - if( (*itr)->GetFileName() == a_FileName ) - { - cPlugin_Lua* Plugin = *itr; - m_LuaPlugins.remove( Plugin ); - delete Plugin; - return; - } - } -} - - - - - -cPlugin_Lua* cPluginManager::GetLuaPlugin( lua_State* a_State ) -{ - for( LuaPluginList::iterator itr = m_LuaPlugins.begin(); itr != m_LuaPlugins.end(); ++itr ) - { - if( (*itr)->GetLuaState() == a_State ) - { - return *itr; - } - } - return NULL; -} - - - - - -void cPluginManager::AddHook( cPlugin* a_Plugin, PluginHook a_Hook ) -{ - if( !a_Plugin ) - { - LOGWARN("Called cPluginManager::AddHook while a_Plugin is NULL"); - return; - } - PluginList & Plugins = m_Hooks[ a_Hook ]; - Plugins.remove( a_Plugin ); - Plugins.push_back( a_Plugin ); -} - - - - - -unsigned int cPluginManager::GetNumPlugins() const -{ - return m_Plugins.size(); -} - - - - - -bool cPluginManager::HasPlugin( cPlugin* a_Plugin ) const -{ - for( PluginList::const_iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); ++itr ) - { - if( *itr == a_Plugin ) - return true; - } - return false; + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPluginManager.h" +#include "cPlugin.h" +#include "cPlugin_Lua.h" +#include "cPlugin_NewLua.h" +#include "cWebAdmin.h" +#include "cItem.h" +#include "cRoot.h" +#include "cLuaCommandBinder.h" +#include "../iniFile/iniFile.h" +#include "tolua++.h" + +#include "SquirrelBindings.h" +#if USE_SQUIRREL + #pragma warning(disable:4100;disable:4127;disable:4510;disable:4610;disable:4244;disable:4512) // Getting A LOT of these warnings from SqPlus + #include + #pragma warning(default:4100;default:4127;default:4510;default:4610;default:4244;default:4512) +#endif + + + + + +cPluginManager* cPluginManager::GetPluginManager() +{ + LOGWARN("WARNING: Using deprecated function cPluginManager::GetPluginManager() use cRoot::Get()->GetPluginManager() instead!"); + return cRoot::Get()->GetPluginManager(); +} + + + + + +cPluginManager::cPluginManager() + : m_LuaCommandBinder( new cLuaCommandBinder() ) + , m_bReloadPlugins(false) +{ +} + + + + + +cPluginManager::~cPluginManager() +{ + UnloadPluginsNow(); + + delete m_LuaCommandBinder; +} + + + + + +void cPluginManager::ReloadPlugins() +{ + m_bReloadPlugins = true; +} + + + + + +void cPluginManager::ReloadPluginsNow() +{ + LOG("Loading plugins"); + m_bReloadPlugins = false; + UnloadPluginsNow(); + + #if USE_SQUIRREL + if( !SquirrelBindings::IsBound ) // Can only do this once apparently, or we're making ambiguous calls in the script + { + SquirrelVM::Init(); + SquirrelBindings::Bind( SquirrelVM::GetVMPtr() ); + } + #endif // USE_SQUIRREL + + cIniFile IniFile("settings.ini"); + if (!IniFile.ReadFile() ) + { + LOGWARNING("cPluginManager: Can't find settings.ini, so can't load any plugins."); + } + + unsigned int KeyNum = IniFile.FindKey("Plugins"); + unsigned int NumPlugins = IniFile.GetNumValues( KeyNum ); + if( NumPlugins > 0 ) + { + for(unsigned int i = 0; i < NumPlugins; i++) + { + AString ValueName = IniFile.GetValueName(KeyNum, i ); + if( ValueName.compare("Plugin") == 0 ) // It's a Lua plugin + { + AString PluginFile = IniFile.GetValue(KeyNum, i ); + if( !PluginFile.empty() ) + { + // allow for comma separated plugin list + // degrades and works fine for the plugin + // per line + AStringVector split = StringSplit( PluginFile, "," ); + for (unsigned int j = 0; j < split.size(); j++) + { + cPlugin_Lua* Plugin = new cPlugin_Lua( (split[j] + AString(".lua") ).c_str() ); + if( !AddLuaPlugin( Plugin ) ) + { + delete Plugin; + } + } + } + } + else if( ValueName.compare("NewPlugin") == 0 ) // New plugin style + { + AString PluginFile = IniFile.GetValue(KeyNum, i ); + if( !PluginFile.empty() ) + { + cPlugin_NewLua* Plugin = new cPlugin_NewLua( PluginFile.c_str() ); + if( !AddPlugin( Plugin ) ) + { + delete Plugin; + } + } + } + + #if USE_SQUIRREL + else if( ValueName.compare("Squirrel") == 0 ) // Squirrel plugin + { + AString PluginFile = IniFile.GetValue(KeyNum, i ); + if( !PluginFile.empty() ) + { + LOGINFO("Loading Squirrel plugin: %s", PluginFile.c_str() ); + try + { + SquirrelObject SquirrelScript = SquirrelVM::CompileScript( (AString("Plugins/") + PluginFile + ".nut").c_str() ); + try + { + SquirrelVM::RunScript( SquirrelScript ); + } + catch (SquirrelError & e) + { + LOGERROR("SquirrelScript error: %s, %s\n", e.desc, "SquirrelVM::RunScript"); + } + } + catch (SquirrelError & e) + { + LOGERROR("SquirrelScript error: %s, %s\n", e.desc, "SquirrelVM::CompileScript"); + } + } + } + #endif // USE_SQUIRREL + + } + } + + if( GetNumPlugins() == 0 ) + { + LOG("No plugins loaded"); + } + else + { + LOG("Loaded %i plugin(s)", GetNumPlugins() ); + } +} + + + + + +void cPluginManager::Tick(float a_Dt) +{ + if( m_bReloadPlugins ) + { + ReloadPluginsNow(); + } + + HookMap::iterator Plugins = m_Hooks.find( E_PLUGIN_TICK ); + if( Plugins != m_Hooks.end() ) + { + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + (*itr)->Tick( a_Dt ); + } + } +} + + + + + +bool cPluginManager::CallHook(PluginHook a_Hook, unsigned int a_NumArgs, ...) +{ + HookMap::iterator Plugins = m_Hooks.find( a_Hook ); + + // Special case for chat hook, since you can also bind commands (bound commands don't use chat hook) + if (a_Hook == HOOK_CHAT) + { + if (a_NumArgs != 2) + { + return false; + } + va_list argptr; + va_start( argptr, a_NumArgs); + const char * Message = va_arg(argptr, const char* ); + cPlayer * Player = va_arg(argptr, cPlayer * ); + va_end (argptr); + + if (m_LuaCommandBinder->HandleCommand( std::string( Message ), Player)) + { + return true; + } + + if (Plugins == m_Hooks.end()) + { + return false; + } + + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnChat(Message, Player)) + { + return true; + } + } + return false; + } + + if (Plugins == m_Hooks.end()) + { + return false; + } + + switch( a_Hook ) + { + case HOOK_COLLECT_ITEM: + { + if( a_NumArgs != 2 ) break; + va_list argptr; + va_start( argptr, a_NumArgs); + cPickup* Pickup = va_arg(argptr, cPickup* ); + cPlayer* Player = va_arg(argptr, cPlayer* ); + va_end (argptr); + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + if( (*itr)->OnCollectItem( Pickup, Player ) ) + return true; + } + break; + } + + case HOOK_BLOCK_DIG: + { + if( a_NumArgs != 2 ) break; + va_list argptr; + va_start( argptr, a_NumArgs); + cPacket_BlockDig* Packet = va_arg(argptr, cPacket_BlockDig* ); + cPlayer* Player = va_arg(argptr, cPlayer* ); + cItem* Item = va_arg( argptr, cItem* ); + va_end (argptr); + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + if( (*itr)->OnBlockDig( Packet, Player, Item ) ) + return true; + } + break; + } + + case HOOK_BLOCK_PLACE: + { + if( a_NumArgs != 2 ) break; + va_list argptr; + va_start( argptr, a_NumArgs); + cPacket_BlockPlace* Packet = va_arg(argptr, cPacket_BlockPlace* ); + cPlayer* Player = va_arg(argptr, cPlayer* ); + va_end (argptr); + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + if( (*itr)->OnBlockPlace( Packet, Player ) ) + return true; + } + break; + } + + case HOOK_DISCONNECT: + { + if( a_NumArgs != 2 ) break; + va_list argptr; + va_start( argptr, a_NumArgs); + const char* Reason = va_arg(argptr, const char* ); + cPlayer* Player = va_arg(argptr, cPlayer* ); + va_end (argptr); + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + if( (*itr)->OnDisconnect( Reason, Player ) ) + return true; + } + break; + } + + case HOOK_LOGIN: + { + if( a_NumArgs != 1 ) break; + va_list argptr; + va_start( argptr, a_NumArgs); + cPacket_Login* Packet = va_arg(argptr, cPacket_Login* ); + va_end (argptr); + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + if( (*itr)->OnLogin( Packet ) ) + return true; + } + break; + } + + case HOOK_PLAYER_JOIN: + { + if( a_NumArgs != 1 ) break; + va_list argptr; + va_start( argptr, a_NumArgs); + cPlayer* Player = va_arg(argptr, cPlayer* ); + va_end (argptr); + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + if( (*itr)->OnPlayerJoin( Player ) ) + return true; + } + break; + } + + case HOOK_PLAYER_MOVE: + { + if( a_NumArgs != 1 ) break; + va_list argptr; + va_start( argptr, a_NumArgs); + cPlayer* Player = va_arg(argptr, cPlayer* ); + va_end (argptr); + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + (*itr)->OnPlayerMove( Player ); + } + break; + } + + case HOOK_TAKE_DAMAGE: + { + if( a_NumArgs != 2 ) break; + va_list argptr; + va_start( argptr, a_NumArgs); + cPawn* Pawn = va_arg(argptr, cPawn* ); + TakeDamageInfo* TDI = va_arg(argptr, TakeDamageInfo* ); + va_end (argptr); + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + (*itr)->OnTakeDamage( Pawn, TDI ); + } + break; + } + + case HOOK_KILLED: + { + if( a_NumArgs != 2 ) break; + va_list argptr; + va_start( argptr, a_NumArgs); + cPawn* Killed = va_arg(argptr, cPawn* ); + cEntity* Killer = va_arg(argptr, cEntity* ); + va_end (argptr); + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + if( (*itr)->OnKilled( Killed, Killer ) ) + return true; + } + break; + } + + case HOOK_CHUNK_GENERATED: + { + if (a_NumArgs != 3) + { + break; + } + va_list argptr; + va_start( argptr, a_NumArgs); + cWorld * World = va_arg(argptr, cWorld *); + int ChunkX = va_arg(argptr, int); + int ChunkZ = va_arg(argptr, int); + va_end (argptr); + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + (*itr)->OnChunkGenerated(World, ChunkX, ChunkZ); + } + break; + } + + case HOOK_CHUNK_GENERATING: + { + if (a_NumArgs != 3) + { + break; + } + va_list argptr; + va_start( argptr, a_NumArgs); + int ChunkX = va_arg(argptr, int); + int ChunkZ = va_arg(argptr, int); + cLuaChunk * LuaChunk = va_arg(argptr, cLuaChunk *); + va_end (argptr); + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnChunkGenerating(ChunkX, ChunkZ, LuaChunk)) + { + return true; + } + } + break; + } + + default: + { + LOGWARNING("cPluginManager: Calling Unknown hook: %i", a_Hook ); + ASSERT(!"Calling an unknown hook"); + break; + } + } // switch (a_Hook) + return false; +} + + + + + +bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_PRE_CRAFTING); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnPreCrafting(a_Player, a_Grid, a_Recipe)) + { + return true; + } + } + return false; +} + + + + + +bool cPluginManager::CallHookCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_CRAFTING_NO_RECIPE); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnCraftingNoRecipe(a_Player, a_Grid, a_Recipe)) + { + return true; + } + } + return false; +} + + + + + +bool cPluginManager::CallHookPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_POST_CRAFTING); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnPostCrafting(a_Player, a_Grid, a_Recipe)) + { + return true; + } + } + return false; +} + + + + + +bool cPluginManager::CallHookBlockToPickup( + BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, + const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups +) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_POST_CRAFTING); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnBlockToPickup(a_BlockType, a_BlockMeta, a_Player, a_EquippedItem, a_Pickups)) + { + return true; + } + } + return false; +} + + + + + +cPlugin* cPluginManager::GetPlugin( const char* a_Plugin ) const +{ + for( PluginList::const_iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); ++itr ) + { + if (strcmp((*itr)->GetName(), a_Plugin) == 0 ) + { + return *itr; + } + } + return 0; +} + + + + + +const cPluginManager::PluginList & cPluginManager::GetAllPlugins() const +{ + return m_Plugins; +} + + + + + +void cPluginManager::UnloadPluginsNow() +{ + m_Hooks.clear(); + + while( m_LuaPlugins.size() > 0 ) + { + cPlugin_Lua* LuaPlugin = *m_LuaPlugins.begin(); + if( LuaPlugin ) + { + cWebAdmin* WebAdmin = cRoot::Get()->GetWebAdmin(); + if( WebAdmin ) WebAdmin->RemovePlugin( LuaPlugin->GetLuaState() ); + delete LuaPlugin; + } + m_LuaPlugins.remove( LuaPlugin ); + } + + while( m_Plugins.size() > 0 ) + { + RemovePlugin( *m_Plugins.begin(), true ); + } + + //SquirrelVM::Shutdown(); // This breaks shit +} + + + + + +void cPluginManager::RemoveHooks( cPlugin* a_Plugin ) +{ + m_Hooks[ E_PLUGIN_TICK].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_CHAT].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_COLLECT_ITEM].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_BLOCK_DIG].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_BLOCK_PLACE].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_DISCONNECT].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_HANDSHAKE].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_LOGIN].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_PLAYER_SPAWN].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_PLAYER_JOIN].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_PLAYER_MOVE].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_TAKE_DAMAGE].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_KILLED].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_CHUNK_GENERATED ].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_CHUNK_GENERATING ].remove( a_Plugin ); + m_Hooks[ E_PLUGIN_BLOCK_TO_DROPS ].remove ( a_Plugin ); +} + + + + + +void cPluginManager::RemovePlugin( cPlugin* a_Plugin, bool a_bDelete /* = false */ ) +{ + if( a_bDelete ) + { + m_LuaCommandBinder->RemoveBindingsForPlugin( a_Plugin ); + m_Plugins.remove( a_Plugin ); + RemoveHooks( a_Plugin ); + a_Plugin->OnDisable(); + if( a_Plugin->GetLanguage() != cPlugin::E_SQUIRREL ) // Squirrel needs to clean it up himself! + { + delete a_Plugin; + } + } + else + { + for( LuaPluginList::iterator itr = m_LuaPlugins.begin(); itr != m_LuaPlugins.end(); ++itr ) + { + (*itr)->RemovePlugin( a_Plugin ); + } + } +} + + + + + +bool cPluginManager::AddPlugin( cPlugin* a_Plugin ) +{ + a_Plugin->m_bCanBindCommands = true; + if( a_Plugin->Initialize() ) + { + m_Plugins.remove( a_Plugin ); + m_Plugins.push_back( a_Plugin ); + return true; + } + + a_Plugin->m_bCanBindCommands = false; + RemoveHooks( a_Plugin ); // Undo any damage the Initialize() might have done + return false; +} + + + + + +bool cPluginManager::AddPlugin( lua_State* a_LuaState, cPlugin* a_Plugin ) +{ + a_Plugin->SetLanguage( cPlugin::E_LUA ); + cPlugin_Lua* LuaPlugin = GetLuaPlugin( a_LuaState ); + if( LuaPlugin == NULL ) + { + lua_Debug ar; + lua_getstack(a_LuaState, 1, &ar); + lua_getinfo(a_LuaState, "nSl", &ar); + LOGERROR("ERROR: Trying to add an 'old style' plugin from within a 'new style' plugin.\nIn file: %s at line: %i", ar.source, ar.currentline); + } + a_Plugin->m_bCanBindCommands = true; + if( LuaPlugin && a_Plugin->Initialize() ) + { + m_Plugins.remove( a_Plugin ); + m_Plugins.push_back( a_Plugin ); + LuaPlugin->AddPlugin( a_Plugin ); + return true; + } + + a_Plugin->m_bCanBindCommands = false; + return false; +} + + + + + +bool cPluginManager::AddLuaPlugin( cPlugin_Lua* a_Plugin ) +{ + m_LuaPlugins.push_back( a_Plugin ); // It HAS to be in here before calling Initialize, so it can be found by AddPlugin() + if(a_Plugin->Initialize() ) + { + return true; + } + LOG(">>>>>>> Could not initialize a plugin! "); + m_LuaPlugins.remove( a_Plugin ); + return false; +} + + + + + +void cPluginManager::RemoveLuaPlugin( std::string a_FileName ) +{ + for( LuaPluginList::iterator itr = m_LuaPlugins.begin(); itr != m_LuaPlugins.end(); ++itr ) + { + if( (*itr)->GetFileName() == a_FileName ) + { + cPlugin_Lua* Plugin = *itr; + m_LuaPlugins.remove( Plugin ); + delete Plugin; + return; + } + } +} + + + + + +cPlugin_Lua* cPluginManager::GetLuaPlugin( lua_State* a_State ) +{ + for( LuaPluginList::iterator itr = m_LuaPlugins.begin(); itr != m_LuaPlugins.end(); ++itr ) + { + if( (*itr)->GetLuaState() == a_State ) + { + return *itr; + } + } + return NULL; +} + + + + + +void cPluginManager::AddHook( cPlugin* a_Plugin, PluginHook a_Hook ) +{ + if( !a_Plugin ) + { + LOGWARN("Called cPluginManager::AddHook while a_Plugin is NULL"); + return; + } + PluginList & Plugins = m_Hooks[ a_Hook ]; + Plugins.remove( a_Plugin ); + Plugins.push_back( a_Plugin ); +} + + + + + +unsigned int cPluginManager::GetNumPlugins() const +{ + return m_Plugins.size(); +} + + + + + +bool cPluginManager::HasPlugin( cPlugin* a_Plugin ) const +{ + for( PluginList::const_iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); ++itr ) + { + if( *itr == a_Plugin ) + return true; + } + return false; } \ No newline at end of file diff --git a/source/cPluginManager.h b/source/cPluginManager.h index 59191ecc3..e9010ebd9 100644 --- a/source/cPluginManager.h +++ b/source/cPluginManager.h @@ -1,121 +1,121 @@ - -#pragma once - -#include "cItem.h" - -struct lua_State; -class cLuaCommandBinder; -class cPlugin; -class cPlugin_Lua; - -// fwd: cPlayer.h -class cPlayer; - -// fwd: CraftingRecipes.h -class cCraftingGrid; -class cCraftingRecipe; - - - - - -class cPluginManager //tolua_export -{ //tolua_export -public: //tolua_export - - // Called each tick - virtual void Tick(float a_Dt); - - // tolua_begin - enum PluginHook - { - HOOK_TICK, - HOOK_CHAT, - HOOK_COLLECT_ITEM, - HOOK_BLOCK_DIG, - HOOK_BLOCK_PLACE, - HOOK_DISCONNECT, - HOOK_HANDSHAKE, - HOOK_LOGIN, - HOOK_PLAYER_SPAWN, - HOOK_PLAYER_JOIN, - HOOK_PLAYER_MOVE, - HOOK_TAKE_DAMAGE, - HOOK_KILLED, - HOOK_CHUNK_GENERATED, - HOOK_CHUNK_GENERATING, - HOOK_BLOCK_TO_DROPS, - HOOK_PRE_CRAFTING, /// cPlayer, cCraftingGrid, cCraftingRecipe - HOOK_CRAFTING_NO_RECIPE, /// cPlayer, cCraftingGrid, cCraftingRecipe - HOOK_POST_CRAFTING, /// cPlayer, cCraftingGrid, cCraftingRecipe - HOOK_BLOCK_TO_PICKUP, /// BlockType, BlockMeta, cPlayer, cItem, cItems - HOOK_WEATHER_CHANGE, - - // E_PLUGIN_ names are obsolete, but are kept for compatibility reasons - E_PLUGIN_TICK = HOOK_TICK, - E_PLUGIN_CHAT = HOOK_CHAT, - E_PLUGIN_COLLECT_ITEM = HOOK_COLLECT_ITEM, - E_PLUGIN_BLOCK_DIG = HOOK_BLOCK_DIG, - E_PLUGIN_BLOCK_PLACE = HOOK_BLOCK_PLACE, - E_PLUGIN_DISCONNECT = HOOK_DISCONNECT, - E_PLUGIN_HANDSHAKE = HOOK_HANDSHAKE, - E_PLUGIN_LOGIN = HOOK_LOGIN, - E_PLUGIN_PLAYER_SPAWN = HOOK_PLAYER_SPAWN, - E_PLUGIN_PLAYER_JOIN = HOOK_PLAYER_JOIN, - E_PLUGIN_PLAYER_MOVE = HOOK_PLAYER_MOVE, - E_PLUGIN_TAKE_DAMAGE = HOOK_TAKE_DAMAGE, - E_PLUGIN_KILLED = HOOK_KILLED, - E_PLUGIN_CHUNK_GENERATED = HOOK_CHUNK_GENERATED, - E_PLUGIN_CHUNK_GENERATING = HOOK_CHUNK_GENERATING, - E_PLUGIN_BLOCK_TO_DROPS = HOOK_BLOCK_TO_DROPS, - }; - // tolua_end - - static cPluginManager * GetPluginManager(); //tolua_export - - typedef std::list< cPlugin * > PluginList; - cPlugin* GetPlugin( const char* a_Plugin ) const; //tolua_export - const PluginList & GetAllPlugins() const; // >> EXPORTED IN MANUALBINDINGS << - - void ReloadPlugins(); //tolua_export - bool AddPlugin( cPlugin* a_Plugin ); - bool AddPlugin( lua_State* a_LuaState, cPlugin* a_Plugin ); //tolua_export - bool AddLuaPlugin( cPlugin_Lua* a_Plugin ); - void AddHook( cPlugin* a_Plugin, PluginHook a_Hook ); //tolua_export - - unsigned int GetNumPlugins() const; //tolua_export - - bool CallHook( PluginHook a_Hook, unsigned int a_NumArgs, ... ); - - bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); - bool CallHookCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); - bool CallHookPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); - bool CallHookBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups); - - void RemoveHooks( cPlugin* a_Plugin ); - void RemovePlugin( cPlugin* a_Plugin, bool a_bDelete = false ); //tolua_export - void RemoveLuaPlugin( std::string a_FileName ); //tolua_export - cPlugin_Lua* GetLuaPlugin( lua_State* a_State ); //tolua_export - - cLuaCommandBinder* GetLuaCommandBinder() const { return m_LuaCommandBinder; } - - bool HasPlugin( cPlugin* a_Plugin ) const; -private: - friend class cRoot; - cPluginManager(); - ~cPluginManager(); - - typedef std::list< cPlugin_Lua* > LuaPluginList; - typedef std::map< cPluginManager::PluginHook, cPluginManager::PluginList > HookMap; - - LuaPluginList m_LuaPlugins; - PluginList m_Plugins; - HookMap m_Hooks; - - void ReloadPluginsNow(); - void UnloadPluginsNow(); - - cLuaCommandBinder* m_LuaCommandBinder; - - bool m_bReloadPlugins; -}; //tolua_export + +#pragma once + +#include "cItem.h" + +struct lua_State; +class cLuaCommandBinder; +class cPlugin; +class cPlugin_Lua; + +// fwd: cPlayer.h +class cPlayer; + +// fwd: CraftingRecipes.h +class cCraftingGrid; +class cCraftingRecipe; + + + + + +class cPluginManager //tolua_export +{ //tolua_export +public: //tolua_export + + // Called each tick + virtual void Tick(float a_Dt); + + // tolua_begin + enum PluginHook + { + HOOK_TICK, + HOOK_CHAT, + HOOK_COLLECT_ITEM, + HOOK_BLOCK_DIG, + HOOK_BLOCK_PLACE, + HOOK_DISCONNECT, + HOOK_HANDSHAKE, + HOOK_LOGIN, + HOOK_PLAYER_SPAWN, + HOOK_PLAYER_JOIN, + HOOK_PLAYER_MOVE, + HOOK_TAKE_DAMAGE, + HOOK_KILLED, + HOOK_CHUNK_GENERATED, + HOOK_CHUNK_GENERATING, + HOOK_BLOCK_TO_DROPS, + HOOK_PRE_CRAFTING, /// cPlayer, cCraftingGrid, cCraftingRecipe + HOOK_CRAFTING_NO_RECIPE, /// cPlayer, cCraftingGrid, cCraftingRecipe + HOOK_POST_CRAFTING, /// cPlayer, cCraftingGrid, cCraftingRecipe + HOOK_BLOCK_TO_PICKUP, /// BlockType, BlockMeta, cPlayer, cItem, cItems + HOOK_WEATHER_CHANGE, + + // E_PLUGIN_ names are obsolete, but are kept for compatibility reasons + E_PLUGIN_TICK = HOOK_TICK, + E_PLUGIN_CHAT = HOOK_CHAT, + E_PLUGIN_COLLECT_ITEM = HOOK_COLLECT_ITEM, + E_PLUGIN_BLOCK_DIG = HOOK_BLOCK_DIG, + E_PLUGIN_BLOCK_PLACE = HOOK_BLOCK_PLACE, + E_PLUGIN_DISCONNECT = HOOK_DISCONNECT, + E_PLUGIN_HANDSHAKE = HOOK_HANDSHAKE, + E_PLUGIN_LOGIN = HOOK_LOGIN, + E_PLUGIN_PLAYER_SPAWN = HOOK_PLAYER_SPAWN, + E_PLUGIN_PLAYER_JOIN = HOOK_PLAYER_JOIN, + E_PLUGIN_PLAYER_MOVE = HOOK_PLAYER_MOVE, + E_PLUGIN_TAKE_DAMAGE = HOOK_TAKE_DAMAGE, + E_PLUGIN_KILLED = HOOK_KILLED, + E_PLUGIN_CHUNK_GENERATED = HOOK_CHUNK_GENERATED, + E_PLUGIN_CHUNK_GENERATING = HOOK_CHUNK_GENERATING, + E_PLUGIN_BLOCK_TO_DROPS = HOOK_BLOCK_TO_DROPS, + }; + // tolua_end + + static cPluginManager * GetPluginManager(); //tolua_export + + typedef std::list< cPlugin * > PluginList; + cPlugin* GetPlugin( const char* a_Plugin ) const; //tolua_export + const PluginList & GetAllPlugins() const; // >> EXPORTED IN MANUALBINDINGS << + + void ReloadPlugins(); //tolua_export + bool AddPlugin( cPlugin* a_Plugin ); + bool AddPlugin( lua_State* a_LuaState, cPlugin* a_Plugin ); //tolua_export + bool AddLuaPlugin( cPlugin_Lua* a_Plugin ); + void AddHook( cPlugin* a_Plugin, PluginHook a_Hook ); //tolua_export + + unsigned int GetNumPlugins() const; //tolua_export + + bool CallHook( PluginHook a_Hook, unsigned int a_NumArgs, ... ); + + bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); + bool CallHookCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); + bool CallHookPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); + bool CallHookBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups); + + void RemoveHooks( cPlugin* a_Plugin ); + void RemovePlugin( cPlugin* a_Plugin, bool a_bDelete = false ); //tolua_export + void RemoveLuaPlugin( std::string a_FileName ); //tolua_export + cPlugin_Lua* GetLuaPlugin( lua_State* a_State ); //tolua_export + + cLuaCommandBinder* GetLuaCommandBinder() const { return m_LuaCommandBinder; } + + bool HasPlugin( cPlugin* a_Plugin ) const; +private: + friend class cRoot; + cPluginManager(); + ~cPluginManager(); + + typedef std::list< cPlugin_Lua* > LuaPluginList; + typedef std::map< cPluginManager::PluginHook, cPluginManager::PluginList > HookMap; + + LuaPluginList m_LuaPlugins; + PluginList m_Plugins; + HookMap m_Hooks; + + void ReloadPluginsNow(); + void UnloadPluginsNow(); + + cLuaCommandBinder* m_LuaCommandBinder; + + bool m_bReloadPlugins; +}; //tolua_export diff --git a/source/cPlugin_Lua.cpp b/source/cPlugin_Lua.cpp index d25df0242..a4cf972f4 100644 --- a/source/cPlugin_Lua.cpp +++ b/source/cPlugin_Lua.cpp @@ -1,98 +1,98 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#define LUA_USE_POSIX -#include "cPlugin_Lua.h" -#include "cPluginManager.h" -#include "cRoot.h" - -extern "C" -{ - #include "lualib.h" -} - -#include "tolua++.h" -#include "Bindings.h" -#include "ManualBindings.h" - -bool report_errors(lua_State* lua, int status) -{ - if ( status!=0 ) - { - std::string s = lua_tostring(lua, -1); - LOGERROR("-- %s", s.c_str() ); - lua_pop(lua, 1); - return true; - } - return false; -} - -cPlugin_Lua::~cPlugin_Lua() -{ - UnloadPlugins(); - if( m_LuaState ) - { - lua_close( m_LuaState ); - m_LuaState = 0; - } -} - -cPlugin_Lua::cPlugin_Lua(const char* a_Plugin) -: m_LuaState( 0 ) -{ - m_FileName.assign( a_Plugin ); -} - -bool cPlugin_Lua::Initialize() -{ - if( !m_LuaState ) - { - m_LuaState = lua_open(); - luaL_openlibs( m_LuaState ); - tolua_AllToLua_open(m_LuaState); - ManualBindings::Bind( m_LuaState ); - } - - int s = luaL_loadfile(m_LuaState, (std::string("Plugins/") + m_FileName ).c_str() ); - if( report_errors( m_LuaState, s ) ) - { - LOGERROR("Can't load plugin %s", m_FileName.c_str() ); - lua_close( m_LuaState ); - m_LuaState = 0; - return false; - } - - s = lua_pcall(m_LuaState, 0, LUA_MULTRET, 0); - if( report_errors( m_LuaState, s ) ) - { - LOGERROR("Error in plugin %s", m_FileName.c_str() ); - lua_close( m_LuaState ); - m_LuaState = 0; - return false; - } - return true; -} - -void cPlugin_Lua::AddPlugin( cPlugin* a_Plugin ) -{ - m_Plugins.push_back( a_Plugin ); -} - -void cPlugin_Lua::RemovePlugin( cPlugin* a_Plugin ) -{ - m_Plugins.remove( a_Plugin ); - cRoot::Get()->GetPluginManager()->RemovePlugin( a_Plugin, true ); -} - -void cPlugin_Lua::UnloadPlugins() -{ - while( m_Plugins.begin() != m_Plugins.end() ) - { - RemovePlugin( *m_Plugins.begin() ); - } -} - -lua_State* cPlugin_Lua::GetLuaState() -{ - return m_LuaState; + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#define LUA_USE_POSIX +#include "cPlugin_Lua.h" +#include "cPluginManager.h" +#include "cRoot.h" + +extern "C" +{ + #include "lualib.h" +} + +#include "tolua++.h" +#include "Bindings.h" +#include "ManualBindings.h" + +bool report_errors(lua_State* lua, int status) +{ + if ( status!=0 ) + { + std::string s = lua_tostring(lua, -1); + LOGERROR("-- %s", s.c_str() ); + lua_pop(lua, 1); + return true; + } + return false; +} + +cPlugin_Lua::~cPlugin_Lua() +{ + UnloadPlugins(); + if( m_LuaState ) + { + lua_close( m_LuaState ); + m_LuaState = 0; + } +} + +cPlugin_Lua::cPlugin_Lua(const char* a_Plugin) +: m_LuaState( 0 ) +{ + m_FileName.assign( a_Plugin ); +} + +bool cPlugin_Lua::Initialize() +{ + if( !m_LuaState ) + { + m_LuaState = lua_open(); + luaL_openlibs( m_LuaState ); + tolua_AllToLua_open(m_LuaState); + ManualBindings::Bind( m_LuaState ); + } + + int s = luaL_loadfile(m_LuaState, (std::string("Plugins/") + m_FileName ).c_str() ); + if( report_errors( m_LuaState, s ) ) + { + LOGERROR("Can't load plugin %s", m_FileName.c_str() ); + lua_close( m_LuaState ); + m_LuaState = 0; + return false; + } + + s = lua_pcall(m_LuaState, 0, LUA_MULTRET, 0); + if( report_errors( m_LuaState, s ) ) + { + LOGERROR("Error in plugin %s", m_FileName.c_str() ); + lua_close( m_LuaState ); + m_LuaState = 0; + return false; + } + return true; +} + +void cPlugin_Lua::AddPlugin( cPlugin* a_Plugin ) +{ + m_Plugins.push_back( a_Plugin ); +} + +void cPlugin_Lua::RemovePlugin( cPlugin* a_Plugin ) +{ + m_Plugins.remove( a_Plugin ); + cRoot::Get()->GetPluginManager()->RemovePlugin( a_Plugin, true ); +} + +void cPlugin_Lua::UnloadPlugins() +{ + while( m_Plugins.begin() != m_Plugins.end() ) + { + RemovePlugin( *m_Plugins.begin() ); + } +} + +lua_State* cPlugin_Lua::GetLuaState() +{ + return m_LuaState; } \ No newline at end of file diff --git a/source/cPlugin_Lua.h b/source/cPlugin_Lua.h index 1ce582a29..6e5d027d4 100644 --- a/source/cPlugin_Lua.h +++ b/source/cPlugin_Lua.h @@ -1,32 +1,32 @@ - -#pragma once - -class cPickup; -class cPlayer; -class cPacket_BlockPlace; -class cPacket_BlockDig; -class cPacket_Login; -class cPlugin; -class cPlugin_Lua //tolua_export -{ //tolua_export -public: - cPlugin_Lua(const char* a_Plugin); - ~cPlugin_Lua(); - - virtual bool Initialize(); - - std::string GetFileName() { return m_FileName; } //tolua_export - typedef struct lua_State lua_State; - lua_State* GetLuaState(); - - void AddPlugin( cPlugin* a_Plugin ); - void RemovePlugin( cPlugin* a_Plugin ); -private: - void UnloadPlugins(); - - std::string m_FileName; - lua_State* m_LuaState; - - typedef std::list< cPlugin* > PluginList; - PluginList m_Plugins; + +#pragma once + +class cPickup; +class cPlayer; +class cPacket_BlockPlace; +class cPacket_BlockDig; +class cPacket_Login; +class cPlugin; +class cPlugin_Lua //tolua_export +{ //tolua_export +public: + cPlugin_Lua(const char* a_Plugin); + ~cPlugin_Lua(); + + virtual bool Initialize(); + + std::string GetFileName() { return m_FileName; } //tolua_export + typedef struct lua_State lua_State; + lua_State* GetLuaState(); + + void AddPlugin( cPlugin* a_Plugin ); + void RemovePlugin( cPlugin* a_Plugin ); +private: + void UnloadPlugins(); + + std::string m_FileName; + lua_State* m_LuaState; + + typedef std::list< cPlugin* > PluginList; + PluginList m_Plugins; }; //tolua_export \ No newline at end of file diff --git a/source/cPlugin_NewLua.cpp b/source/cPlugin_NewLua.cpp index ae79ebd3c..92764a368 100644 --- a/source/cPlugin_NewLua.cpp +++ b/source/cPlugin_NewLua.cpp @@ -1,551 +1,551 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#define LUA_USE_POSIX -#include "cPlugin_NewLua.h" -#include "cMCLogger.h" -#include "cWebPlugin_Lua.h" -#include "LuaItems.h" - -extern "C" -{ -#include "lualib.h" -} - -#include "tolua++.h" -#include "Bindings.h" -#include "ManualBindings.h" - -#ifdef _WIN32 -// #include "wdirent.h" -#else -#include -#endif - - - - - -extern bool report_errors(lua_State* lua, int status); - - - - - -cPlugin_NewLua::cPlugin_NewLua( const char* a_PluginName ) - : m_LuaState( 0 ) -{ - m_Directory = a_PluginName; -} - - - - - -cPlugin_NewLua::~cPlugin_NewLua() -{ - cCSLock Lock( m_CriticalSection ); - for( WebPluginList::iterator itr = m_WebPlugins.begin(); itr != m_WebPlugins.end(); ++itr ) - { - delete *itr; - } - m_WebPlugins.clear(); - - if( m_LuaState ) - { - lua_close( m_LuaState ); - m_LuaState = 0; - } -} - - - - - -bool cPlugin_NewLua::Initialize() -{ - cCSLock Lock( m_CriticalSection ); - if( !m_LuaState ) - { - m_LuaState = lua_open(); - luaL_openlibs( m_LuaState ); - tolua_AllToLua_open(m_LuaState); - ManualBindings::Bind( m_LuaState ); - } - - std::string PluginPath = std::string("Plugins/") + m_Directory + "/"; - - // Load all files for this plugin, and execute them - AStringList Files = GetDirectoryContents(PluginPath.c_str()); - for (AStringList::const_iterator itr = Files.begin(); itr != Files.end(); ++itr) - { - if (itr->rfind(".lua") == AString::npos) - { - continue; - } - AString Path = PluginPath + *itr; - int s = luaL_loadfile(m_LuaState, Path.c_str() ); - if( report_errors( m_LuaState, s ) ) - { - LOGERROR("Can't load plugin %s because of an error in file %s", m_Directory.c_str(), Path.c_str() ); - lua_close( m_LuaState ); - m_LuaState = 0; - return false; - } - - s = lua_pcall(m_LuaState, 0, LUA_MULTRET, 0); - if( report_errors( m_LuaState, s ) ) - { - LOGERROR("Error in plugin %s in file %s", m_Directory.c_str(), Path.c_str() ); - lua_close( m_LuaState ); - m_LuaState = 0; - return false; - } - } // for itr - Files[] - - // Call intialize function - if( !PushFunction("Initialize") ) - { - lua_close( m_LuaState ); - m_LuaState = 0; - return false; - } - - tolua_pushusertype(m_LuaState, this, "cPlugin_NewLua"); - - if( !CallFunction(1, 1, "Initialize") ) - { - lua_close( m_LuaState ); - m_LuaState = 0; - return false; - } - - if( !lua_isboolean( m_LuaState, -1 ) ) - { - LOGWARN("Error in plugin %s Initialize() must return a boolean value!", m_Directory.c_str() ); - lua_close( m_LuaState ); - m_LuaState = 0; - return false; - } - - bool bSuccess = (tolua_toboolean( m_LuaState, -1, 0) > 0); - return bSuccess; -} - - - - - -void cPlugin_NewLua::OnDisable() -{ - cCSLock Lock( m_CriticalSection ); - if( !PushFunction("OnDisable", false) ) // false = don't log error if not found - return; - - CallFunction(0, 0, "OnDisable"); -} - - - - - -void cPlugin_NewLua::Tick(float a_Dt) -{ - cCSLock Lock( m_CriticalSection ); - if( !PushFunction("Tick") ) - return; - - tolua_pushnumber( m_LuaState, a_Dt ); - - CallFunction(1, 0, "Tick"); -} - - - - - -bool cPlugin_NewLua::OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player ) -{ - cCSLock Lock( m_CriticalSection ); - if( !PushFunction("OnCollectItem") ) - return false; - - tolua_pushusertype(m_LuaState, a_Pickup, "cPickup"); - tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); - - if( !CallFunction(2, 1, "OnCollectItem") ) - return false; - - bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); - return bRetVal; -} - - - - - -bool cPlugin_NewLua::OnDisconnect(const AString & a_Reason, cPlayer* a_Player ) -{ - cCSLock Lock( m_CriticalSection ); - if( !PushFunction("OnDisconnect") ) - return false; - - tolua_pushstring( m_LuaState, a_Reason.c_str() ); - tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); - - if( !CallFunction(2, 1, "OnDisconnect") ) - return false; - - bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); - return bRetVal; -} - - - - - -bool cPlugin_NewLua::OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player ) -{ - cCSLock Lock( m_CriticalSection ); - if( !PushFunction("OnBlockPlace") ) - return false; - - tolua_pushusertype(m_LuaState, a_PacketData, "cPacket_BlockPlace"); - tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); - - if( !CallFunction(2, 1, "OnBlockPlace") ) - return false; - - bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); - return bRetVal; -} - - - - - -bool cPlugin_NewLua::OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem ) -{ - cCSLock Lock( m_CriticalSection ); - if( !PushFunction("OnBlockDig") ) - return false; - - tolua_pushusertype(m_LuaState, a_PacketData, "cPacket_BlockDig"); - tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); - tolua_pushusertype(m_LuaState, a_PickupItem, "cItem"); - - if( !CallFunction(3, 1, "OnBlockDig") ) - return false; - - bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); - return bRetVal; -} - - - - - -bool cPlugin_NewLua::OnChat( const char* a_Chat, cPlayer* a_Player ) -{ - cCSLock Lock( m_CriticalSection ); - if( !PushFunction("OnChat") ) - return false; - - tolua_pushstring( m_LuaState, a_Chat ); - tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); - - if( !CallFunction(2, 1, "OnChat") ) - return false; - - bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); - return bRetVal; -} - - - - - -bool cPlugin_NewLua::OnLogin( cPacket_Login* a_PacketData ) -{ - cCSLock Lock( m_CriticalSection ); - if( !PushFunction("OnLogin") ) - return false; - - tolua_pushusertype(m_LuaState, a_PacketData, "cPacket_Login"); - - if( !CallFunction(1, 1, "OnLogin") ) - return false; - - bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); - return bRetVal; -} - - - - - -void cPlugin_NewLua::OnPlayerSpawn( cPlayer* a_Player ) -{ - cCSLock Lock( m_CriticalSection ); - if( !PushFunction("OnPlayerSpawn") ) - return; - - tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); - - CallFunction(1, 0, "OnPlayerSpawn"); -} - - - - - -bool cPlugin_NewLua::OnPlayerJoin( cPlayer* a_Player ) -{ - cCSLock Lock( m_CriticalSection ); - if( !PushFunction("OnPlayerJoin") ) - return false; - - tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); - - if( !CallFunction(1, 1, "OnPlayerJoin") ) - return false; - - bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); - return bRetVal; -} - - - - - -void cPlugin_NewLua::OnPlayerMove( cPlayer* a_Player ) -{ - cCSLock Lock( m_CriticalSection ); - if( !PushFunction("OnPlayerMove") ) - return; - - tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); - - CallFunction(1, 0, "OnPlayerMove"); -} - - - - - -void cPlugin_NewLua::OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo ) -{ - cCSLock Lock( m_CriticalSection ); - if( !PushFunction("OnTakeDamage") ) - return; - - tolua_pushusertype(m_LuaState, a_Pawn, "cPawn"); - tolua_pushusertype(m_LuaState, a_TakeDamageInfo, "TakeDamageInfo"); - - CallFunction(2, 0, "OnTakeDamage"); -} - - - - - -bool cPlugin_NewLua::OnKilled( cPawn* a_Killed, cEntity* a_Killer ) -{ - cCSLock Lock( m_CriticalSection ); - if( !PushFunction("OnKilled") ) - return false; - - tolua_pushusertype(m_LuaState, a_Killed, "cPawn"); - tolua_pushusertype(m_LuaState, a_Killer, "cEntity"); - - if( !CallFunction(2, 1, "OnKilled") ) - return false; - - bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); - return bRetVal; -} - - - - - -void cPlugin_NewLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ) -{ - cCSLock Lock(m_CriticalSection); - if (!PushFunction("OnChunkGenerated")) - { - return; - } - - tolua_pushusertype(m_LuaState, a_World, "cWorld"); - tolua_pushnumber (m_LuaState, a_ChunkX); - tolua_pushnumber (m_LuaState, a_ChunkZ); - - CallFunction(3, 0, "OnChunkGenerated"); -} - - - - - -bool cPlugin_NewLua::OnChunkGenerating( int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) -{ - cCSLock Lock(m_CriticalSection); - if (!PushFunction("OnChunkGenerating")) - return false; - - tolua_pushnumber (m_LuaState, a_ChunkX); - tolua_pushnumber (m_LuaState, a_ChunkZ); - tolua_pushusertype(m_LuaState, a_pLuaChunk, "cLuaChunk"); - - if( !CallFunction(3, 1, "OnChunkGenerating") ) - return false; - - bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); - return bRetVal; -} - - - - - -bool cPlugin_NewLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) -{ - cCSLock Lock(m_CriticalSection); - if (!PushFunction("OnPreCrafting")) - return false; - - tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); - tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); - tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); - - if (!CallFunction(3, 1, "OnPreCrafting")) - { - return false; - } - - bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); - return bRetVal; -} - - - - - -bool cPlugin_NewLua::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) -{ - cCSLock Lock(m_CriticalSection); - if (!PushFunction("OnCraftingNoRecipe")) - return false; - - tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); - tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); - tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); - - if (!CallFunction(3, 1, "OnCraftingNoRecipe")) - { - return false; - } - - bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); - return bRetVal; -} - - - - - -bool cPlugin_NewLua::OnPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) -{ - cCSLock Lock(m_CriticalSection); - if (!PushFunction("OnPostCrafting")) - return false; - - tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); - tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); - tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); - - if (!CallFunction(3, 1, "OnPostCrafting")) - { - return false; - } - - bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); - return bRetVal; -} - - - - - -bool cPlugin_NewLua::OnBlockToPickup( - BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, - const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups -) -{ - cLuaItems Pickups(a_Pickups); - cCSLock Lock(m_CriticalSection); - if (!PushFunction("OnBlockToPickup")) - return false; - - tolua_pushnumber (m_LuaState, a_BlockType); - tolua_pushnumber (m_LuaState, a_BlockMeta); - tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); - tolua_pushusertype(m_LuaState, (void *)&a_EquippedItem, "cItem"); - tolua_pushusertype(m_LuaState, (void *)&Pickups, "cLuaItems"); - - if (!CallFunction(5, 1, "OnBlockToPickup")) - { - return false; - } - - bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); - return bRetVal; -} - - - - - -cWebPlugin_Lua* cPlugin_NewLua::CreateWebPlugin(lua_State* a_LuaState) -{ - cCSLock Lock( m_CriticalSection ); - if( a_LuaState != m_LuaState ) - { - LOGERROR("Not allowed to create a WebPlugin from another plugin but your own!"); - return 0; - } - cWebPlugin_Lua* WebPlugin = new cWebPlugin_Lua( this ); - - m_WebPlugins.push_back( WebPlugin ); - - return WebPlugin; -} - - -// Helper functions -bool cPlugin_NewLua::PushFunction( const char* a_FunctionName, bool a_bLogError /* = true */ ) -{ - lua_getglobal(m_LuaState, a_FunctionName); - if(!lua_isfunction(m_LuaState,-1)) - { - if( a_bLogError ) - { - LOGWARN("Error in plugin %s: Could not find function %s()", m_Directory.c_str(), a_FunctionName ); - } - lua_pop(m_LuaState,1); - return false; - } - return true; -} - -bool cPlugin_NewLua::CallFunction( int a_NumArgs, int a_NumResults, const char* a_FunctionName ) -{ - int s = lua_pcall(m_LuaState, a_NumArgs, a_NumResults, 0); - if( report_errors( m_LuaState, s ) ) - { - LOGWARN("Error in plugin %s calling function %s()", m_Directory.c_str(), a_FunctionName ); - return false; - } - return true; + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#define LUA_USE_POSIX +#include "cPlugin_NewLua.h" +#include "cMCLogger.h" +#include "cWebPlugin_Lua.h" +#include "LuaItems.h" + +extern "C" +{ +#include "lualib.h" +} + +#include "tolua++.h" +#include "Bindings.h" +#include "ManualBindings.h" + +#ifdef _WIN32 +// #include "wdirent.h" +#else +#include +#endif + + + + + +extern bool report_errors(lua_State* lua, int status); + + + + + +cPlugin_NewLua::cPlugin_NewLua( const char* a_PluginName ) + : m_LuaState( 0 ) +{ + m_Directory = a_PluginName; +} + + + + + +cPlugin_NewLua::~cPlugin_NewLua() +{ + cCSLock Lock( m_CriticalSection ); + for( WebPluginList::iterator itr = m_WebPlugins.begin(); itr != m_WebPlugins.end(); ++itr ) + { + delete *itr; + } + m_WebPlugins.clear(); + + if( m_LuaState ) + { + lua_close( m_LuaState ); + m_LuaState = 0; + } +} + + + + + +bool cPlugin_NewLua::Initialize() +{ + cCSLock Lock( m_CriticalSection ); + if( !m_LuaState ) + { + m_LuaState = lua_open(); + luaL_openlibs( m_LuaState ); + tolua_AllToLua_open(m_LuaState); + ManualBindings::Bind( m_LuaState ); + } + + std::string PluginPath = std::string("Plugins/") + m_Directory + "/"; + + // Load all files for this plugin, and execute them + AStringList Files = GetDirectoryContents(PluginPath.c_str()); + for (AStringList::const_iterator itr = Files.begin(); itr != Files.end(); ++itr) + { + if (itr->rfind(".lua") == AString::npos) + { + continue; + } + AString Path = PluginPath + *itr; + int s = luaL_loadfile(m_LuaState, Path.c_str() ); + if( report_errors( m_LuaState, s ) ) + { + LOGERROR("Can't load plugin %s because of an error in file %s", m_Directory.c_str(), Path.c_str() ); + lua_close( m_LuaState ); + m_LuaState = 0; + return false; + } + + s = lua_pcall(m_LuaState, 0, LUA_MULTRET, 0); + if( report_errors( m_LuaState, s ) ) + { + LOGERROR("Error in plugin %s in file %s", m_Directory.c_str(), Path.c_str() ); + lua_close( m_LuaState ); + m_LuaState = 0; + return false; + } + } // for itr - Files[] + + // Call intialize function + if( !PushFunction("Initialize") ) + { + lua_close( m_LuaState ); + m_LuaState = 0; + return false; + } + + tolua_pushusertype(m_LuaState, this, "cPlugin_NewLua"); + + if( !CallFunction(1, 1, "Initialize") ) + { + lua_close( m_LuaState ); + m_LuaState = 0; + return false; + } + + if( !lua_isboolean( m_LuaState, -1 ) ) + { + LOGWARN("Error in plugin %s Initialize() must return a boolean value!", m_Directory.c_str() ); + lua_close( m_LuaState ); + m_LuaState = 0; + return false; + } + + bool bSuccess = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bSuccess; +} + + + + + +void cPlugin_NewLua::OnDisable() +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnDisable", false) ) // false = don't log error if not found + return; + + CallFunction(0, 0, "OnDisable"); +} + + + + + +void cPlugin_NewLua::Tick(float a_Dt) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("Tick") ) + return; + + tolua_pushnumber( m_LuaState, a_Dt ); + + CallFunction(1, 0, "Tick"); +} + + + + + +bool cPlugin_NewLua::OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnCollectItem") ) + return false; + + tolua_pushusertype(m_LuaState, a_Pickup, "cPickup"); + tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + + if( !CallFunction(2, 1, "OnCollectItem") ) + return false; + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +bool cPlugin_NewLua::OnDisconnect(const AString & a_Reason, cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnDisconnect") ) + return false; + + tolua_pushstring( m_LuaState, a_Reason.c_str() ); + tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + + if( !CallFunction(2, 1, "OnDisconnect") ) + return false; + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +bool cPlugin_NewLua::OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnBlockPlace") ) + return false; + + tolua_pushusertype(m_LuaState, a_PacketData, "cPacket_BlockPlace"); + tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + + if( !CallFunction(2, 1, "OnBlockPlace") ) + return false; + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +bool cPlugin_NewLua::OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnBlockDig") ) + return false; + + tolua_pushusertype(m_LuaState, a_PacketData, "cPacket_BlockDig"); + tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + tolua_pushusertype(m_LuaState, a_PickupItem, "cItem"); + + if( !CallFunction(3, 1, "OnBlockDig") ) + return false; + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +bool cPlugin_NewLua::OnChat( const char* a_Chat, cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnChat") ) + return false; + + tolua_pushstring( m_LuaState, a_Chat ); + tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + + if( !CallFunction(2, 1, "OnChat") ) + return false; + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +bool cPlugin_NewLua::OnLogin( cPacket_Login* a_PacketData ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnLogin") ) + return false; + + tolua_pushusertype(m_LuaState, a_PacketData, "cPacket_Login"); + + if( !CallFunction(1, 1, "OnLogin") ) + return false; + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +void cPlugin_NewLua::OnPlayerSpawn( cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnPlayerSpawn") ) + return; + + tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + + CallFunction(1, 0, "OnPlayerSpawn"); +} + + + + + +bool cPlugin_NewLua::OnPlayerJoin( cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnPlayerJoin") ) + return false; + + tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + + if( !CallFunction(1, 1, "OnPlayerJoin") ) + return false; + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +void cPlugin_NewLua::OnPlayerMove( cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnPlayerMove") ) + return; + + tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + + CallFunction(1, 0, "OnPlayerMove"); +} + + + + + +void cPlugin_NewLua::OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnTakeDamage") ) + return; + + tolua_pushusertype(m_LuaState, a_Pawn, "cPawn"); + tolua_pushusertype(m_LuaState, a_TakeDamageInfo, "TakeDamageInfo"); + + CallFunction(2, 0, "OnTakeDamage"); +} + + + + + +bool cPlugin_NewLua::OnKilled( cPawn* a_Killed, cEntity* a_Killer ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnKilled") ) + return false; + + tolua_pushusertype(m_LuaState, a_Killed, "cPawn"); + tolua_pushusertype(m_LuaState, a_Killer, "cEntity"); + + if( !CallFunction(2, 1, "OnKilled") ) + return false; + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +void cPlugin_NewLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ) +{ + cCSLock Lock(m_CriticalSection); + if (!PushFunction("OnChunkGenerated")) + { + return; + } + + tolua_pushusertype(m_LuaState, a_World, "cWorld"); + tolua_pushnumber (m_LuaState, a_ChunkX); + tolua_pushnumber (m_LuaState, a_ChunkZ); + + CallFunction(3, 0, "OnChunkGenerated"); +} + + + + + +bool cPlugin_NewLua::OnChunkGenerating( int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) +{ + cCSLock Lock(m_CriticalSection); + if (!PushFunction("OnChunkGenerating")) + return false; + + tolua_pushnumber (m_LuaState, a_ChunkX); + tolua_pushnumber (m_LuaState, a_ChunkZ); + tolua_pushusertype(m_LuaState, a_pLuaChunk, "cLuaChunk"); + + if( !CallFunction(3, 1, "OnChunkGenerating") ) + return false; + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +bool cPlugin_NewLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +{ + cCSLock Lock(m_CriticalSection); + if (!PushFunction("OnPreCrafting")) + return false; + + tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); + tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); + tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); + + if (!CallFunction(3, 1, "OnPreCrafting")) + { + return false; + } + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +bool cPlugin_NewLua::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +{ + cCSLock Lock(m_CriticalSection); + if (!PushFunction("OnCraftingNoRecipe")) + return false; + + tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); + tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); + tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); + + if (!CallFunction(3, 1, "OnCraftingNoRecipe")) + { + return false; + } + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +bool cPlugin_NewLua::OnPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +{ + cCSLock Lock(m_CriticalSection); + if (!PushFunction("OnPostCrafting")) + return false; + + tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); + tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); + tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); + + if (!CallFunction(3, 1, "OnPostCrafting")) + { + return false; + } + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +bool cPlugin_NewLua::OnBlockToPickup( + BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, + const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups +) +{ + cLuaItems Pickups(a_Pickups); + cCSLock Lock(m_CriticalSection); + if (!PushFunction("OnBlockToPickup")) + return false; + + tolua_pushnumber (m_LuaState, a_BlockType); + tolua_pushnumber (m_LuaState, a_BlockMeta); + tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); + tolua_pushusertype(m_LuaState, (void *)&a_EquippedItem, "cItem"); + tolua_pushusertype(m_LuaState, (void *)&Pickups, "cLuaItems"); + + if (!CallFunction(5, 1, "OnBlockToPickup")) + { + return false; + } + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +cWebPlugin_Lua* cPlugin_NewLua::CreateWebPlugin(lua_State* a_LuaState) +{ + cCSLock Lock( m_CriticalSection ); + if( a_LuaState != m_LuaState ) + { + LOGERROR("Not allowed to create a WebPlugin from another plugin but your own!"); + return 0; + } + cWebPlugin_Lua* WebPlugin = new cWebPlugin_Lua( this ); + + m_WebPlugins.push_back( WebPlugin ); + + return WebPlugin; +} + + +// Helper functions +bool cPlugin_NewLua::PushFunction( const char* a_FunctionName, bool a_bLogError /* = true */ ) +{ + lua_getglobal(m_LuaState, a_FunctionName); + if(!lua_isfunction(m_LuaState,-1)) + { + if( a_bLogError ) + { + LOGWARN("Error in plugin %s: Could not find function %s()", m_Directory.c_str(), a_FunctionName ); + } + lua_pop(m_LuaState,1); + return false; + } + return true; +} + +bool cPlugin_NewLua::CallFunction( int a_NumArgs, int a_NumResults, const char* a_FunctionName ) +{ + int s = lua_pcall(m_LuaState, a_NumArgs, a_NumResults, 0); + if( report_errors( m_LuaState, s ) ) + { + LOGWARN("Error in plugin %s calling function %s()", m_Directory.c_str(), a_FunctionName ); + return false; + } + return true; } \ No newline at end of file diff --git a/source/cPlugin_NewLua.h b/source/cPlugin_NewLua.h index d6bb50637..e66c26e3f 100644 --- a/source/cPlugin_NewLua.h +++ b/source/cPlugin_NewLua.h @@ -1,60 +1,60 @@ - -#pragma once - -#include "cPlugin.h" - - - - - -typedef struct lua_State lua_State; -class cWebPlugin_Lua; - - - - - -class cPlugin_NewLua : public cPlugin //tolua_export -{ //tolua_export -public: //tolua_export - cPlugin_NewLua( const char* a_PluginName ); - ~cPlugin_NewLua(); - - virtual void OnDisable(); //tolua_export - virtual bool Initialize(); //tolua_export - - virtual void Tick(float a_Dt); //tolua_export - - virtual bool OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player ) override; - virtual bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player ) override; - virtual bool OnBlockPlace (cPacket_BlockPlace* a_PacketData, cPlayer* a_Player ) override; - virtual bool OnBlockDig (cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem ) override; - virtual bool OnChat (const char* a_Chat, cPlayer* a_Player ) override; - virtual bool OnLogin (cPacket_Login* a_PacketData ) override; - virtual void OnPlayerSpawn (cPlayer* a_Player ) override; - virtual bool OnPlayerJoin (cPlayer* a_Player ) override; - virtual void OnPlayerMove (cPlayer* a_Player ) override; - virtual void OnTakeDamage (cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo ) override; - virtual bool OnKilled (cPawn* a_Killed, cEntity* a_Killer ) override; - virtual void OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; - virtual bool OnChunkGenerating (int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) override; - virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; - virtual bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; - virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; - virtual bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups); - - lua_State* GetLuaState() { return m_LuaState; } - - cWebPlugin_Lua* CreateWebPlugin(lua_State* a_LuaState); //tolua_export -private: - bool PushFunction( const char* a_FunctionName, bool a_bLogError = true ); - bool CallFunction( int a_NumArgs, int a_NumResults, const char* a_FunctionName ); // a_FunctionName is only used for error messages, nothing else - - typedef std::list< cWebPlugin_Lua* > WebPluginList; - WebPluginList m_WebPlugins; - - cCriticalSection m_CriticalSection; - - std::string m_Directory; - lua_State* m_LuaState; + +#pragma once + +#include "cPlugin.h" + + + + + +typedef struct lua_State lua_State; +class cWebPlugin_Lua; + + + + + +class cPlugin_NewLua : public cPlugin //tolua_export +{ //tolua_export +public: //tolua_export + cPlugin_NewLua( const char* a_PluginName ); + ~cPlugin_NewLua(); + + virtual void OnDisable(); //tolua_export + virtual bool Initialize(); //tolua_export + + virtual void Tick(float a_Dt); //tolua_export + + virtual bool OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player ) override; + virtual bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player ) override; + virtual bool OnBlockPlace (cPacket_BlockPlace* a_PacketData, cPlayer* a_Player ) override; + virtual bool OnBlockDig (cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem ) override; + virtual bool OnChat (const char* a_Chat, cPlayer* a_Player ) override; + virtual bool OnLogin (cPacket_Login* a_PacketData ) override; + virtual void OnPlayerSpawn (cPlayer* a_Player ) override; + virtual bool OnPlayerJoin (cPlayer* a_Player ) override; + virtual void OnPlayerMove (cPlayer* a_Player ) override; + virtual void OnTakeDamage (cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo ) override; + virtual bool OnKilled (cPawn* a_Killed, cEntity* a_Killer ) override; + virtual void OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; + virtual bool OnChunkGenerating (int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) override; + virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; + virtual bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; + virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; + virtual bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups); + + lua_State* GetLuaState() { return m_LuaState; } + + cWebPlugin_Lua* CreateWebPlugin(lua_State* a_LuaState); //tolua_export +private: + bool PushFunction( const char* a_FunctionName, bool a_bLogError = true ); + bool CallFunction( int a_NumArgs, int a_NumResults, const char* a_FunctionName ); // a_FunctionName is only used for error messages, nothing else + + typedef std::list< cWebPlugin_Lua* > WebPluginList; + WebPluginList m_WebPlugins; + + cCriticalSection m_CriticalSection; + + std::string m_Directory; + lua_State* m_LuaState; };//tolua_export \ No newline at end of file diff --git a/source/cRedstone.cpp b/source/cRedstone.cpp index 5a1c9bc8b..701835d5a 100644 --- a/source/cRedstone.cpp +++ b/source/cRedstone.cpp @@ -1,374 +1,374 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cRedstone.h" -#include "cPiston.h" -#include "cRoot.h" -#include "cWorld.h" -#include "BlockID.h" -#include - - - - - -bool cRedstone::s_UseRedstone = false; - - - - - -cRedstone::cRedstone( cWorld* a_World ) - :m_World ( a_World ) - ,m_Metadata ( 0 ) - ,m_Direction ( 0 ) -{ - -} - - - - - -void cRedstone::ChangeRedstone( int fillx, int filly, int fillz, bool added ) -{ - s_UseRedstone = false; - if( !s_UseRedstone ) return; - - char before; - //int tempX; - //int tempY; - //int tempZ; - //int state; - //m_Direction - // 0 = x+ - // 1 = x- - // 2 = z+ - // 3 = z- - // 4 = y+ - // 5 = v- - - - if (added) { - m_Metadata = 15; - } else { - m_Metadata = 0; - } - before = m_Metadata; - - //printf("etb1\n"); - CalculateRedstone( fillx, filly, fillz ); //calculate all item centers. - //printf("etb2\n"); - - int Block = (int)m_World->GetBlock( fillx, filly, fillz ); - - switch (Block)//these blocks won't trigger the normal calculaton because they are affected by the redstone around them. So we check each possible channel around them instead. - { - case E_BLOCK_REDSTONE_TORCH_ON: - case E_BLOCK_REDSTONE_TORCH_OFF: - case E_BLOCK_AIR: - case E_BLOCK_PISTON_EXTENSION: - case E_BLOCK_PISTON: - case E_BLOCK_STICKY_PISTON: - { - m_Metadata = 0; - m_Direction = 0; - CalculateRedstone( fillx+1, filly, fillz ); - m_Metadata = 0; - m_Direction = 1; - CalculateRedstone( fillx-1, filly, fillz ); - m_Metadata = 0; - m_Direction = 2; - CalculateRedstone( fillx, filly, fillz+1 ); - m_Metadata = 0; - m_Direction = 3; - CalculateRedstone( fillx, filly, fillz-1 ); - m_Metadata = 0; - CalculateRedstone( fillx, filly-1, fillz ); - break; - } - case E_BLOCK_REDSTONE_WIRE: //special case for redstone wire. - { - m_Direction = 0; - CalculateRedstone( fillx+1, filly, fillz ); - m_Direction = 1; - CalculateRedstone( fillx-1, filly, fillz ); - m_Direction = 2; - CalculateRedstone( fillx, filly, fillz+1 ); - m_Direction = 3; - CalculateRedstone( fillx, filly, fillz-1 ); - m_Metadata = 0; - CalculateRedstone( fillx, filly-1, fillz ); - - m_Direction = 4; - CalculateRedstone( fillx+1, filly+1, fillz ); - CalculateRedstone( fillx-1, filly+1, fillz ); - CalculateRedstone( fillx, filly+1, fillz+1 ); - CalculateRedstone( fillx, filly+1, fillz-1 ); - - m_Direction = 5; - CalculateRedstone( fillx+1, filly-1, fillz ); - CalculateRedstone( fillx-1, filly-1, fillz ); - CalculateRedstone( fillx, filly-1, fillz+1 ); - CalculateRedstone( fillx, filly-1, fillz-1 ); - break; - } - } - - //printf("done here\n"); -} - - - - - -void cRedstone::CalculateRedstone( int fillx, int filly, int fillz) -{ - - if ( ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_STICKY_PISTON ) || ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_PISTON ) ) { - char pistonMeta = m_World->GetBlockMeta( fillx, filly, fillz ); - if (m_Metadata > 0) { - if (pistonMeta < 6) { // only extend if piston is not already extended - cPiston Piston(m_World); - Piston.ExtendPiston(fillx, filly, fillz); - } - } else { - if (pistonMeta > 6) { // only retract if piston is not already retracted - cPiston Piston(m_World); - Piston.RetractPiston(fillx, filly, fillz); - } - } - - } else if ( ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_ITEM_LEVER ) || ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_ITEM_STONE_BUTTON ) ) { - - if ( (int)m_World->GetBlockMeta( fillx, filly, fillz) > 6 ) { //button powered - m_Metadata = 15; //change meta to 15 only if redstone power device in on possition is found. - if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) { - CalculateRedstone(fillx-1,filly,fillz); - } - if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) { - CalculateRedstone(fillx+1,filly,fillz); - } - if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) { - CalculateRedstone(fillx,filly,fillz-1); - } - if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) { - CalculateRedstone(fillx,filly,fillz+1); - } - } else { - if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) { - CalculateRedstone(fillx-1,filly,fillz); - } - if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) { - CalculateRedstone(fillx+1,filly,fillz); - } - if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) { - CalculateRedstone(fillx,filly,fillz-1); - } - if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) { - CalculateRedstone(fillx,filly,fillz+1); - } - } - - } else if ( ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_STONE_PRESSURE_PLATE ) || ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_STONE_BUTTON ) ) { - - if ( (int)m_World->GetBlockMeta( fillx, filly, fillz) == 1 ) { //plate powered - m_Metadata = 15; //change meta to 15 only if redstone power device in on possition is found. - if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) { - CalculateRedstone(fillx-1,filly,fillz); - } - if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) { - CalculateRedstone(fillx+1,filly,fillz); - } - if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) { - CalculateRedstone(fillx,filly,fillz-1); - } - if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) { - CalculateRedstone(fillx,filly,fillz+1); - } - - } else { - - if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) { - CalculateRedstone(fillx-1,filly,fillz); - } - if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) { - CalculateRedstone(fillx+1,filly,fillz); - } - if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) { - CalculateRedstone(fillx,filly,fillz-1); - } - if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) { - CalculateRedstone(fillx,filly,fillz+1); - } - } - - } else if ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_ON ) { //If torch is on - //printf("found torch on\n"); - m_Metadata = 15; //change meta to 15 only if redstone torch in on possition is found. - if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) { - CalculateRedstone(fillx-1,filly,fillz); - } - if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) { - CalculateRedstone(fillx+1,filly,fillz); - } - if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) { - CalculateRedstone(fillx,filly,fillz-1); - } - if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) { - CalculateRedstone(fillx,filly,fillz+1); - } - - } else if ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_OFF ) { //if the torch is off - //printf("found torch off\n"); - // no need to change meta here. - if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) { - CalculateRedstone(fillx-1,filly,fillz); - } - if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) { - CalculateRedstone(fillx+1,filly,fillz); - } - if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) { - CalculateRedstone(fillx,filly,fillz-1); - } - if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) { - CalculateRedstone(fillx,filly,fillz+1); - } - - } else if ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_REDSTONE_WIRE ) { //simple fill algorithm for redstone wire. - - if ( (int)m_World->GetBlockMeta( fillx, filly, fillz) != m_Metadata ) { - m_World->FastSetBlock( fillx, filly, fillz, (char)E_BLOCK_REDSTONE_WIRE, m_Metadata ); - m_Direction = 0; - CalculateRedstone( fillx+1, filly, fillz ); - m_Direction = 1; - CalculateRedstone( fillx-1, filly, fillz ); - m_Direction = 2; - CalculateRedstone( fillx, filly, fillz+1 ); - m_Direction = 3; - CalculateRedstone( fillx, filly, fillz-1 ); - CalculateRedstone( fillx, filly-1, fillz ); //check one block below //similar to same plane - - m_Direction = 4; - CalculateRedstone( fillx+1, filly+1, fillz ); - CalculateRedstone( fillx-1, filly+1, fillz ); - CalculateRedstone( fillx, filly+1, fillz+1 ); - CalculateRedstone( fillx, filly+1, fillz-1 ); - - m_Direction = 5; - CalculateRedstone( fillx+1, filly-1, fillz ); - CalculateRedstone( fillx-1, filly-1, fillz ); - CalculateRedstone( fillx, filly-1, fillz+1 ); - CalculateRedstone( fillx, filly-1, fillz-1 ); - } - - } else { //default, check item for torch attached to it. If meta > 0 then turn that torch off, otherwise turn it on. This change needs to be passed to the next world tick. - //check for torch to east with meta 1 //turn off - //check for torch to west with meta 2 //turn off - //check for torch to south with meta 3 //turn off - //check for torch to north with meta 4 //turn off - //check for torch above with meta 5 //turn off - if ( (int)m_World->GetBlock( fillx, filly, fillz ) != E_BLOCK_AIR ) { - if (m_Direction < 4) { //redstone wire can only power blocks on the same plane or directly below - if ( (int)m_Metadata > 0 ) { //wire powered - - //printf("bird: %i dog: %i \n",(int)m_World->GetBlock( fillx, filly+1, fillz ),(int)m_World->GetBlockMeta( fillx, filly+1, fillz)); - if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) == 1 ) ) { //east - m_World->m_RSList.push_back(fillx+1); - m_World->m_RSList.push_back(filly); - m_World->m_RSList.push_back(fillz); - m_World->m_RSList.push_back(00000); - } - if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) == 2 ) ) { //west - m_World->m_RSList.push_back(fillx-1); - m_World->m_RSList.push_back(filly); - m_World->m_RSList.push_back(fillz); - m_World->m_RSList.push_back(00000); - } - if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_TORCH_ON) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) == 3 ) ) { //south - m_World->m_RSList.push_back(fillx); - m_World->m_RSList.push_back(filly); - m_World->m_RSList.push_back(fillz+1); - m_World->m_RSList.push_back(00000); - } - if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_TORCH_ON) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) == 4 ) ) { //north - m_World->m_RSList.push_back(fillx); - m_World->m_RSList.push_back(filly); - m_World->m_RSList.push_back(fillz-1); - m_World->m_RSList.push_back(00000); - } - if ( ( (int)m_World->GetBlock( fillx, filly+1, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) && ( (int)m_World->GetBlockMeta( fillx, filly+1, fillz) == 5 ) ) { //top - m_World->m_RSList.push_back(fillx); - m_World->m_RSList.push_back(filly+1); - m_World->m_RSList.push_back(fillz); - m_World->m_RSList.push_back(00000); - } - - } else { //wire not powered - - bool BlockPowered = IsBlockPowered( fillx, filly, fillz ); //chck this block for other wire turned on or torch turned on below: - if (BlockPowered == false) { //if block is not bowered by something else then I need to check for off torches and turn them on. - - //printf("echo: %i cruiser: %i \n",(int)m_World->GetBlock( fillx, filly+1, fillz ),(int)m_World->GetBlockMeta( fillx, filly+1, fillz)); - if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_OFF) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) == 1 ) ) { //east - m_World->m_RSList.push_back(fillx+1); - m_World->m_RSList.push_back(filly); - m_World->m_RSList.push_back(fillz); - m_World->m_RSList.push_back(11111); - } - if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_OFF) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) == 2 ) ) { //west - m_World->m_RSList.push_back(fillx-1); - m_World->m_RSList.push_back(filly); - m_World->m_RSList.push_back(fillz); - m_World->m_RSList.push_back(11111); - } - if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_TORCH_OFF) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) == 3 ) ) { //south - m_World->m_RSList.push_back(fillx); - m_World->m_RSList.push_back(filly); - m_World->m_RSList.push_back(fillz+1); - m_World->m_RSList.push_back(11111);; - } - if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_TORCH_OFF) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) == 4 ) ) { //north - m_World->m_RSList.push_back(fillx); - m_World->m_RSList.push_back(filly); - m_World->m_RSList.push_back(fillz-1); - m_World->m_RSList.push_back(11111); - } - if ( ( (int)m_World->GetBlock( fillx, filly+1, fillz ) == E_BLOCK_REDSTONE_TORCH_OFF) && ( (int)m_World->GetBlockMeta( fillx, filly+1, fillz) == 5 ) ) { //top - m_World->m_RSList.push_back(fillx); - m_World->m_RSList.push_back(filly+1); - m_World->m_RSList.push_back(fillz); - m_World->m_RSList.push_back(11111); - } - - } - - } - - } - - } - - } - -} - - - - - -bool cRedstone::IsBlockPowered( int fillx, int filly, int fillz ) -{ - - if ( (int)m_World->GetBlock( fillx, filly-1, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) { return true; } - if ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) { return true; } - if ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) { return true; } - if ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_TORCH_ON) { return true; } - if ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_TORCH_ON) { return true; } - if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) > 0 ) ) { return true; } - if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) > 0 ) ) { return true; } - if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) > 0 ) ) { return true; } - if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) > 0 ) ) { return true; } - if ( ( (int)m_World->GetBlock( fillx, filly+1, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly+1, fillz) > 0 ) ) { return true; } - return false; + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cRedstone.h" +#include "cPiston.h" +#include "cRoot.h" +#include "cWorld.h" +#include "BlockID.h" +#include + + + + + +bool cRedstone::s_UseRedstone = false; + + + + + +cRedstone::cRedstone( cWorld* a_World ) + :m_World ( a_World ) + ,m_Metadata ( 0 ) + ,m_Direction ( 0 ) +{ + +} + + + + + +void cRedstone::ChangeRedstone( int fillx, int filly, int fillz, bool added ) +{ + s_UseRedstone = false; + if( !s_UseRedstone ) return; + + char before; + //int tempX; + //int tempY; + //int tempZ; + //int state; + //m_Direction + // 0 = x+ + // 1 = x- + // 2 = z+ + // 3 = z- + // 4 = y+ + // 5 = v- + + + if (added) { + m_Metadata = 15; + } else { + m_Metadata = 0; + } + before = m_Metadata; + + //printf("etb1\n"); + CalculateRedstone( fillx, filly, fillz ); //calculate all item centers. + //printf("etb2\n"); + + int Block = (int)m_World->GetBlock( fillx, filly, fillz ); + + switch (Block)//these blocks won't trigger the normal calculaton because they are affected by the redstone around them. So we check each possible channel around them instead. + { + case E_BLOCK_REDSTONE_TORCH_ON: + case E_BLOCK_REDSTONE_TORCH_OFF: + case E_BLOCK_AIR: + case E_BLOCK_PISTON_EXTENSION: + case E_BLOCK_PISTON: + case E_BLOCK_STICKY_PISTON: + { + m_Metadata = 0; + m_Direction = 0; + CalculateRedstone( fillx+1, filly, fillz ); + m_Metadata = 0; + m_Direction = 1; + CalculateRedstone( fillx-1, filly, fillz ); + m_Metadata = 0; + m_Direction = 2; + CalculateRedstone( fillx, filly, fillz+1 ); + m_Metadata = 0; + m_Direction = 3; + CalculateRedstone( fillx, filly, fillz-1 ); + m_Metadata = 0; + CalculateRedstone( fillx, filly-1, fillz ); + break; + } + case E_BLOCK_REDSTONE_WIRE: //special case for redstone wire. + { + m_Direction = 0; + CalculateRedstone( fillx+1, filly, fillz ); + m_Direction = 1; + CalculateRedstone( fillx-1, filly, fillz ); + m_Direction = 2; + CalculateRedstone( fillx, filly, fillz+1 ); + m_Direction = 3; + CalculateRedstone( fillx, filly, fillz-1 ); + m_Metadata = 0; + CalculateRedstone( fillx, filly-1, fillz ); + + m_Direction = 4; + CalculateRedstone( fillx+1, filly+1, fillz ); + CalculateRedstone( fillx-1, filly+1, fillz ); + CalculateRedstone( fillx, filly+1, fillz+1 ); + CalculateRedstone( fillx, filly+1, fillz-1 ); + + m_Direction = 5; + CalculateRedstone( fillx+1, filly-1, fillz ); + CalculateRedstone( fillx-1, filly-1, fillz ); + CalculateRedstone( fillx, filly-1, fillz+1 ); + CalculateRedstone( fillx, filly-1, fillz-1 ); + break; + } + } + + //printf("done here\n"); +} + + + + + +void cRedstone::CalculateRedstone( int fillx, int filly, int fillz) +{ + + if ( ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_STICKY_PISTON ) || ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_PISTON ) ) { + char pistonMeta = m_World->GetBlockMeta( fillx, filly, fillz ); + if (m_Metadata > 0) { + if (pistonMeta < 6) { // only extend if piston is not already extended + cPiston Piston(m_World); + Piston.ExtendPiston(fillx, filly, fillz); + } + } else { + if (pistonMeta > 6) { // only retract if piston is not already retracted + cPiston Piston(m_World); + Piston.RetractPiston(fillx, filly, fillz); + } + } + + } else if ( ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_ITEM_LEVER ) || ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_ITEM_STONE_BUTTON ) ) { + + if ( (int)m_World->GetBlockMeta( fillx, filly, fillz) > 6 ) { //button powered + m_Metadata = 15; //change meta to 15 only if redstone power device in on possition is found. + if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx-1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx+1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz-1); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz+1); + } + } else { + if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx-1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx+1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz-1); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz+1); + } + } + + } else if ( ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_STONE_PRESSURE_PLATE ) || ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_STONE_BUTTON ) ) { + + if ( (int)m_World->GetBlockMeta( fillx, filly, fillz) == 1 ) { //plate powered + m_Metadata = 15; //change meta to 15 only if redstone power device in on possition is found. + if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx-1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx+1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz-1); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz+1); + } + + } else { + + if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx-1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx+1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz-1); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz+1); + } + } + + } else if ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_ON ) { //If torch is on + //printf("found torch on\n"); + m_Metadata = 15; //change meta to 15 only if redstone torch in on possition is found. + if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx-1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx+1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz-1); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz+1); + } + + } else if ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_OFF ) { //if the torch is off + //printf("found torch off\n"); + // no need to change meta here. + if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx-1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx+1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz-1); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz+1); + } + + } else if ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_REDSTONE_WIRE ) { //simple fill algorithm for redstone wire. + + if ( (int)m_World->GetBlockMeta( fillx, filly, fillz) != m_Metadata ) { + m_World->FastSetBlock( fillx, filly, fillz, (char)E_BLOCK_REDSTONE_WIRE, m_Metadata ); + m_Direction = 0; + CalculateRedstone( fillx+1, filly, fillz ); + m_Direction = 1; + CalculateRedstone( fillx-1, filly, fillz ); + m_Direction = 2; + CalculateRedstone( fillx, filly, fillz+1 ); + m_Direction = 3; + CalculateRedstone( fillx, filly, fillz-1 ); + CalculateRedstone( fillx, filly-1, fillz ); //check one block below //similar to same plane + + m_Direction = 4; + CalculateRedstone( fillx+1, filly+1, fillz ); + CalculateRedstone( fillx-1, filly+1, fillz ); + CalculateRedstone( fillx, filly+1, fillz+1 ); + CalculateRedstone( fillx, filly+1, fillz-1 ); + + m_Direction = 5; + CalculateRedstone( fillx+1, filly-1, fillz ); + CalculateRedstone( fillx-1, filly-1, fillz ); + CalculateRedstone( fillx, filly-1, fillz+1 ); + CalculateRedstone( fillx, filly-1, fillz-1 ); + } + + } else { //default, check item for torch attached to it. If meta > 0 then turn that torch off, otherwise turn it on. This change needs to be passed to the next world tick. + //check for torch to east with meta 1 //turn off + //check for torch to west with meta 2 //turn off + //check for torch to south with meta 3 //turn off + //check for torch to north with meta 4 //turn off + //check for torch above with meta 5 //turn off + if ( (int)m_World->GetBlock( fillx, filly, fillz ) != E_BLOCK_AIR ) { + if (m_Direction < 4) { //redstone wire can only power blocks on the same plane or directly below + if ( (int)m_Metadata > 0 ) { //wire powered + + //printf("bird: %i dog: %i \n",(int)m_World->GetBlock( fillx, filly+1, fillz ),(int)m_World->GetBlockMeta( fillx, filly+1, fillz)); + if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) == 1 ) ) { //east + m_World->m_RSList.push_back(fillx+1); + m_World->m_RSList.push_back(filly); + m_World->m_RSList.push_back(fillz); + m_World->m_RSList.push_back(00000); + } + if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) == 2 ) ) { //west + m_World->m_RSList.push_back(fillx-1); + m_World->m_RSList.push_back(filly); + m_World->m_RSList.push_back(fillz); + m_World->m_RSList.push_back(00000); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_TORCH_ON) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) == 3 ) ) { //south + m_World->m_RSList.push_back(fillx); + m_World->m_RSList.push_back(filly); + m_World->m_RSList.push_back(fillz+1); + m_World->m_RSList.push_back(00000); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_TORCH_ON) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) == 4 ) ) { //north + m_World->m_RSList.push_back(fillx); + m_World->m_RSList.push_back(filly); + m_World->m_RSList.push_back(fillz-1); + m_World->m_RSList.push_back(00000); + } + if ( ( (int)m_World->GetBlock( fillx, filly+1, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) && ( (int)m_World->GetBlockMeta( fillx, filly+1, fillz) == 5 ) ) { //top + m_World->m_RSList.push_back(fillx); + m_World->m_RSList.push_back(filly+1); + m_World->m_RSList.push_back(fillz); + m_World->m_RSList.push_back(00000); + } + + } else { //wire not powered + + bool BlockPowered = IsBlockPowered( fillx, filly, fillz ); //chck this block for other wire turned on or torch turned on below: + if (BlockPowered == false) { //if block is not bowered by something else then I need to check for off torches and turn them on. + + //printf("echo: %i cruiser: %i \n",(int)m_World->GetBlock( fillx, filly+1, fillz ),(int)m_World->GetBlockMeta( fillx, filly+1, fillz)); + if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_OFF) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) == 1 ) ) { //east + m_World->m_RSList.push_back(fillx+1); + m_World->m_RSList.push_back(filly); + m_World->m_RSList.push_back(fillz); + m_World->m_RSList.push_back(11111); + } + if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_OFF) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) == 2 ) ) { //west + m_World->m_RSList.push_back(fillx-1); + m_World->m_RSList.push_back(filly); + m_World->m_RSList.push_back(fillz); + m_World->m_RSList.push_back(11111); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_TORCH_OFF) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) == 3 ) ) { //south + m_World->m_RSList.push_back(fillx); + m_World->m_RSList.push_back(filly); + m_World->m_RSList.push_back(fillz+1); + m_World->m_RSList.push_back(11111);; + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_TORCH_OFF) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) == 4 ) ) { //north + m_World->m_RSList.push_back(fillx); + m_World->m_RSList.push_back(filly); + m_World->m_RSList.push_back(fillz-1); + m_World->m_RSList.push_back(11111); + } + if ( ( (int)m_World->GetBlock( fillx, filly+1, fillz ) == E_BLOCK_REDSTONE_TORCH_OFF) && ( (int)m_World->GetBlockMeta( fillx, filly+1, fillz) == 5 ) ) { //top + m_World->m_RSList.push_back(fillx); + m_World->m_RSList.push_back(filly+1); + m_World->m_RSList.push_back(fillz); + m_World->m_RSList.push_back(11111); + } + + } + + } + + } + + } + + } + +} + + + + + +bool cRedstone::IsBlockPowered( int fillx, int filly, int fillz ) +{ + + if ( (int)m_World->GetBlock( fillx, filly-1, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) { return true; } + if ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) { return true; } + if ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) { return true; } + if ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_TORCH_ON) { return true; } + if ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_TORCH_ON) { return true; } + if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) > 0 ) ) { return true; } + if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) > 0 ) ) { return true; } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) > 0 ) ) { return true; } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) > 0 ) ) { return true; } + if ( ( (int)m_World->GetBlock( fillx, filly+1, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly+1, fillz) > 0 ) ) { return true; } + return false; } \ No newline at end of file diff --git a/source/cRedstone.h b/source/cRedstone.h index 5c971ad36..a5377e8a7 100644 --- a/source/cRedstone.h +++ b/source/cRedstone.h @@ -1,122 +1,122 @@ -#pragma once - -#include "Vector3i.h" - -class cWorld; -class cRedstone -{ -public: - - cRedstone( cWorld* a_World ); - - static char RepeaterRotationToMetaData( float a_Rotation ) - { - a_Rotation += 90 + 45; // So its not aligned with axis - if( a_Rotation > 360.f ) a_Rotation -= 360.f; - if( a_Rotation >= 0.f && a_Rotation < 90.f ) - return 0x1; - else if( a_Rotation >= 180 && a_Rotation < 270 ) - return 0x3; - else if( a_Rotation >= 90 && a_Rotation < 180 ) - return 0x2; - else - return 0x0; - } - - static bool IsRepeaterPointingTo( const Vector3i & a_RepeaterPos, char a_MetaData, const Vector3i & a_BlockPos ) - { - switch( a_MetaData & 0x3 ) - { - case 0x0: - if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 0, 0, 1 ) ) ) - { - return true; - } - break; - case 0x1: - if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i(-1, 0, 0 ) ) ) - { - return true; - } - break; - case 0x2: - if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 0, 0,-1 ) ) ) - { - return true; - } - break; - case 0x3: - if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 1, 0, 0 ) ) ) - { - return true; - } - break; - default: - break; - } - return false; - } - - static bool IsRepeaterPointingAway( const Vector3i & a_RepeaterPos, char a_MetaData, const Vector3i & a_BlockPos ) - { - switch( a_MetaData & 0x3 ) - { - case 0x0: - if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 0, 0,-1 ) ) ) - { - return true; - } - break; - case 0x1: - if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 1, 0, 0 ) ) ) - { - return true; - } - break; - case 0x2: - if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 0, 0, 1 ) ) ) - { - return true; - } - break; - case 0x3: - if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i(-1, 0, 0 ) ) ) - { - return true; - } - break; - default: - break; - } - return false; - } - - static Vector3i GetRepeaterDirection( char a_MetaData ) - { - switch( a_MetaData & 0x3 ) - { - case 0x0: - return Vector3i( 0, 0,-1 ); - case 0x1: - return Vector3i( 1, 0, 0 ); - case 0x2: - return Vector3i( 0, 0, 1 ); - case 0x3: - return Vector3i(-1, 0, 0 ); - default: - break; - } - return Vector3i(); - } - - void CalculateRedstone( int, int, int ); - void ChangeRedstone( int, int, int, bool ); - bool IsBlockPowered( int, int, int ); - - cWorld* m_World; - - char m_Metadata; - char m_Direction; - - static bool s_UseRedstone; -}; +#pragma once + +#include "Vector3i.h" + +class cWorld; +class cRedstone +{ +public: + + cRedstone( cWorld* a_World ); + + static char RepeaterRotationToMetaData( float a_Rotation ) + { + a_Rotation += 90 + 45; // So its not aligned with axis + if( a_Rotation > 360.f ) a_Rotation -= 360.f; + if( a_Rotation >= 0.f && a_Rotation < 90.f ) + return 0x1; + else if( a_Rotation >= 180 && a_Rotation < 270 ) + return 0x3; + else if( a_Rotation >= 90 && a_Rotation < 180 ) + return 0x2; + else + return 0x0; + } + + static bool IsRepeaterPointingTo( const Vector3i & a_RepeaterPos, char a_MetaData, const Vector3i & a_BlockPos ) + { + switch( a_MetaData & 0x3 ) + { + case 0x0: + if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 0, 0, 1 ) ) ) + { + return true; + } + break; + case 0x1: + if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i(-1, 0, 0 ) ) ) + { + return true; + } + break; + case 0x2: + if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 0, 0,-1 ) ) ) + { + return true; + } + break; + case 0x3: + if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 1, 0, 0 ) ) ) + { + return true; + } + break; + default: + break; + } + return false; + } + + static bool IsRepeaterPointingAway( const Vector3i & a_RepeaterPos, char a_MetaData, const Vector3i & a_BlockPos ) + { + switch( a_MetaData & 0x3 ) + { + case 0x0: + if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 0, 0,-1 ) ) ) + { + return true; + } + break; + case 0x1: + if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 1, 0, 0 ) ) ) + { + return true; + } + break; + case 0x2: + if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 0, 0, 1 ) ) ) + { + return true; + } + break; + case 0x3: + if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i(-1, 0, 0 ) ) ) + { + return true; + } + break; + default: + break; + } + return false; + } + + static Vector3i GetRepeaterDirection( char a_MetaData ) + { + switch( a_MetaData & 0x3 ) + { + case 0x0: + return Vector3i( 0, 0,-1 ); + case 0x1: + return Vector3i( 1, 0, 0 ); + case 0x2: + return Vector3i( 0, 0, 1 ); + case 0x3: + return Vector3i(-1, 0, 0 ); + default: + break; + } + return Vector3i(); + } + + void CalculateRedstone( int, int, int ); + void ChangeRedstone( int, int, int, bool ); + bool IsBlockPowered( int, int, int ); + + cWorld* m_World; + + char m_Metadata; + char m_Direction; + + static bool s_UseRedstone; +}; diff --git a/source/cRedstoneSimulator.cpp b/source/cRedstoneSimulator.cpp index 652d5a943..44a6bdb4c 100644 --- a/source/cRedstoneSimulator.cpp +++ b/source/cRedstoneSimulator.cpp @@ -1,702 +1,702 @@ -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cRedstoneSimulator.h" -#include "cPiston.h" -#include "cWorld.h" -#include "BlockID.h" -#include "cCriticalSection.h" -#include "cTorch.h" - -#include "cRedstone.h" - - - -cRedstoneSimulator::cRedstoneSimulator( cWorld* a_World ) - : super(a_World) -{ -} - - - - - -cRedstoneSimulator::~cRedstoneSimulator() -{ -} - - - - - -void cRedstoneSimulator::WakeUp( int a_X, int a_Y, int a_Z ) -{ - if( cRedstone::s_UseRedstone ) return; // Using the other/broken simulator - - cCSLock Lock( m_CS ); - m_Blocks.push_back( Vector3i( a_X, a_Y, a_Z ) ); -} - - - - - -void cRedstoneSimulator::Simulate( float a_Dt ) -{ - if( cRedstone::s_UseRedstone ) return; // Using the other/broken simulator - - // Toggle torches on/off - while( !m_RefreshTorchesAround.empty() ) - { - Vector3i pos = m_RefreshTorchesAround.front(); - m_RefreshTorchesAround.pop_front(); - - RefreshTorchesAround( pos ); - } - - // Set repeaters to correct values, and decrement ticks - for( RepeaterList::iterator itr = m_SetRepeaters.begin(); itr != m_SetRepeaters.end(); ) - { - (*itr).Ticks--; - if( (*itr).Ticks <= 0 ) - { - char Block = m_World->GetBlock( (*itr).Position ); - if( (*itr).bPowerOn == true && Block == E_BLOCK_REDSTONE_REPEATER_OFF ) - { - m_World->FastSetBlock( (*itr).Position.x, (*itr).Position.y, (*itr).Position.z, E_BLOCK_REDSTONE_REPEATER_ON, m_World->GetBlockMeta( (*itr).Position ) ); - m_Blocks.push_back( (*itr).Position ); - } - else if( (*itr).bPowerOn == false && Block == E_BLOCK_REDSTONE_REPEATER_ON ) - { - m_World->FastSetBlock( (*itr).Position.x, (*itr).Position.y, (*itr).Position.z, E_BLOCK_REDSTONE_REPEATER_OFF, m_World->GetBlockMeta( (*itr).Position ) ); - m_Blocks.push_back( (*itr).Position ); - } - - if( (*itr).bPowerOffNextTime ) - { - (*itr).bPowerOn = false; - (*itr).bPowerOffNextTime = false; - (*itr).Ticks = 10; // TODO: Look up actual ticks from block metadata - ++itr; - } - else - { - itr = m_SetRepeaters.erase( itr ); - } - } - else - { - ++itr; - } - } - - // Handle changed blocks - { - cCSLock Lock( m_CS ); - std::swap( m_Blocks, m_BlocksBuffer ); - } - for( BlockList::iterator itr = m_BlocksBuffer.begin(); itr != m_BlocksBuffer.end(); ++itr ) - { - HandleChange( *itr ); - } - m_BlocksBuffer.clear(); -} - - - - - -void cRedstoneSimulator::RefreshTorchesAround( const Vector3i & a_BlockPos ) -{ - static Vector3i Surroundings [] = { - Vector3i(-1, 0, 0), - Vector3i( 1, 0, 0), - Vector3i( 0, 0,-1), - Vector3i( 0, 0, 1), - Vector3i( 0, 1, 0), // Also toggle torch on top - }; - char TargetBlockID = E_BLOCK_REDSTONE_TORCH_ON; - char TargetRepeaterID = E_BLOCK_REDSTONE_REPEATER_OFF; - if( IsPowered( a_BlockPos, true ) ) - { - TargetBlockID = E_BLOCK_REDSTONE_TORCH_OFF; - TargetRepeaterID = E_BLOCK_REDSTONE_REPEATER_ON; - //if( m_World->GetBlock( a_BlockPos ) == E_BLOCK_DIRT ) - //{ - // m_World->FastSetBlock( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, E_BLOCK_STONE, 0 ); - //} - } - else - { - //if( m_World->GetBlock( a_BlockPos ) == E_BLOCK_STONE ) - //{ - // m_World->FastSetBlock( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, E_BLOCK_DIRT, 0 ); - //} - } - - for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) - { - Vector3i TorchPos = a_BlockPos + Surroundings[i]; - const char Block = m_World->GetBlock( TorchPos ); - switch( Block ) - { - case E_BLOCK_REDSTONE_TORCH_ON: - case E_BLOCK_REDSTONE_TORCH_OFF: - if( Block != TargetBlockID ) - { - char TorchMeta = m_World->GetBlockMeta( TorchPos ); - if( cTorch::IsAttachedTo( TorchPos, TorchMeta, a_BlockPos ) ) - { - m_World->FastSetBlock( TorchPos.x, TorchPos.y, TorchPos.z, TargetBlockID, m_World->GetBlockMeta( TorchPos ) ); - m_Blocks.push_back( TorchPos ); - } - } - break; - case E_BLOCK_REDSTONE_REPEATER_ON: - case E_BLOCK_REDSTONE_REPEATER_OFF: - if( Block != TargetRepeaterID && cRedstone::IsRepeaterPointingAway( TorchPos, m_World->GetBlockMeta( TorchPos ), a_BlockPos ) ) - { - SetRepeater( TorchPos, 10, TargetRepeaterID == E_BLOCK_REDSTONE_REPEATER_ON ); - } - break; - default: - break; - }; - } -} - - - - - -void cRedstoneSimulator::HandleChange( const Vector3i & a_BlockPos ) -{ - std::deque< Vector3i > SpreadStack; - - Vector3i Surroundings[] = { - Vector3i( 1, 0, 0 ), - Vector3i( 1, 1, 0 ), - Vector3i( 1,-1, 0 ), - Vector3i(-1, 0, 0 ), - Vector3i(-1, 1, 0 ), - Vector3i(-1,-1, 0 ), - Vector3i( 0, 0, 1 ), - Vector3i( 0, 1, 1 ), - Vector3i( 0,-1, 1 ), - Vector3i( 0, 0,-1 ), - Vector3i( 0, 1,-1 ), - Vector3i( 0,-1,-1 ), - Vector3i( 0,-1, 0 ), - }; - - char Block = m_World->GetBlock( a_BlockPos ); - - // First check whether torch should be on or off - if( Block == E_BLOCK_REDSTONE_TORCH_ON || Block == E_BLOCK_REDSTONE_TORCH_OFF ) - { - static Vector3i Surroundings [] = { - Vector3i(-1, 0, 0), - Vector3i( 1, 0, 0), - Vector3i( 0, 0,-1), - Vector3i( 0, 0, 1), - Vector3i( 0,-1, 0), - }; - for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) - { - Vector3i pos = a_BlockPos + Surroundings[i]; - char OtherBlock = m_World->GetBlock( pos ); - if( (OtherBlock != E_BLOCK_AIR) && (OtherBlock != E_BLOCK_REDSTONE_TORCH_ON) && (OtherBlock != E_BLOCK_REDSTONE_TORCH_OFF) ) - { - RefreshTorchesAround( pos ); - } - } - Block = m_World->GetBlock( a_BlockPos ); // Make sure we got the updated block - } - else if( Block == E_BLOCK_REDSTONE_REPEATER_ON || Block == E_BLOCK_REDSTONE_REPEATER_OFF ) // Check if repeater is powered by a 'powered block' (not wires/torch) - { - Vector3i Direction = cRedstone::GetRepeaterDirection( m_World->GetBlockMeta( a_BlockPos ) ); - Vector3i pos = a_BlockPos - Direction; // NOTE: It's minus Direction - char OtherBlock = m_World->GetBlock( pos ); - if( (OtherBlock != E_BLOCK_AIR) && (OtherBlock != E_BLOCK_REDSTONE_TORCH_ON) && (OtherBlock != E_BLOCK_REDSTONE_TORCH_OFF) && (OtherBlock != E_BLOCK_REDSTONE_WIRE) ) - { - RefreshTorchesAround( pos ); - } - else - { - SetRepeater( a_BlockPos, 10, IsPowered( a_BlockPos, false ) ); - } - Block = m_World->GetBlock( a_BlockPos ); - } - - BlockList Sources; - // If torch is still on, use it as a source - if( Block == E_BLOCK_REDSTONE_TORCH_ON ) - { - Sources.push_back( a_BlockPos ); - } - else if( Block == E_BLOCK_REDSTONE_REPEATER_ON ) - { - static Vector3i Surroundings [] = { // It only spreads right in front, and one block up - Vector3i( 0, 0, 0), - Vector3i( 0, 1, 0), - }; - Vector3i Direction = cRedstone::GetRepeaterDirection( m_World->GetBlockMeta( a_BlockPos ) ); - for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) - { - Vector3i pos = a_BlockPos + Direction + Surroundings[i]; - if( PowerBlock( pos, a_BlockPos, 0xf ) ) - { - SpreadStack.push_back( pos ); - } - } - } - - // Power all blocks legally connected to the sources - if( Block != E_BLOCK_REDSTONE_REPEATER_ON ) - { - BlockList NewSources = RemoveCurrent( a_BlockPos ); - Sources.insert( Sources.end(), NewSources.begin(), NewSources.end() ); - while( !Sources.empty() ) - { - Vector3i SourcePos = Sources.back(); - Sources.pop_back(); - - char Block = m_World->GetBlock( SourcePos ); - switch( Block ) - { - case E_BLOCK_REDSTONE_TORCH_OFF: - case E_BLOCK_REDSTONE_TORCH_ON: - { - static Vector3i Surroundings [] = { - Vector3i(-1, 0, 0), - Vector3i( 1, 0, 0), - Vector3i( 0, 0,-1), - Vector3i( 0, 0, 1), - }; - for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) - { - Vector3i OtherPos = SourcePos + Surroundings[i]; - if( PowerBlock( OtherPos, a_BlockPos, 0xf ) ) - { - SpreadStack.push_back( OtherPos ); // Changed, so add to stack - } - } - } - break; - case E_BLOCK_REDSTONE_REPEATER_OFF: - case E_BLOCK_REDSTONE_REPEATER_ON: - { - static Vector3i Surroundings [] = { - Vector3i( 0, 0, 0), - Vector3i( 0, 1, 0), - }; - Vector3i Direction = cRedstone::GetRepeaterDirection( m_World->GetBlockMeta( SourcePos ) ); - for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) - { - Vector3i pos = SourcePos + Direction + Surroundings[i]; - if( PowerBlock( pos, a_BlockPos, 0xf ) ) - { - SpreadStack.push_back( pos ); - } - } - } - break; - }; - - - } - } - - - // Do a floodfill - while( !SpreadStack.empty() ) - { - Vector3i pos = SpreadStack.back(); - SpreadStack.pop_back(); - - char Meta = m_World->GetBlockMeta( pos ); - - for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) - { - Vector3i OtherPos = pos + Surroundings[i]; - if( PowerBlock( OtherPos, pos, Meta-1 ) ) - { - SpreadStack.push_back( OtherPos ); // Changed, so add to stack - } - } - } - - // Only after a redstone area has been completely simulated the redstone entities can react - while( !m_RefreshPistons.empty() ) - { - Vector3i pos = m_RefreshPistons.back(); - m_RefreshPistons.pop_back(); - - char Block = m_World->GetBlock( pos ); - switch( Block ) - { - case E_BLOCK_PISTON: - case E_BLOCK_STICKY_PISTON: - if( IsPowered( pos ) ) - { - cPiston Piston( m_World ); - Piston.ExtendPiston( pos.x, pos.y, pos.z ); - } - else - { - cPiston Piston( m_World ); - Piston.RetractPiston( pos.x, pos.y, pos.z ); - } - break; - default: - break; - }; - } -} - - - - - -bool cRedstoneSimulator::PowerBlock( const Vector3i & a_BlockPos, const Vector3i & a_FromBlock, char a_Power ) -{ - char Block = m_World->GetBlock( a_BlockPos ); - switch( Block ) - { - case E_BLOCK_REDSTONE_WIRE: - { - if( m_World->GetBlockMeta( a_BlockPos ) < a_Power ) - { - m_World->SetBlockMeta( a_BlockPos, a_Power ); - return true; - } - } - break; - case E_BLOCK_PISTON: - case E_BLOCK_STICKY_PISTON: - { - m_RefreshPistons.push_back( a_BlockPos ); - } - break; - case E_BLOCK_REDSTONE_REPEATER_OFF: - case E_BLOCK_REDSTONE_REPEATER_ON: - { - if( cRedstone::IsRepeaterPointingAway( a_BlockPos, m_World->GetBlockMeta( a_BlockPos ), a_FromBlock ) ) - { - SetRepeater( a_BlockPos, 10, true ); - } - } - break; - default: - { - if( Block != E_BLOCK_AIR && Block != E_BLOCK_REDSTONE_TORCH_ON && Block != E_BLOCK_REDSTONE_TORCH_OFF ) - { - if( IsPowered( a_BlockPos, true ) ) - { - m_RefreshTorchesAround.push_back( a_BlockPos ); - } - } - } - break; - }; - - return false; -} - - - - - -int cRedstoneSimulator::UnPowerBlock( const Vector3i & a_BlockPos, const Vector3i & a_FromBlock ) -{ - char Block = m_World->GetBlock( a_BlockPos ); - switch( Block ) - { - case E_BLOCK_REDSTONE_WIRE: - { - if( m_World->GetBlockMeta( a_BlockPos ) > 0 ) - { - m_World->SetBlockMeta( a_BlockPos, 0 ); - return 1; - } - } - break; - case E_BLOCK_PISTON: - case E_BLOCK_STICKY_PISTON: - { - m_RefreshPistons.push_back( a_BlockPos ); - } - break; - case E_BLOCK_REDSTONE_TORCH_ON: - { - return 2; - } - break; - case E_BLOCK_REDSTONE_REPEATER_ON: - { - if( cRedstone::IsRepeaterPointingTo( a_BlockPos, m_World->GetBlockMeta( a_BlockPos ), a_FromBlock ) - || cRedstone::IsRepeaterPointingTo( a_BlockPos, m_World->GetBlockMeta( a_BlockPos ), a_FromBlock - Vector3i(0, 1, 0) ) ) // Check if repeater is next/below wire - { - return 2; - } - else if( cRedstone::IsRepeaterPointingAway( a_BlockPos, m_World->GetBlockMeta( a_BlockPos ), a_FromBlock ) ) - { - SetRepeater( a_BlockPos, 10, false ); - } - } - case E_BLOCK_REDSTONE_REPEATER_OFF: - if( cRedstone::IsRepeaterPointingAway( a_BlockPos, m_World->GetBlockMeta( a_BlockPos ), a_FromBlock ) ) - { - SetRepeater( a_BlockPos, 10, false ); - } - break; - default: - if( Block != E_BLOCK_AIR && Block != E_BLOCK_REDSTONE_TORCH_ON && Block != E_BLOCK_REDSTONE_TORCH_OFF ) - { - if( !IsPowered( a_BlockPos, true ) ) - { - m_RefreshTorchesAround.push_back( a_BlockPos ); - } - } - break; - }; - - return 0; -} - - - - - -// Removes current from all powered redstone wires until it reaches an energy source. -// Also returns all energy sources it encountered -cRedstoneSimulator::BlockList cRedstoneSimulator::RemoveCurrent( const Vector3i & a_BlockPos ) -{ - - - std::deque< Vector3i > SpreadStack; - std::deque< Vector3i > FoundSources; - - Vector3i Surroundings[] = { - Vector3i( 1, 0, 0 ), - Vector3i( 1, 1, 0 ), - Vector3i( 1,-1, 0 ), - Vector3i(-1, 0, 0 ), - Vector3i(-1, 1, 0 ), - Vector3i(-1,-1, 0 ), - Vector3i( 0, 0, 1 ), - Vector3i( 0, 1, 1 ), - Vector3i( 0,-1, 1 ), - Vector3i( 0, 0,-1 ), - Vector3i( 0, 1,-1 ), - Vector3i( 0,-1,-1 ), - Vector3i( 0,-1, 0 ), - }; - - char Block = m_World->GetBlock( a_BlockPos ); - if( Block == E_BLOCK_REDSTONE_REPEATER_ON || Block == E_BLOCK_REDSTONE_REPEATER_OFF ) - { - static Vector3i Surroundings [] = { // Repeaters only spread right in front and 1 block up - Vector3i( 0, 0, 0), - Vector3i( 0, 1, 0), - }; - Vector3i Direction = cRedstone::GetRepeaterDirection( m_World->GetBlockMeta( a_BlockPos ) ); - for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) - { - Vector3i pos = a_BlockPos + Direction + Surroundings[i]; - int RetVal = UnPowerBlock( pos, a_BlockPos ); - if( RetVal == 1 ) - { - SpreadStack.push_back( pos ); // Changed, so add to stack - } - else if( RetVal == 2 ) - { - FoundSources.push_back( pos ); - } - } - } - else if( Block == E_BLOCK_REDSTONE_TORCH_OFF || Block == E_BLOCK_REDSTONE_TORCH_ON ) - { - static Vector3i Surroundings [] = { // Torches only spread on the same level - Vector3i(-1, 0, 0), - Vector3i( 1, 0, 0), - Vector3i( 0, 0,-1), - Vector3i( 0, 0, 1), - }; - - for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) - { - Vector3i pos = Vector3i( a_BlockPos ) + Surroundings[i]; - int RetVal = UnPowerBlock( pos, a_BlockPos ); - if( RetVal == 1 ) - { - SpreadStack.push_back( pos ); // Changed, so add to stack - } - else if( RetVal == 2 ) - { - FoundSources.push_back( pos ); - } - } - } - else - { - SpreadStack.push_back( a_BlockPos ); - } - - - while( !SpreadStack.empty() ) - { - Vector3i pos = SpreadStack.back(); - SpreadStack.pop_back(); - - for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) - { - Vector3i OtherPos = pos + Surroundings[i]; - int RetVal = UnPowerBlock( OtherPos, pos ); - if( RetVal == 1 ) - { - SpreadStack.push_back( OtherPos ); // Changed, so add to stack - } - else if( RetVal == 2 ) - { - FoundSources.push_back( OtherPos ); - } - } - } - - return FoundSources; -} - - - - - -bool cRedstoneSimulator::IsPowering( const Vector3i & a_PowerPos, const Vector3i & a_BlockPos, eRedstoneDirection a_WireDirection, bool a_bOnlyByWire ) -{ - char PowerBlock = m_World->GetBlock( a_PowerPos ); - if( !a_bOnlyByWire && PowerBlock == E_BLOCK_REDSTONE_TORCH_ON ) return true; - if( PowerBlock == E_BLOCK_REDSTONE_REPEATER_ON ) // A repeater pointing towards block is regarded as wire - { - if( cRedstone::IsRepeaterPointingTo( a_PowerPos, m_World->GetBlockMeta( a_PowerPos ), a_BlockPos ) ) - { - return true; - } - } - if( PowerBlock == E_BLOCK_REDSTONE_WIRE ) - { - if( m_World->GetBlockMeta( a_PowerPos ) > 0 ) - { - if( GetDirection( a_PowerPos ) == a_WireDirection ) - { - return true; - } - } - } - - return false; -} - - - - - -bool cRedstoneSimulator::IsPowered( const Vector3i & a_BlockPos, bool a_bOnlyByWire /* = false */ ) -{ - char Block = m_World->GetBlock( a_BlockPos ); - if( Block == E_BLOCK_REDSTONE_REPEATER_OFF || Block == E_BLOCK_REDSTONE_REPEATER_ON ) - { - Vector3i Behind = a_BlockPos - cRedstone::GetRepeaterDirection( m_World->GetBlockMeta( a_BlockPos ) ); - char BehindBlock = m_World->GetBlock( Behind ); - if( BehindBlock == E_BLOCK_REDSTONE_TORCH_ON ) - { - return true; - } - if( BehindBlock == E_BLOCK_REDSTONE_WIRE ) - { - if( m_World->GetBlockMeta( Behind ) > 0 ) - { - return true; - } - } - if( BehindBlock == E_BLOCK_REDSTONE_REPEATER_ON ) - { - if( cRedstone::IsRepeaterPointingTo( Behind, m_World->GetBlockMeta( Behind ), a_BlockPos ) ) - { - return true; - } - } - return false; - } - - if( IsPowering( Vector3i( a_BlockPos.x-1, a_BlockPos.y, a_BlockPos.z ), a_BlockPos, REDSTONE_X_POS, a_bOnlyByWire ) ) - return true; - if( IsPowering( Vector3i( a_BlockPos.x+1, a_BlockPos.y, a_BlockPos.z ), a_BlockPos, REDSTONE_X_NEG, a_bOnlyByWire ) ) - return true; - if( IsPowering( Vector3i( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z-1 ), a_BlockPos, REDSTONE_Z_POS, a_bOnlyByWire ) ) - return true; - if( IsPowering( Vector3i( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z+1 ), a_BlockPos, REDSTONE_Z_NEG, a_bOnlyByWire ) ) - return true; - - // Only wires can power the bottom block - char PosY = m_World->GetBlock( a_BlockPos.x, a_BlockPos.y+1, a_BlockPos.z ); - if( PosY == E_BLOCK_REDSTONE_WIRE ) - { - if( m_World->GetBlockMeta( a_BlockPos.x, a_BlockPos.y+1, a_BlockPos.z ) > 0 ) - { - return true; - } - } - - return false; -} - - - - -// Believe me, it works!! TODO: Add repeaters and low/high wires -cRedstoneSimulator::eRedstoneDirection cRedstoneSimulator::GetDirection( int a_X, int a_Y, int a_Z ) -{ - int Dir = REDSTONE_NONE; - - char NegX = m_World->GetBlock( a_X-1, a_Y, a_Z ); - if( NegX == E_BLOCK_REDSTONE_WIRE || NegX == E_BLOCK_REDSTONE_TORCH_ON ) - { - Dir |= (REDSTONE_X_POS); - } - char PosX = m_World->GetBlock( a_X+1, a_Y, a_Z ); - if( PosX == E_BLOCK_REDSTONE_WIRE || PosX == E_BLOCK_REDSTONE_TORCH_ON ) - { - Dir |= (REDSTONE_X_NEG); - } - char NegZ = m_World->GetBlock( a_X, a_Y, a_Z-1 ); - if( NegZ == E_BLOCK_REDSTONE_WIRE || NegZ == E_BLOCK_REDSTONE_TORCH_ON ) - { - if( (Dir & REDSTONE_X_POS) && !(Dir & REDSTONE_X_NEG ) ) //corner - { - Dir ^= REDSTONE_X_POS; - Dir |= REDSTONE_X_NEG; - } - if( (Dir & REDSTONE_X_NEG) && !(Dir & REDSTONE_X_POS ) ) //corner - { - Dir ^= REDSTONE_X_NEG; - Dir |= REDSTONE_X_POS; - } - Dir |= REDSTONE_Z_POS; - } - char PosZ = m_World->GetBlock( a_X, a_Y, a_Z+1 ); - if( PosZ == E_BLOCK_REDSTONE_WIRE || PosZ == E_BLOCK_REDSTONE_TORCH_ON ) - { - if( (Dir & REDSTONE_X_POS) && !(Dir & REDSTONE_X_NEG ) ) //corner - { - Dir ^= REDSTONE_X_POS; - Dir |= REDSTONE_X_NEG; - } - if( (Dir & REDSTONE_X_NEG) && !(Dir & REDSTONE_X_POS ) ) //corner - { - Dir ^= REDSTONE_X_NEG; - Dir |= REDSTONE_X_POS; - } - Dir |= REDSTONE_Z_NEG; - } - - return (eRedstoneDirection)Dir; +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cRedstoneSimulator.h" +#include "cPiston.h" +#include "cWorld.h" +#include "BlockID.h" +#include "cCriticalSection.h" +#include "cTorch.h" + +#include "cRedstone.h" + + + +cRedstoneSimulator::cRedstoneSimulator( cWorld* a_World ) + : super(a_World) +{ +} + + + + + +cRedstoneSimulator::~cRedstoneSimulator() +{ +} + + + + + +void cRedstoneSimulator::WakeUp( int a_X, int a_Y, int a_Z ) +{ + if( cRedstone::s_UseRedstone ) return; // Using the other/broken simulator + + cCSLock Lock( m_CS ); + m_Blocks.push_back( Vector3i( a_X, a_Y, a_Z ) ); +} + + + + + +void cRedstoneSimulator::Simulate( float a_Dt ) +{ + if( cRedstone::s_UseRedstone ) return; // Using the other/broken simulator + + // Toggle torches on/off + while( !m_RefreshTorchesAround.empty() ) + { + Vector3i pos = m_RefreshTorchesAround.front(); + m_RefreshTorchesAround.pop_front(); + + RefreshTorchesAround( pos ); + } + + // Set repeaters to correct values, and decrement ticks + for( RepeaterList::iterator itr = m_SetRepeaters.begin(); itr != m_SetRepeaters.end(); ) + { + (*itr).Ticks--; + if( (*itr).Ticks <= 0 ) + { + char Block = m_World->GetBlock( (*itr).Position ); + if( (*itr).bPowerOn == true && Block == E_BLOCK_REDSTONE_REPEATER_OFF ) + { + m_World->FastSetBlock( (*itr).Position.x, (*itr).Position.y, (*itr).Position.z, E_BLOCK_REDSTONE_REPEATER_ON, m_World->GetBlockMeta( (*itr).Position ) ); + m_Blocks.push_back( (*itr).Position ); + } + else if( (*itr).bPowerOn == false && Block == E_BLOCK_REDSTONE_REPEATER_ON ) + { + m_World->FastSetBlock( (*itr).Position.x, (*itr).Position.y, (*itr).Position.z, E_BLOCK_REDSTONE_REPEATER_OFF, m_World->GetBlockMeta( (*itr).Position ) ); + m_Blocks.push_back( (*itr).Position ); + } + + if( (*itr).bPowerOffNextTime ) + { + (*itr).bPowerOn = false; + (*itr).bPowerOffNextTime = false; + (*itr).Ticks = 10; // TODO: Look up actual ticks from block metadata + ++itr; + } + else + { + itr = m_SetRepeaters.erase( itr ); + } + } + else + { + ++itr; + } + } + + // Handle changed blocks + { + cCSLock Lock( m_CS ); + std::swap( m_Blocks, m_BlocksBuffer ); + } + for( BlockList::iterator itr = m_BlocksBuffer.begin(); itr != m_BlocksBuffer.end(); ++itr ) + { + HandleChange( *itr ); + } + m_BlocksBuffer.clear(); +} + + + + + +void cRedstoneSimulator::RefreshTorchesAround( const Vector3i & a_BlockPos ) +{ + static Vector3i Surroundings [] = { + Vector3i(-1, 0, 0), + Vector3i( 1, 0, 0), + Vector3i( 0, 0,-1), + Vector3i( 0, 0, 1), + Vector3i( 0, 1, 0), // Also toggle torch on top + }; + char TargetBlockID = E_BLOCK_REDSTONE_TORCH_ON; + char TargetRepeaterID = E_BLOCK_REDSTONE_REPEATER_OFF; + if( IsPowered( a_BlockPos, true ) ) + { + TargetBlockID = E_BLOCK_REDSTONE_TORCH_OFF; + TargetRepeaterID = E_BLOCK_REDSTONE_REPEATER_ON; + //if( m_World->GetBlock( a_BlockPos ) == E_BLOCK_DIRT ) + //{ + // m_World->FastSetBlock( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, E_BLOCK_STONE, 0 ); + //} + } + else + { + //if( m_World->GetBlock( a_BlockPos ) == E_BLOCK_STONE ) + //{ + // m_World->FastSetBlock( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, E_BLOCK_DIRT, 0 ); + //} + } + + for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) + { + Vector3i TorchPos = a_BlockPos + Surroundings[i]; + const char Block = m_World->GetBlock( TorchPos ); + switch( Block ) + { + case E_BLOCK_REDSTONE_TORCH_ON: + case E_BLOCK_REDSTONE_TORCH_OFF: + if( Block != TargetBlockID ) + { + char TorchMeta = m_World->GetBlockMeta( TorchPos ); + if( cTorch::IsAttachedTo( TorchPos, TorchMeta, a_BlockPos ) ) + { + m_World->FastSetBlock( TorchPos.x, TorchPos.y, TorchPos.z, TargetBlockID, m_World->GetBlockMeta( TorchPos ) ); + m_Blocks.push_back( TorchPos ); + } + } + break; + case E_BLOCK_REDSTONE_REPEATER_ON: + case E_BLOCK_REDSTONE_REPEATER_OFF: + if( Block != TargetRepeaterID && cRedstone::IsRepeaterPointingAway( TorchPos, m_World->GetBlockMeta( TorchPos ), a_BlockPos ) ) + { + SetRepeater( TorchPos, 10, TargetRepeaterID == E_BLOCK_REDSTONE_REPEATER_ON ); + } + break; + default: + break; + }; + } +} + + + + + +void cRedstoneSimulator::HandleChange( const Vector3i & a_BlockPos ) +{ + std::deque< Vector3i > SpreadStack; + + Vector3i Surroundings[] = { + Vector3i( 1, 0, 0 ), + Vector3i( 1, 1, 0 ), + Vector3i( 1,-1, 0 ), + Vector3i(-1, 0, 0 ), + Vector3i(-1, 1, 0 ), + Vector3i(-1,-1, 0 ), + Vector3i( 0, 0, 1 ), + Vector3i( 0, 1, 1 ), + Vector3i( 0,-1, 1 ), + Vector3i( 0, 0,-1 ), + Vector3i( 0, 1,-1 ), + Vector3i( 0,-1,-1 ), + Vector3i( 0,-1, 0 ), + }; + + char Block = m_World->GetBlock( a_BlockPos ); + + // First check whether torch should be on or off + if( Block == E_BLOCK_REDSTONE_TORCH_ON || Block == E_BLOCK_REDSTONE_TORCH_OFF ) + { + static Vector3i Surroundings [] = { + Vector3i(-1, 0, 0), + Vector3i( 1, 0, 0), + Vector3i( 0, 0,-1), + Vector3i( 0, 0, 1), + Vector3i( 0,-1, 0), + }; + for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) + { + Vector3i pos = a_BlockPos + Surroundings[i]; + char OtherBlock = m_World->GetBlock( pos ); + if( (OtherBlock != E_BLOCK_AIR) && (OtherBlock != E_BLOCK_REDSTONE_TORCH_ON) && (OtherBlock != E_BLOCK_REDSTONE_TORCH_OFF) ) + { + RefreshTorchesAround( pos ); + } + } + Block = m_World->GetBlock( a_BlockPos ); // Make sure we got the updated block + } + else if( Block == E_BLOCK_REDSTONE_REPEATER_ON || Block == E_BLOCK_REDSTONE_REPEATER_OFF ) // Check if repeater is powered by a 'powered block' (not wires/torch) + { + Vector3i Direction = cRedstone::GetRepeaterDirection( m_World->GetBlockMeta( a_BlockPos ) ); + Vector3i pos = a_BlockPos - Direction; // NOTE: It's minus Direction + char OtherBlock = m_World->GetBlock( pos ); + if( (OtherBlock != E_BLOCK_AIR) && (OtherBlock != E_BLOCK_REDSTONE_TORCH_ON) && (OtherBlock != E_BLOCK_REDSTONE_TORCH_OFF) && (OtherBlock != E_BLOCK_REDSTONE_WIRE) ) + { + RefreshTorchesAround( pos ); + } + else + { + SetRepeater( a_BlockPos, 10, IsPowered( a_BlockPos, false ) ); + } + Block = m_World->GetBlock( a_BlockPos ); + } + + BlockList Sources; + // If torch is still on, use it as a source + if( Block == E_BLOCK_REDSTONE_TORCH_ON ) + { + Sources.push_back( a_BlockPos ); + } + else if( Block == E_BLOCK_REDSTONE_REPEATER_ON ) + { + static Vector3i Surroundings [] = { // It only spreads right in front, and one block up + Vector3i( 0, 0, 0), + Vector3i( 0, 1, 0), + }; + Vector3i Direction = cRedstone::GetRepeaterDirection( m_World->GetBlockMeta( a_BlockPos ) ); + for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) + { + Vector3i pos = a_BlockPos + Direction + Surroundings[i]; + if( PowerBlock( pos, a_BlockPos, 0xf ) ) + { + SpreadStack.push_back( pos ); + } + } + } + + // Power all blocks legally connected to the sources + if( Block != E_BLOCK_REDSTONE_REPEATER_ON ) + { + BlockList NewSources = RemoveCurrent( a_BlockPos ); + Sources.insert( Sources.end(), NewSources.begin(), NewSources.end() ); + while( !Sources.empty() ) + { + Vector3i SourcePos = Sources.back(); + Sources.pop_back(); + + char Block = m_World->GetBlock( SourcePos ); + switch( Block ) + { + case E_BLOCK_REDSTONE_TORCH_OFF: + case E_BLOCK_REDSTONE_TORCH_ON: + { + static Vector3i Surroundings [] = { + Vector3i(-1, 0, 0), + Vector3i( 1, 0, 0), + Vector3i( 0, 0,-1), + Vector3i( 0, 0, 1), + }; + for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) + { + Vector3i OtherPos = SourcePos + Surroundings[i]; + if( PowerBlock( OtherPos, a_BlockPos, 0xf ) ) + { + SpreadStack.push_back( OtherPos ); // Changed, so add to stack + } + } + } + break; + case E_BLOCK_REDSTONE_REPEATER_OFF: + case E_BLOCK_REDSTONE_REPEATER_ON: + { + static Vector3i Surroundings [] = { + Vector3i( 0, 0, 0), + Vector3i( 0, 1, 0), + }; + Vector3i Direction = cRedstone::GetRepeaterDirection( m_World->GetBlockMeta( SourcePos ) ); + for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) + { + Vector3i pos = SourcePos + Direction + Surroundings[i]; + if( PowerBlock( pos, a_BlockPos, 0xf ) ) + { + SpreadStack.push_back( pos ); + } + } + } + break; + }; + + + } + } + + + // Do a floodfill + while( !SpreadStack.empty() ) + { + Vector3i pos = SpreadStack.back(); + SpreadStack.pop_back(); + + char Meta = m_World->GetBlockMeta( pos ); + + for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) + { + Vector3i OtherPos = pos + Surroundings[i]; + if( PowerBlock( OtherPos, pos, Meta-1 ) ) + { + SpreadStack.push_back( OtherPos ); // Changed, so add to stack + } + } + } + + // Only after a redstone area has been completely simulated the redstone entities can react + while( !m_RefreshPistons.empty() ) + { + Vector3i pos = m_RefreshPistons.back(); + m_RefreshPistons.pop_back(); + + char Block = m_World->GetBlock( pos ); + switch( Block ) + { + case E_BLOCK_PISTON: + case E_BLOCK_STICKY_PISTON: + if( IsPowered( pos ) ) + { + cPiston Piston( m_World ); + Piston.ExtendPiston( pos.x, pos.y, pos.z ); + } + else + { + cPiston Piston( m_World ); + Piston.RetractPiston( pos.x, pos.y, pos.z ); + } + break; + default: + break; + }; + } +} + + + + + +bool cRedstoneSimulator::PowerBlock( const Vector3i & a_BlockPos, const Vector3i & a_FromBlock, char a_Power ) +{ + char Block = m_World->GetBlock( a_BlockPos ); + switch( Block ) + { + case E_BLOCK_REDSTONE_WIRE: + { + if( m_World->GetBlockMeta( a_BlockPos ) < a_Power ) + { + m_World->SetBlockMeta( a_BlockPos, a_Power ); + return true; + } + } + break; + case E_BLOCK_PISTON: + case E_BLOCK_STICKY_PISTON: + { + m_RefreshPistons.push_back( a_BlockPos ); + } + break; + case E_BLOCK_REDSTONE_REPEATER_OFF: + case E_BLOCK_REDSTONE_REPEATER_ON: + { + if( cRedstone::IsRepeaterPointingAway( a_BlockPos, m_World->GetBlockMeta( a_BlockPos ), a_FromBlock ) ) + { + SetRepeater( a_BlockPos, 10, true ); + } + } + break; + default: + { + if( Block != E_BLOCK_AIR && Block != E_BLOCK_REDSTONE_TORCH_ON && Block != E_BLOCK_REDSTONE_TORCH_OFF ) + { + if( IsPowered( a_BlockPos, true ) ) + { + m_RefreshTorchesAround.push_back( a_BlockPos ); + } + } + } + break; + }; + + return false; +} + + + + + +int cRedstoneSimulator::UnPowerBlock( const Vector3i & a_BlockPos, const Vector3i & a_FromBlock ) +{ + char Block = m_World->GetBlock( a_BlockPos ); + switch( Block ) + { + case E_BLOCK_REDSTONE_WIRE: + { + if( m_World->GetBlockMeta( a_BlockPos ) > 0 ) + { + m_World->SetBlockMeta( a_BlockPos, 0 ); + return 1; + } + } + break; + case E_BLOCK_PISTON: + case E_BLOCK_STICKY_PISTON: + { + m_RefreshPistons.push_back( a_BlockPos ); + } + break; + case E_BLOCK_REDSTONE_TORCH_ON: + { + return 2; + } + break; + case E_BLOCK_REDSTONE_REPEATER_ON: + { + if( cRedstone::IsRepeaterPointingTo( a_BlockPos, m_World->GetBlockMeta( a_BlockPos ), a_FromBlock ) + || cRedstone::IsRepeaterPointingTo( a_BlockPos, m_World->GetBlockMeta( a_BlockPos ), a_FromBlock - Vector3i(0, 1, 0) ) ) // Check if repeater is next/below wire + { + return 2; + } + else if( cRedstone::IsRepeaterPointingAway( a_BlockPos, m_World->GetBlockMeta( a_BlockPos ), a_FromBlock ) ) + { + SetRepeater( a_BlockPos, 10, false ); + } + } + case E_BLOCK_REDSTONE_REPEATER_OFF: + if( cRedstone::IsRepeaterPointingAway( a_BlockPos, m_World->GetBlockMeta( a_BlockPos ), a_FromBlock ) ) + { + SetRepeater( a_BlockPos, 10, false ); + } + break; + default: + if( Block != E_BLOCK_AIR && Block != E_BLOCK_REDSTONE_TORCH_ON && Block != E_BLOCK_REDSTONE_TORCH_OFF ) + { + if( !IsPowered( a_BlockPos, true ) ) + { + m_RefreshTorchesAround.push_back( a_BlockPos ); + } + } + break; + }; + + return 0; +} + + + + + +// Removes current from all powered redstone wires until it reaches an energy source. +// Also returns all energy sources it encountered +cRedstoneSimulator::BlockList cRedstoneSimulator::RemoveCurrent( const Vector3i & a_BlockPos ) +{ + + + std::deque< Vector3i > SpreadStack; + std::deque< Vector3i > FoundSources; + + Vector3i Surroundings[] = { + Vector3i( 1, 0, 0 ), + Vector3i( 1, 1, 0 ), + Vector3i( 1,-1, 0 ), + Vector3i(-1, 0, 0 ), + Vector3i(-1, 1, 0 ), + Vector3i(-1,-1, 0 ), + Vector3i( 0, 0, 1 ), + Vector3i( 0, 1, 1 ), + Vector3i( 0,-1, 1 ), + Vector3i( 0, 0,-1 ), + Vector3i( 0, 1,-1 ), + Vector3i( 0,-1,-1 ), + Vector3i( 0,-1, 0 ), + }; + + char Block = m_World->GetBlock( a_BlockPos ); + if( Block == E_BLOCK_REDSTONE_REPEATER_ON || Block == E_BLOCK_REDSTONE_REPEATER_OFF ) + { + static Vector3i Surroundings [] = { // Repeaters only spread right in front and 1 block up + Vector3i( 0, 0, 0), + Vector3i( 0, 1, 0), + }; + Vector3i Direction = cRedstone::GetRepeaterDirection( m_World->GetBlockMeta( a_BlockPos ) ); + for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) + { + Vector3i pos = a_BlockPos + Direction + Surroundings[i]; + int RetVal = UnPowerBlock( pos, a_BlockPos ); + if( RetVal == 1 ) + { + SpreadStack.push_back( pos ); // Changed, so add to stack + } + else if( RetVal == 2 ) + { + FoundSources.push_back( pos ); + } + } + } + else if( Block == E_BLOCK_REDSTONE_TORCH_OFF || Block == E_BLOCK_REDSTONE_TORCH_ON ) + { + static Vector3i Surroundings [] = { // Torches only spread on the same level + Vector3i(-1, 0, 0), + Vector3i( 1, 0, 0), + Vector3i( 0, 0,-1), + Vector3i( 0, 0, 1), + }; + + for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) + { + Vector3i pos = Vector3i( a_BlockPos ) + Surroundings[i]; + int RetVal = UnPowerBlock( pos, a_BlockPos ); + if( RetVal == 1 ) + { + SpreadStack.push_back( pos ); // Changed, so add to stack + } + else if( RetVal == 2 ) + { + FoundSources.push_back( pos ); + } + } + } + else + { + SpreadStack.push_back( a_BlockPos ); + } + + + while( !SpreadStack.empty() ) + { + Vector3i pos = SpreadStack.back(); + SpreadStack.pop_back(); + + for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) + { + Vector3i OtherPos = pos + Surroundings[i]; + int RetVal = UnPowerBlock( OtherPos, pos ); + if( RetVal == 1 ) + { + SpreadStack.push_back( OtherPos ); // Changed, so add to stack + } + else if( RetVal == 2 ) + { + FoundSources.push_back( OtherPos ); + } + } + } + + return FoundSources; +} + + + + + +bool cRedstoneSimulator::IsPowering( const Vector3i & a_PowerPos, const Vector3i & a_BlockPos, eRedstoneDirection a_WireDirection, bool a_bOnlyByWire ) +{ + char PowerBlock = m_World->GetBlock( a_PowerPos ); + if( !a_bOnlyByWire && PowerBlock == E_BLOCK_REDSTONE_TORCH_ON ) return true; + if( PowerBlock == E_BLOCK_REDSTONE_REPEATER_ON ) // A repeater pointing towards block is regarded as wire + { + if( cRedstone::IsRepeaterPointingTo( a_PowerPos, m_World->GetBlockMeta( a_PowerPos ), a_BlockPos ) ) + { + return true; + } + } + if( PowerBlock == E_BLOCK_REDSTONE_WIRE ) + { + if( m_World->GetBlockMeta( a_PowerPos ) > 0 ) + { + if( GetDirection( a_PowerPos ) == a_WireDirection ) + { + return true; + } + } + } + + return false; +} + + + + + +bool cRedstoneSimulator::IsPowered( const Vector3i & a_BlockPos, bool a_bOnlyByWire /* = false */ ) +{ + char Block = m_World->GetBlock( a_BlockPos ); + if( Block == E_BLOCK_REDSTONE_REPEATER_OFF || Block == E_BLOCK_REDSTONE_REPEATER_ON ) + { + Vector3i Behind = a_BlockPos - cRedstone::GetRepeaterDirection( m_World->GetBlockMeta( a_BlockPos ) ); + char BehindBlock = m_World->GetBlock( Behind ); + if( BehindBlock == E_BLOCK_REDSTONE_TORCH_ON ) + { + return true; + } + if( BehindBlock == E_BLOCK_REDSTONE_WIRE ) + { + if( m_World->GetBlockMeta( Behind ) > 0 ) + { + return true; + } + } + if( BehindBlock == E_BLOCK_REDSTONE_REPEATER_ON ) + { + if( cRedstone::IsRepeaterPointingTo( Behind, m_World->GetBlockMeta( Behind ), a_BlockPos ) ) + { + return true; + } + } + return false; + } + + if( IsPowering( Vector3i( a_BlockPos.x-1, a_BlockPos.y, a_BlockPos.z ), a_BlockPos, REDSTONE_X_POS, a_bOnlyByWire ) ) + return true; + if( IsPowering( Vector3i( a_BlockPos.x+1, a_BlockPos.y, a_BlockPos.z ), a_BlockPos, REDSTONE_X_NEG, a_bOnlyByWire ) ) + return true; + if( IsPowering( Vector3i( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z-1 ), a_BlockPos, REDSTONE_Z_POS, a_bOnlyByWire ) ) + return true; + if( IsPowering( Vector3i( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z+1 ), a_BlockPos, REDSTONE_Z_NEG, a_bOnlyByWire ) ) + return true; + + // Only wires can power the bottom block + char PosY = m_World->GetBlock( a_BlockPos.x, a_BlockPos.y+1, a_BlockPos.z ); + if( PosY == E_BLOCK_REDSTONE_WIRE ) + { + if( m_World->GetBlockMeta( a_BlockPos.x, a_BlockPos.y+1, a_BlockPos.z ) > 0 ) + { + return true; + } + } + + return false; +} + + + + +// Believe me, it works!! TODO: Add repeaters and low/high wires +cRedstoneSimulator::eRedstoneDirection cRedstoneSimulator::GetDirection( int a_X, int a_Y, int a_Z ) +{ + int Dir = REDSTONE_NONE; + + char NegX = m_World->GetBlock( a_X-1, a_Y, a_Z ); + if( NegX == E_BLOCK_REDSTONE_WIRE || NegX == E_BLOCK_REDSTONE_TORCH_ON ) + { + Dir |= (REDSTONE_X_POS); + } + char PosX = m_World->GetBlock( a_X+1, a_Y, a_Z ); + if( PosX == E_BLOCK_REDSTONE_WIRE || PosX == E_BLOCK_REDSTONE_TORCH_ON ) + { + Dir |= (REDSTONE_X_NEG); + } + char NegZ = m_World->GetBlock( a_X, a_Y, a_Z-1 ); + if( NegZ == E_BLOCK_REDSTONE_WIRE || NegZ == E_BLOCK_REDSTONE_TORCH_ON ) + { + if( (Dir & REDSTONE_X_POS) && !(Dir & REDSTONE_X_NEG ) ) //corner + { + Dir ^= REDSTONE_X_POS; + Dir |= REDSTONE_X_NEG; + } + if( (Dir & REDSTONE_X_NEG) && !(Dir & REDSTONE_X_POS ) ) //corner + { + Dir ^= REDSTONE_X_NEG; + Dir |= REDSTONE_X_POS; + } + Dir |= REDSTONE_Z_POS; + } + char PosZ = m_World->GetBlock( a_X, a_Y, a_Z+1 ); + if( PosZ == E_BLOCK_REDSTONE_WIRE || PosZ == E_BLOCK_REDSTONE_TORCH_ON ) + { + if( (Dir & REDSTONE_X_POS) && !(Dir & REDSTONE_X_NEG ) ) //corner + { + Dir ^= REDSTONE_X_POS; + Dir |= REDSTONE_X_NEG; + } + if( (Dir & REDSTONE_X_NEG) && !(Dir & REDSTONE_X_POS ) ) //corner + { + Dir ^= REDSTONE_X_NEG; + Dir |= REDSTONE_X_POS; + } + Dir |= REDSTONE_Z_NEG; + } + + return (eRedstoneDirection)Dir; } \ No newline at end of file diff --git a/source/cRedstoneSimulator.h b/source/cRedstoneSimulator.h index 927902f5a..6ac1eef5d 100644 --- a/source/cRedstoneSimulator.h +++ b/source/cRedstoneSimulator.h @@ -1,90 +1,90 @@ -#pragma once - -#include "cSimulator.h" -#include "Vector3i.h" - -class cRedstoneSimulator : public cSimulator -{ - typedef cSimulator super; -public: - cRedstoneSimulator( cWorld* a_World ); - ~cRedstoneSimulator(); - - virtual void Simulate( float a_Dt ); - virtual bool IsAllowedBlock( char a_BlockID ) { return true; } - - virtual void WakeUp( int a_X, int a_Y, int a_Z ); - - enum eRedstoneDirection - { - REDSTONE_NONE = 0, - REDSTONE_X_POS = 0x1, - REDSTONE_X_NEG = 0x2, - REDSTONE_Z_POS = 0x4, - REDSTONE_Z_NEG = 0x8, - }; - eRedstoneDirection GetDirection( int a_X, int a_Y, int a_Z ); - eRedstoneDirection GetDirection( const Vector3i & a_Pos ) { return GetDirection( a_Pos.x, a_Pos.y, a_Pos.z ); } -private: - struct sRepeaterChange - { - Vector3i Position; - int Ticks; - bool bPowerOn; - bool bPowerOffNextTime; - }; - - typedef std::deque BlockList; - - typedef std::deque< sRepeaterChange > RepeaterList; - RepeaterList m_SetRepeaters; - void SetRepeater( const Vector3i & a_Position, int a_Ticks, bool a_bPowerOn ) - { - for( RepeaterList::iterator itr = m_SetRepeaters.begin(); itr != m_SetRepeaters.end(); ++itr ) - { - sRepeaterChange & Change = *itr; - if( Change.Position.Equals( a_Position ) ) - { - if( Change.bPowerOn && a_bPowerOn == false ) - { - Change.bPowerOffNextTime = true; - } - if( a_bPowerOn == true ) - { - Change.bPowerOffNextTime = false; - } - Change.bPowerOn |= a_bPowerOn; - return; - } - } - - sRepeaterChange RC; - RC.Position = a_Position; - RC.Ticks = a_Ticks; - RC.bPowerOn = a_bPowerOn; - RC.bPowerOffNextTime = false; - m_SetRepeaters.push_back( RC ); - } - - virtual void AddBlock(int a_X, int a_Y, int a_Z) {} - - void HandleChange( const Vector3i & a_BlockPos ); - BlockList RemoveCurrent( const Vector3i & a_BlockPos ); - - bool PowerBlock( const Vector3i & a_BlockPos, const Vector3i & a_FromBlock, char a_Power ); - int UnPowerBlock( const Vector3i & a_BlockPos, const Vector3i & a_FromBlock ); - - bool IsPowered( const Vector3i & a_BlockPos, bool a_bOnlyByWire = false ); - bool IsPowering( const Vector3i & a_PowerPos, const Vector3i & a_BlockPos, eRedstoneDirection a_WireDirection, bool a_bOnlyByWire ); - - BlockList m_Blocks; - BlockList m_BlocksBuffer; - - BlockList m_RefreshPistons; - - BlockList m_RefreshTorchesAround; - - void RefreshTorchesAround( const Vector3i & a_BlockPos ); - - cCriticalSection m_CS; +#pragma once + +#include "cSimulator.h" +#include "Vector3i.h" + +class cRedstoneSimulator : public cSimulator +{ + typedef cSimulator super; +public: + cRedstoneSimulator( cWorld* a_World ); + ~cRedstoneSimulator(); + + virtual void Simulate( float a_Dt ); + virtual bool IsAllowedBlock( char a_BlockID ) { return true; } + + virtual void WakeUp( int a_X, int a_Y, int a_Z ); + + enum eRedstoneDirection + { + REDSTONE_NONE = 0, + REDSTONE_X_POS = 0x1, + REDSTONE_X_NEG = 0x2, + REDSTONE_Z_POS = 0x4, + REDSTONE_Z_NEG = 0x8, + }; + eRedstoneDirection GetDirection( int a_X, int a_Y, int a_Z ); + eRedstoneDirection GetDirection( const Vector3i & a_Pos ) { return GetDirection( a_Pos.x, a_Pos.y, a_Pos.z ); } +private: + struct sRepeaterChange + { + Vector3i Position; + int Ticks; + bool bPowerOn; + bool bPowerOffNextTime; + }; + + typedef std::deque BlockList; + + typedef std::deque< sRepeaterChange > RepeaterList; + RepeaterList m_SetRepeaters; + void SetRepeater( const Vector3i & a_Position, int a_Ticks, bool a_bPowerOn ) + { + for( RepeaterList::iterator itr = m_SetRepeaters.begin(); itr != m_SetRepeaters.end(); ++itr ) + { + sRepeaterChange & Change = *itr; + if( Change.Position.Equals( a_Position ) ) + { + if( Change.bPowerOn && a_bPowerOn == false ) + { + Change.bPowerOffNextTime = true; + } + if( a_bPowerOn == true ) + { + Change.bPowerOffNextTime = false; + } + Change.bPowerOn |= a_bPowerOn; + return; + } + } + + sRepeaterChange RC; + RC.Position = a_Position; + RC.Ticks = a_Ticks; + RC.bPowerOn = a_bPowerOn; + RC.bPowerOffNextTime = false; + m_SetRepeaters.push_back( RC ); + } + + virtual void AddBlock(int a_X, int a_Y, int a_Z) {} + + void HandleChange( const Vector3i & a_BlockPos ); + BlockList RemoveCurrent( const Vector3i & a_BlockPos ); + + bool PowerBlock( const Vector3i & a_BlockPos, const Vector3i & a_FromBlock, char a_Power ); + int UnPowerBlock( const Vector3i & a_BlockPos, const Vector3i & a_FromBlock ); + + bool IsPowered( const Vector3i & a_BlockPos, bool a_bOnlyByWire = false ); + bool IsPowering( const Vector3i & a_PowerPos, const Vector3i & a_BlockPos, eRedstoneDirection a_WireDirection, bool a_bOnlyByWire ); + + BlockList m_Blocks; + BlockList m_BlocksBuffer; + + BlockList m_RefreshPistons; + + BlockList m_RefreshTorchesAround; + + void RefreshTorchesAround( const Vector3i & a_BlockPos ); + + cCriticalSection m_CS; }; \ No newline at end of file diff --git a/source/cReferenceManager.cpp b/source/cReferenceManager.cpp index e639884c4..b39d71858 100644 --- a/source/cReferenceManager.cpp +++ b/source/cReferenceManager.cpp @@ -1,43 +1,43 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cReferenceManager.h" -#include "cEntity.h" - - - - - -cReferenceManager::cReferenceManager( ENUM_REFERENCE_MANAGER_TYPE a_Type ) - : m_Type( a_Type ) -{ -} - -cReferenceManager::~cReferenceManager() -{ - if( m_Type == RFMNGR_REFERENCERS ) - { - for( std::list< cEntity** >::iterator itr = m_References.begin(); itr != m_References.end(); ++itr ) - { - *(*itr) = 0; // Set referenced pointer to 0 - } - } - else - { - for( std::list< cEntity** >::iterator itr = m_References.begin(); itr != m_References.end(); ++itr ) - { - cEntity* Ptr = (*(*itr)); - if( Ptr ) Ptr->Dereference( *(*itr) ); - } - } -} - -void cReferenceManager::AddReference( cEntity*& a_EntityPtr ) -{ - m_References.push_back( &a_EntityPtr ); -} - -void cReferenceManager::Dereference( cEntity*& a_EntityPtr ) -{ - m_References.remove( &a_EntityPtr ); + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cReferenceManager.h" +#include "cEntity.h" + + + + + +cReferenceManager::cReferenceManager( ENUM_REFERENCE_MANAGER_TYPE a_Type ) + : m_Type( a_Type ) +{ +} + +cReferenceManager::~cReferenceManager() +{ + if( m_Type == RFMNGR_REFERENCERS ) + { + for( std::list< cEntity** >::iterator itr = m_References.begin(); itr != m_References.end(); ++itr ) + { + *(*itr) = 0; // Set referenced pointer to 0 + } + } + else + { + for( std::list< cEntity** >::iterator itr = m_References.begin(); itr != m_References.end(); ++itr ) + { + cEntity* Ptr = (*(*itr)); + if( Ptr ) Ptr->Dereference( *(*itr) ); + } + } +} + +void cReferenceManager::AddReference( cEntity*& a_EntityPtr ) +{ + m_References.push_back( &a_EntityPtr ); +} + +void cReferenceManager::Dereference( cEntity*& a_EntityPtr ) +{ + m_References.remove( &a_EntityPtr ); } \ No newline at end of file diff --git a/source/cReferenceManager.h b/source/cReferenceManager.h index 3142d5d5a..bcd451f72 100644 --- a/source/cReferenceManager.h +++ b/source/cReferenceManager.h @@ -1,34 +1,34 @@ - -#pragma once - - - - - -class cEntity; - - - - - -class cReferenceManager -{ -public: - enum ENUM_REFERENCE_MANAGER_TYPE - { - RFMNGR_REFERENCERS, - RFMNGR_REFERENCES, - }; - cReferenceManager( ENUM_REFERENCE_MANAGER_TYPE a_Type ); - ~cReferenceManager(); - - void AddReference( cEntity*& a_EntityPtr ); - void Dereference( cEntity*& a_EntityPtr ); -private: - ENUM_REFERENCE_MANAGER_TYPE m_Type; - std::list< cEntity** > m_References; -}; - - - - + +#pragma once + + + + + +class cEntity; + + + + + +class cReferenceManager +{ +public: + enum ENUM_REFERENCE_MANAGER_TYPE + { + RFMNGR_REFERENCERS, + RFMNGR_REFERENCES, + }; + cReferenceManager( ENUM_REFERENCE_MANAGER_TYPE a_Type ); + ~cReferenceManager(); + + void AddReference( cEntity*& a_EntityPtr ); + void Dereference( cEntity*& a_EntityPtr ); +private: + ENUM_REFERENCE_MANAGER_TYPE m_Type; + std::list< cEntity** > m_References; +}; + + + + diff --git a/source/cRoot.cpp b/source/cRoot.cpp index 59f0e47f4..9feff537d 100644 --- a/source/cRoot.cpp +++ b/source/cRoot.cpp @@ -1,394 +1,394 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cRoot.h" -#include "cServer.h" -#include "cWorld.h" -#include "cWebAdmin.h" -#include "cFurnaceRecipe.h" -#include "cGroupManager.h" -#include "CraftingRecipes.h" -#include "cPluginManager.h" -#include "cMonsterConfig.h" -#include "cSleep.h" -#include "cThread.h" -#include "cFileFormatUpdater.h" -#include "cRedstone.h" - -#include "../iniFile/iniFile.h" - -#include - - - - - -cRoot* cRoot::s_Root = 0; - -typedef std::map< AString, cWorld* > WorldMap; -struct cRoot::sRootState -{ - cWorld* pDefaultWorld; - WorldMap WorldsByName; -}; - - - - - -cRoot::cRoot() - : m_Server( 0 ) - , m_MonsterConfig( 0 ) - , m_GroupManager( 0 ) - , m_CraftingRecipes(NULL) - , m_FurnaceRecipe( 0 ) - , m_WebAdmin( 0 ) - , m_PluginManager( 0 ) - , m_Log( 0 ) - , m_bStop( false ) - , m_bRestart( false ) - , m_InputThread( 0 ) - , m_pState( new sRootState ) -{ - s_Root = this; -} - - - - - -cRoot::~cRoot() -{ - s_Root = 0; - delete m_pState; -} - - - - - -void cRoot::InputThread(void* a_Params) -{ - cRoot& self = *(cRoot*)a_Params; - - while( !(self.m_bStop || self.m_bRestart) ) - { - std::string Command; - std::getline(std::cin, Command); - self.ServerCommand( Command.c_str() ); - } -} - - - - - -void cRoot::Start() -{ - delete m_Log; - m_Log = new cMCLogger(); - - m_bStop = false; - while (!m_bStop) - { - m_bRestart = false; - - LoadGlobalSettings(); - - cFileFormatUpdater::UpdateFileFormat(); - - LOG("Creating new server instance..."); - m_Server = new cServer(); - - LOG("Starting server..."); - cIniFile IniFile("settings.ini"); - IniFile.ReadFile(); - int Port = IniFile.GetValueSetI("Server", "Port", 25565 ); - if(!m_Server->InitServer( Port )) - { - LOG("Failed to start server, shutting down."); - return; - } - IniFile.WriteFile(); - - cIniFile WebIniFile("webadmin.ini"); - if( WebIniFile.ReadFile() ) - { - if( WebIniFile.GetValueB("WebAdmin", "Enabled", false ) == true ) - { - LOG("Creating WebAdmin..."); - m_WebAdmin = new cWebAdmin(8080); - } - } - - LOG("Loading settings..."); - m_GroupManager = new cGroupManager(); - m_CraftingRecipes = new cCraftingRecipes; - m_FurnaceRecipe = new cFurnaceRecipe(); - - LOG("Loading worlds..."); - LoadWorlds(); - - LOG("Loading plugin manager..."); - m_PluginManager = new cPluginManager(); // This should be last - m_PluginManager->ReloadPluginsNow(); - - LOG("Loading MonsterConfig..."); - m_MonsterConfig = new cMonsterConfig; - - // This sets stuff in motion - LOG("Starting Authenticator..."); - m_Authenticator.Start(); - - LOG("Starting worlds..."); - StartWorlds(); - - LOG("Starting server..."); - m_Server->StartListenThread(); - //cHeartBeat* HeartBeat = new cHeartBeat(); - - LOG("Starting InputThread..."); - m_InputThread = new cThread( InputThread, this, "cRoot::InputThread" ); - m_InputThread->Start( true ); - - LOG("Initialization done, server running now."); - while( !m_bStop && !m_bRestart ) // These are modified by external threads - { - cSleep::MilliSleep( 1000 ); - } - - delete m_InputThread; m_InputThread = 0; - - // Deallocate stuffs - LOG("Shutting down server..."); - m_Server->Shutdown(); // This waits for threads to stop and d/c clients - LOG("Stopping authenticator..."); - m_Authenticator.Stop(); - LOG("Stopping plugin manager..."); - delete m_PluginManager; m_PluginManager = 0; // This should be first - LOG("Freeing MonsterConfig..."); - delete m_MonsterConfig; m_MonsterConfig = 0; - LOG("Stopping WebAdmin..."); - delete m_WebAdmin; m_WebAdmin = 0; - LOG("Unloading recipes..."); - delete m_FurnaceRecipe; m_FurnaceRecipe = NULL; - delete m_CraftingRecipes; m_CraftingRecipes = NULL; - LOG("Forgetting groups..."); - delete m_GroupManager; m_GroupManager = 0; - LOG("Unloading worlds..."); - UnloadWorlds(); - LOG("Destroying server..."); - //delete HeartBeat; HeartBeat = 0; - delete m_Server; m_Server = 0; - LOG("Shutdown done."); - } - - delete m_Log; m_Log = 0; -} - - - - - -void cRoot::LoadGlobalSettings() -{ - cIniFile IniFile("settings.ini"); - if( IniFile.ReadFile() ) - { - cRedstone::s_UseRedstone = IniFile.GetValueB("Redstone", "SimulateRedstone", true ); - } -} - - - - - -void cRoot::LoadWorlds(void) -{ - cIniFile IniFile("settings.ini"); IniFile.ReadFile(); - - // First get the default world - AString DefaultWorldName = IniFile.GetValueSet("Worlds", "DefaultWorld", "world"); - m_pState->pDefaultWorld = new cWorld( DefaultWorldName.c_str() ); - m_pState->WorldsByName[ DefaultWorldName ] = m_pState->pDefaultWorld; - - // Then load the other worlds - unsigned int KeyNum = IniFile.FindKey("Worlds"); - unsigned int NumWorlds = IniFile.GetNumValues( KeyNum ); - if (NumWorlds <= 0) - { - return; - } - - for (unsigned int i = 0; i < NumWorlds; i++) - { - AString ValueName = IniFile.GetValueName(KeyNum, i ); - if (ValueName.compare("World") != 0) - { - continue; - } - AString WorldName = IniFile.GetValue(KeyNum, i ); - if (WorldName.empty()) - { - continue; - } - cWorld* NewWorld = new cWorld( WorldName.c_str() ); - m_pState->WorldsByName[ WorldName ] = NewWorld; - } // for i - Worlds -} - - - - - -void cRoot::StartWorlds(void) -{ - for( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr ) - { - itr->second->InitializeSpawn(); - } -} - - - - - -void cRoot::UnloadWorlds(void) -{ - for( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr ) - { - delete itr->second; - } - m_pState->WorldsByName.clear(); -} - - - - - -cWorld* cRoot::GetDefaultWorld() -{ - return m_pState->pDefaultWorld; -} - - - - - -cWorld* cRoot::GetWorld( const AString & a_WorldName ) -{ - WorldMap::iterator itr = m_pState->WorldsByName.find( a_WorldName ); - if( itr != m_pState->WorldsByName.end() ) - return itr->second; - return 0; -} - - - - - -bool cRoot::ForEachWorld(cWorldListCallback & a_Callback) -{ - for( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr ) - { - if (a_Callback.Item(itr->second)) - { - return false; - } - } - return true; -} - - - - - -void cRoot::TickWorlds( float a_Dt ) -{ - for( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr ) - { - itr->second->Tick( a_Dt ); - } -} - - - - - -void cRoot::ServerCommand( const char * a_Cmd ) -{ - LOG("Server console command: \"%s\"", a_Cmd ); - m_Server->ServerCommand( a_Cmd ); - if( strcmp(a_Cmd, "stop") == 0 ) - { - m_bStop = true; - } - else if( strcmp( a_Cmd, "restart") == 0 ) - { - m_bRestart = true; - } -} - - - - - -void cRoot::KickUser(int a_ClientID, const AString & a_Reason) -{ - m_Server->KickUser(a_ClientID, a_Reason); -} - - - - - -void cRoot::AuthenticateUser(int a_ClientID) -{ - m_Server->AuthenticateUser(a_ClientID); -} - - - - - -int cRoot::GetTotalChunkCount(void) -{ - int res = 0; - for ( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr ) - { - res += itr->second->GetNumChunks(); - } - return res; -} - - - - - -void cRoot::SaveAllChunks(void) -{ - for (WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr) - { - itr->second->SaveAllChunks(); - } -} - - - - - -bool cRoot::ForEachPlayer(cPlayerListCallback & a_Callback) -{ - for (WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr) - { - if (!itr->second->ForEachPlayer(a_Callback)) - { - return false; - } - } - return true; -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cRoot.h" +#include "cServer.h" +#include "cWorld.h" +#include "cWebAdmin.h" +#include "cFurnaceRecipe.h" +#include "cGroupManager.h" +#include "CraftingRecipes.h" +#include "cPluginManager.h" +#include "cMonsterConfig.h" +#include "cSleep.h" +#include "cThread.h" +#include "cFileFormatUpdater.h" +#include "cRedstone.h" + +#include "../iniFile/iniFile.h" + +#include + + + + + +cRoot* cRoot::s_Root = 0; + +typedef std::map< AString, cWorld* > WorldMap; +struct cRoot::sRootState +{ + cWorld* pDefaultWorld; + WorldMap WorldsByName; +}; + + + + + +cRoot::cRoot() + : m_Server( 0 ) + , m_MonsterConfig( 0 ) + , m_GroupManager( 0 ) + , m_CraftingRecipes(NULL) + , m_FurnaceRecipe( 0 ) + , m_WebAdmin( 0 ) + , m_PluginManager( 0 ) + , m_Log( 0 ) + , m_bStop( false ) + , m_bRestart( false ) + , m_InputThread( 0 ) + , m_pState( new sRootState ) +{ + s_Root = this; +} + + + + + +cRoot::~cRoot() +{ + s_Root = 0; + delete m_pState; +} + + + + + +void cRoot::InputThread(void* a_Params) +{ + cRoot& self = *(cRoot*)a_Params; + + while( !(self.m_bStop || self.m_bRestart) ) + { + std::string Command; + std::getline(std::cin, Command); + self.ServerCommand( Command.c_str() ); + } +} + + + + + +void cRoot::Start() +{ + delete m_Log; + m_Log = new cMCLogger(); + + m_bStop = false; + while (!m_bStop) + { + m_bRestart = false; + + LoadGlobalSettings(); + + cFileFormatUpdater::UpdateFileFormat(); + + LOG("Creating new server instance..."); + m_Server = new cServer(); + + LOG("Starting server..."); + cIniFile IniFile("settings.ini"); + IniFile.ReadFile(); + int Port = IniFile.GetValueSetI("Server", "Port", 25565 ); + if(!m_Server->InitServer( Port )) + { + LOG("Failed to start server, shutting down."); + return; + } + IniFile.WriteFile(); + + cIniFile WebIniFile("webadmin.ini"); + if( WebIniFile.ReadFile() ) + { + if( WebIniFile.GetValueB("WebAdmin", "Enabled", false ) == true ) + { + LOG("Creating WebAdmin..."); + m_WebAdmin = new cWebAdmin(8080); + } + } + + LOG("Loading settings..."); + m_GroupManager = new cGroupManager(); + m_CraftingRecipes = new cCraftingRecipes; + m_FurnaceRecipe = new cFurnaceRecipe(); + + LOG("Loading worlds..."); + LoadWorlds(); + + LOG("Loading plugin manager..."); + m_PluginManager = new cPluginManager(); // This should be last + m_PluginManager->ReloadPluginsNow(); + + LOG("Loading MonsterConfig..."); + m_MonsterConfig = new cMonsterConfig; + + // This sets stuff in motion + LOG("Starting Authenticator..."); + m_Authenticator.Start(); + + LOG("Starting worlds..."); + StartWorlds(); + + LOG("Starting server..."); + m_Server->StartListenThread(); + //cHeartBeat* HeartBeat = new cHeartBeat(); + + LOG("Starting InputThread..."); + m_InputThread = new cThread( InputThread, this, "cRoot::InputThread" ); + m_InputThread->Start( true ); + + LOG("Initialization done, server running now."); + while( !m_bStop && !m_bRestart ) // These are modified by external threads + { + cSleep::MilliSleep( 1000 ); + } + + delete m_InputThread; m_InputThread = 0; + + // Deallocate stuffs + LOG("Shutting down server..."); + m_Server->Shutdown(); // This waits for threads to stop and d/c clients + LOG("Stopping authenticator..."); + m_Authenticator.Stop(); + LOG("Stopping plugin manager..."); + delete m_PluginManager; m_PluginManager = 0; // This should be first + LOG("Freeing MonsterConfig..."); + delete m_MonsterConfig; m_MonsterConfig = 0; + LOG("Stopping WebAdmin..."); + delete m_WebAdmin; m_WebAdmin = 0; + LOG("Unloading recipes..."); + delete m_FurnaceRecipe; m_FurnaceRecipe = NULL; + delete m_CraftingRecipes; m_CraftingRecipes = NULL; + LOG("Forgetting groups..."); + delete m_GroupManager; m_GroupManager = 0; + LOG("Unloading worlds..."); + UnloadWorlds(); + LOG("Destroying server..."); + //delete HeartBeat; HeartBeat = 0; + delete m_Server; m_Server = 0; + LOG("Shutdown done."); + } + + delete m_Log; m_Log = 0; +} + + + + + +void cRoot::LoadGlobalSettings() +{ + cIniFile IniFile("settings.ini"); + if( IniFile.ReadFile() ) + { + cRedstone::s_UseRedstone = IniFile.GetValueB("Redstone", "SimulateRedstone", true ); + } +} + + + + + +void cRoot::LoadWorlds(void) +{ + cIniFile IniFile("settings.ini"); IniFile.ReadFile(); + + // First get the default world + AString DefaultWorldName = IniFile.GetValueSet("Worlds", "DefaultWorld", "world"); + m_pState->pDefaultWorld = new cWorld( DefaultWorldName.c_str() ); + m_pState->WorldsByName[ DefaultWorldName ] = m_pState->pDefaultWorld; + + // Then load the other worlds + unsigned int KeyNum = IniFile.FindKey("Worlds"); + unsigned int NumWorlds = IniFile.GetNumValues( KeyNum ); + if (NumWorlds <= 0) + { + return; + } + + for (unsigned int i = 0; i < NumWorlds; i++) + { + AString ValueName = IniFile.GetValueName(KeyNum, i ); + if (ValueName.compare("World") != 0) + { + continue; + } + AString WorldName = IniFile.GetValue(KeyNum, i ); + if (WorldName.empty()) + { + continue; + } + cWorld* NewWorld = new cWorld( WorldName.c_str() ); + m_pState->WorldsByName[ WorldName ] = NewWorld; + } // for i - Worlds +} + + + + + +void cRoot::StartWorlds(void) +{ + for( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr ) + { + itr->second->InitializeSpawn(); + } +} + + + + + +void cRoot::UnloadWorlds(void) +{ + for( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr ) + { + delete itr->second; + } + m_pState->WorldsByName.clear(); +} + + + + + +cWorld* cRoot::GetDefaultWorld() +{ + return m_pState->pDefaultWorld; +} + + + + + +cWorld* cRoot::GetWorld( const AString & a_WorldName ) +{ + WorldMap::iterator itr = m_pState->WorldsByName.find( a_WorldName ); + if( itr != m_pState->WorldsByName.end() ) + return itr->second; + return 0; +} + + + + + +bool cRoot::ForEachWorld(cWorldListCallback & a_Callback) +{ + for( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr ) + { + if (a_Callback.Item(itr->second)) + { + return false; + } + } + return true; +} + + + + + +void cRoot::TickWorlds( float a_Dt ) +{ + for( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr ) + { + itr->second->Tick( a_Dt ); + } +} + + + + + +void cRoot::ServerCommand( const char * a_Cmd ) +{ + LOG("Server console command: \"%s\"", a_Cmd ); + m_Server->ServerCommand( a_Cmd ); + if( strcmp(a_Cmd, "stop") == 0 ) + { + m_bStop = true; + } + else if( strcmp( a_Cmd, "restart") == 0 ) + { + m_bRestart = true; + } +} + + + + + +void cRoot::KickUser(int a_ClientID, const AString & a_Reason) +{ + m_Server->KickUser(a_ClientID, a_Reason); +} + + + + + +void cRoot::AuthenticateUser(int a_ClientID) +{ + m_Server->AuthenticateUser(a_ClientID); +} + + + + + +int cRoot::GetTotalChunkCount(void) +{ + int res = 0; + for ( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr ) + { + res += itr->second->GetNumChunks(); + } + return res; +} + + + + + +void cRoot::SaveAllChunks(void) +{ + for (WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr) + { + itr->second->SaveAllChunks(); + } +} + + + + + +bool cRoot::ForEachPlayer(cPlayerListCallback & a_Callback) +{ + for (WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr) + { + if (!itr->second->ForEachPlayer(a_Callback)) + { + return false; + } + } + return true; +} + + + + diff --git a/source/cRoot.h b/source/cRoot.h index 7b0a7ea18..21bd39f7d 100644 --- a/source/cRoot.h +++ b/source/cRoot.h @@ -1,109 +1,109 @@ - -#pragma once - - - - -#include "cAuthenticator.h" - - - - - -class cThread; -class cMonsterConfig; -class cGroupManager; -class cCraftingRecipes; -class cFurnaceRecipe; -class cWebAdmin; -class cPluginManager; -class cServer; -class cWorld; -class cPlayer; -typedef cItemCallback cPlayerListCallback; -typedef cItemCallback cWorldListCallback; - - - - - -class cRoot //tolua_export -{ //tolua_export -public: - static cRoot* Get() { return s_Root; } //tolua_export - - cRoot(void); - ~cRoot(); - - void Start(void); - - cServer * GetServer(void) { return m_Server; } //tolua_export - cWorld * GetDefaultWorld(void); //tolua_export - cWorld * GetWorld(const AString & a_WorldName); //tolua_export - - /// Calls the callback for each world; returns true if the callback didn't abort (return true) - bool ForEachWorld(cWorldListCallback & a_Callback); // >> Exported in ManualBindings << - - cMonsterConfig * GetMonsterConfig() { return m_MonsterConfig; } - - cGroupManager * GetGroupManager (void) { return m_GroupManager; } // tolua_export - cCraftingRecipes * GetCraftingRecipes(void) { return m_CraftingRecipes; } // tolua_export - cFurnaceRecipe * GetFurnaceRecipe (void) { return m_FurnaceRecipe; } // tolua_export - cWebAdmin * GetWebAdmin (void) { return m_WebAdmin; } // tolua_export - cPluginManager * GetPluginManager (void) { return m_PluginManager; } // tolua_export - cAuthenticator & GetAuthenticator (void) { return m_Authenticator; } - - void ServerCommand(const char* a_Cmd ); //tolua_export - - void KickUser(int a_ClientID, const AString & a_Reason); // Kicks the user, no matter in what world they are. Used from cAuthenticator - void AuthenticateUser(int a_ClientID); // Called by cAuthenticator to auth the specified user - - void TickWorlds( float a_Dt ); - - /// Returns the number of chunks loaded - int GetTotalChunkCount(void); // tolua_export - - /// Saves all chunks in all worlds - void SaveAllChunks(void); - - /// Calls the callback for each player in all worlds - bool ForEachPlayer(cPlayerListCallback & a_Callback); - -private: - void LoadGlobalSettings(); - - /// Loads the worlds from settings.ini, creates the worldmap - void LoadWorlds(void); - - /// Starts each world's life - void StartWorlds(void); - - void UnloadWorlds(void); - - cServer * m_Server; - cMonsterConfig * m_MonsterConfig; - - cGroupManager * m_GroupManager; - cCraftingRecipes * m_CraftingRecipes; - cFurnaceRecipe * m_FurnaceRecipe; - cWebAdmin * m_WebAdmin; - cPluginManager * m_PluginManager; - cAuthenticator m_Authenticator; - - cMCLogger * m_Log; - - bool m_bStop; - bool m_bRestart; - - struct sRootState; - sRootState* m_pState; - - cThread* m_InputThread; - static void InputThread(void* a_Params); - - static cRoot* s_Root; -}; //tolua_export - - - - + +#pragma once + + + + +#include "cAuthenticator.h" + + + + + +class cThread; +class cMonsterConfig; +class cGroupManager; +class cCraftingRecipes; +class cFurnaceRecipe; +class cWebAdmin; +class cPluginManager; +class cServer; +class cWorld; +class cPlayer; +typedef cItemCallback cPlayerListCallback; +typedef cItemCallback cWorldListCallback; + + + + + +class cRoot //tolua_export +{ //tolua_export +public: + static cRoot* Get() { return s_Root; } //tolua_export + + cRoot(void); + ~cRoot(); + + void Start(void); + + cServer * GetServer(void) { return m_Server; } //tolua_export + cWorld * GetDefaultWorld(void); //tolua_export + cWorld * GetWorld(const AString & a_WorldName); //tolua_export + + /// Calls the callback for each world; returns true if the callback didn't abort (return true) + bool ForEachWorld(cWorldListCallback & a_Callback); // >> Exported in ManualBindings << + + cMonsterConfig * GetMonsterConfig() { return m_MonsterConfig; } + + cGroupManager * GetGroupManager (void) { return m_GroupManager; } // tolua_export + cCraftingRecipes * GetCraftingRecipes(void) { return m_CraftingRecipes; } // tolua_export + cFurnaceRecipe * GetFurnaceRecipe (void) { return m_FurnaceRecipe; } // tolua_export + cWebAdmin * GetWebAdmin (void) { return m_WebAdmin; } // tolua_export + cPluginManager * GetPluginManager (void) { return m_PluginManager; } // tolua_export + cAuthenticator & GetAuthenticator (void) { return m_Authenticator; } + + void ServerCommand(const char* a_Cmd ); //tolua_export + + void KickUser(int a_ClientID, const AString & a_Reason); // Kicks the user, no matter in what world they are. Used from cAuthenticator + void AuthenticateUser(int a_ClientID); // Called by cAuthenticator to auth the specified user + + void TickWorlds( float a_Dt ); + + /// Returns the number of chunks loaded + int GetTotalChunkCount(void); // tolua_export + + /// Saves all chunks in all worlds + void SaveAllChunks(void); + + /// Calls the callback for each player in all worlds + bool ForEachPlayer(cPlayerListCallback & a_Callback); + +private: + void LoadGlobalSettings(); + + /// Loads the worlds from settings.ini, creates the worldmap + void LoadWorlds(void); + + /// Starts each world's life + void StartWorlds(void); + + void UnloadWorlds(void); + + cServer * m_Server; + cMonsterConfig * m_MonsterConfig; + + cGroupManager * m_GroupManager; + cCraftingRecipes * m_CraftingRecipes; + cFurnaceRecipe * m_FurnaceRecipe; + cWebAdmin * m_WebAdmin; + cPluginManager * m_PluginManager; + cAuthenticator m_Authenticator; + + cMCLogger * m_Log; + + bool m_bStop; + bool m_bRestart; + + struct sRootState; + sRootState* m_pState; + + cThread* m_InputThread; + static void InputThread(void* a_Params); + + static cRoot* s_Root; +}; //tolua_export + + + + diff --git a/source/cSandSimulator.cpp b/source/cSandSimulator.cpp index 3fe678f90..6e5c5ecde 100644 --- a/source/cSandSimulator.cpp +++ b/source/cSandSimulator.cpp @@ -1,91 +1,91 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cSandSimulator.h" -#include "cWorld.h" -#include "Vector3i.h" -#include "BlockID.h" -#include "Defines.h" - - - - - -cSandSimulator::cSandSimulator( cWorld* a_World ) - : cSimulator(a_World) - , m_Blocks(new BlockList) - , m_Buffer(new BlockList) -{ - -} - -cSandSimulator::~cSandSimulator() -{ - delete m_Buffer; - delete m_Blocks; -} - -void cSandSimulator::Simulate( float a_Dt ) -{ - m_Buffer->clear(); - std::swap( m_Blocks, m_Buffer ); - - for( BlockList::iterator itr = m_Buffer->begin(); itr != m_Buffer->end(); ++itr ) - { - Vector3i Pos = *itr; - char BlockID = m_World->GetBlock(Pos.x, Pos.y, Pos.z); - if(!IsAllowedBlock(BlockID)) - continue; - - char BottomBlock = m_World->GetBlock( Pos.x, Pos.y - 1, Pos.z ); - - if( IsPassable(BottomBlock) ) - { - m_World->SetBlock( Pos.x, Pos.y, Pos.z, E_BLOCK_AIR, 0 ); - m_World->SetBlock( Pos.x, Pos.y - 1, Pos.z, BlockID, 0 ); - } - } - -} - - -bool cSandSimulator::IsAllowedBlock( char a_BlockID ) -{ - return a_BlockID == E_BLOCK_SAND - || a_BlockID == E_BLOCK_GRAVEL; -} - -void cSandSimulator::AddBlock(int a_X, int a_Y, int a_Z) -{ - if(!IsAllowedBlock(m_World->GetBlock(a_X, a_Y, a_Z))) //This should save very much time because it doesn´t have to iterate through all blocks - return; - - Vector3i Block(a_X, a_Y, a_Z); - - //check for duplicates - for( BlockList::iterator itr = m_Blocks->begin(); itr != m_Blocks->end(); ++itr ) - { - Vector3i Pos = *itr; - if( Pos.x == a_X && Pos.y == a_Y && Pos.z == a_Z ) - return; - } - - m_Blocks->push_back(Block); - -} - -bool cSandSimulator::IsPassable( char a_BlockID ) -{ - return a_BlockID == E_BLOCK_AIR - || IsBlockWater(a_BlockID) - || IsBlockLava(a_BlockID) - || a_BlockID == E_BLOCK_FIRE; - -} - -void cSandSimulator::WakeUp( int a_X, int a_Y, int a_Z ) -{ - //Nothing else needs to be simulated :D (Bugs not included :s) - AddBlock( a_X, a_Y+1, a_Z ); - AddBlock( a_X, a_Y, a_Z ); -} + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSandSimulator.h" +#include "cWorld.h" +#include "Vector3i.h" +#include "BlockID.h" +#include "Defines.h" + + + + + +cSandSimulator::cSandSimulator( cWorld* a_World ) + : cSimulator(a_World) + , m_Blocks(new BlockList) + , m_Buffer(new BlockList) +{ + +} + +cSandSimulator::~cSandSimulator() +{ + delete m_Buffer; + delete m_Blocks; +} + +void cSandSimulator::Simulate( float a_Dt ) +{ + m_Buffer->clear(); + std::swap( m_Blocks, m_Buffer ); + + for( BlockList::iterator itr = m_Buffer->begin(); itr != m_Buffer->end(); ++itr ) + { + Vector3i Pos = *itr; + char BlockID = m_World->GetBlock(Pos.x, Pos.y, Pos.z); + if(!IsAllowedBlock(BlockID)) + continue; + + char BottomBlock = m_World->GetBlock( Pos.x, Pos.y - 1, Pos.z ); + + if( IsPassable(BottomBlock) ) + { + m_World->SetBlock( Pos.x, Pos.y, Pos.z, E_BLOCK_AIR, 0 ); + m_World->SetBlock( Pos.x, Pos.y - 1, Pos.z, BlockID, 0 ); + } + } + +} + + +bool cSandSimulator::IsAllowedBlock( char a_BlockID ) +{ + return a_BlockID == E_BLOCK_SAND + || a_BlockID == E_BLOCK_GRAVEL; +} + +void cSandSimulator::AddBlock(int a_X, int a_Y, int a_Z) +{ + if(!IsAllowedBlock(m_World->GetBlock(a_X, a_Y, a_Z))) //This should save very much time because it doesn´t have to iterate through all blocks + return; + + Vector3i Block(a_X, a_Y, a_Z); + + //check for duplicates + for( BlockList::iterator itr = m_Blocks->begin(); itr != m_Blocks->end(); ++itr ) + { + Vector3i Pos = *itr; + if( Pos.x == a_X && Pos.y == a_Y && Pos.z == a_Z ) + return; + } + + m_Blocks->push_back(Block); + +} + +bool cSandSimulator::IsPassable( char a_BlockID ) +{ + return a_BlockID == E_BLOCK_AIR + || IsBlockWater(a_BlockID) + || IsBlockLava(a_BlockID) + || a_BlockID == E_BLOCK_FIRE; + +} + +void cSandSimulator::WakeUp( int a_X, int a_Y, int a_Z ) +{ + //Nothing else needs to be simulated :D (Bugs not included :s) + AddBlock( a_X, a_Y+1, a_Z ); + AddBlock( a_X, a_Y, a_Z ); +} diff --git a/source/cSandSimulator.h b/source/cSandSimulator.h index c99092726..c95d5e476 100644 --- a/source/cSandSimulator.h +++ b/source/cSandSimulator.h @@ -1,40 +1,40 @@ - -#pragma once - -#include "cSimulator.h" -#include "cBlockEntity.h" -#include "Vector3i.h" - - - - - -class cWorld; - - - - - -class cSandSimulator : public cSimulator -{ -public: - cSandSimulator( cWorld* a_World ); - ~cSandSimulator(); - - virtual void Simulate( float a_Dt ); - virtual void WakeUp( int a_X, int a_Y, int a_Z ); - - virtual bool IsAllowedBlock( char a_BlockID ); - virtual bool IsPassable( char a_BlockID ); - -protected: - virtual void AddBlock(int a_X, int a_Y, int a_Z); - - typedef std::list BlockList; - BlockList * m_Blocks; - BlockList * m_Buffer; -}; - - - - + +#pragma once + +#include "cSimulator.h" +#include "cBlockEntity.h" +#include "Vector3i.h" + + + + + +class cWorld; + + + + + +class cSandSimulator : public cSimulator +{ +public: + cSandSimulator( cWorld* a_World ); + ~cSandSimulator(); + + virtual void Simulate( float a_Dt ); + virtual void WakeUp( int a_X, int a_Y, int a_Z ); + + virtual bool IsAllowedBlock( char a_BlockID ); + virtual bool IsPassable( char a_BlockID ); + +protected: + virtual void AddBlock(int a_X, int a_Y, int a_Z); + + typedef std::list BlockList; + BlockList * m_Blocks; + BlockList * m_Buffer; +}; + + + + diff --git a/source/cSemaphore.cpp b/source/cSemaphore.cpp index 6fe8f6d5b..468de6858 100644 --- a/source/cSemaphore.cpp +++ b/source/cSemaphore.cpp @@ -1,91 +1,91 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - - - - - -cSemaphore::cSemaphore( unsigned int a_MaxCount, unsigned int a_InitialCount /* = 0 */ ) -#ifndef _WIN32 - : m_bNamed( false ) -#endif -{ -#ifndef _WIN32 - (void)a_MaxCount; - m_Handle = new sem_t; - if (sem_init( (sem_t*)m_Handle, 0, 0)) - { - LOG("WARNING cSemaphore: Could not create unnamed semaphore, fallback to named."); - delete (sem_t*)m_Handle; // named semaphores return their own address - m_bNamed = true; - - AString Name; - Printf(Name, "cSemaphore%p", this ); - m_Handle = sem_open(Name.c_str(), O_CREAT, 777, a_InitialCount); - if( m_Handle == SEM_FAILED ) - { - LOG("ERROR: Could not create Semaphore. (%i)", errno ); - } - else - { - if( sem_unlink(Name.c_str()) != 0 ) - { - LOG("ERROR: Could not unlink cSemaphore. (%i)", errno); - } - } - } -#else - m_Handle = CreateSemaphore( - NULL, // security attribute - a_InitialCount, // initial count - a_MaxCount, // maximum count - 0 // name (optional) - ); -#endif -} - -cSemaphore::~cSemaphore() -{ -#ifdef _WIN32 - CloseHandle( m_Handle ); -#else - if( m_bNamed ) - { - if( sem_close( (sem_t*)m_Handle ) != 0 ) - { - LOG("ERROR: Could not close cSemaphore. (%i)", errno); - } - } - else - { - sem_destroy( (sem_t*)m_Handle ); - delete (sem_t*)m_Handle; - } - m_Handle = 0; - -#endif -} - -void cSemaphore::Wait() -{ -#ifndef _WIN32 - if( sem_wait( (sem_t*)m_Handle ) != 0) - { - LOG("ERROR: Could not wait for cSemaphore. (%i)", errno); - } -#else - WaitForSingleObject( m_Handle, INFINITE); -#endif -} - -void cSemaphore::Signal() -{ -#ifndef _WIN32 - if( sem_post( (sem_t*)m_Handle ) != 0 ) - { - LOG("ERROR: Could not signal cSemaphore. (%i)", errno); - } -#else - ReleaseSemaphore( m_Handle, 1, NULL ); -#endif -} + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + + + + + +cSemaphore::cSemaphore( unsigned int a_MaxCount, unsigned int a_InitialCount /* = 0 */ ) +#ifndef _WIN32 + : m_bNamed( false ) +#endif +{ +#ifndef _WIN32 + (void)a_MaxCount; + m_Handle = new sem_t; + if (sem_init( (sem_t*)m_Handle, 0, 0)) + { + LOG("WARNING cSemaphore: Could not create unnamed semaphore, fallback to named."); + delete (sem_t*)m_Handle; // named semaphores return their own address + m_bNamed = true; + + AString Name; + Printf(Name, "cSemaphore%p", this ); + m_Handle = sem_open(Name.c_str(), O_CREAT, 777, a_InitialCount); + if( m_Handle == SEM_FAILED ) + { + LOG("ERROR: Could not create Semaphore. (%i)", errno ); + } + else + { + if( sem_unlink(Name.c_str()) != 0 ) + { + LOG("ERROR: Could not unlink cSemaphore. (%i)", errno); + } + } + } +#else + m_Handle = CreateSemaphore( + NULL, // security attribute + a_InitialCount, // initial count + a_MaxCount, // maximum count + 0 // name (optional) + ); +#endif +} + +cSemaphore::~cSemaphore() +{ +#ifdef _WIN32 + CloseHandle( m_Handle ); +#else + if( m_bNamed ) + { + if( sem_close( (sem_t*)m_Handle ) != 0 ) + { + LOG("ERROR: Could not close cSemaphore. (%i)", errno); + } + } + else + { + sem_destroy( (sem_t*)m_Handle ); + delete (sem_t*)m_Handle; + } + m_Handle = 0; + +#endif +} + +void cSemaphore::Wait() +{ +#ifndef _WIN32 + if( sem_wait( (sem_t*)m_Handle ) != 0) + { + LOG("ERROR: Could not wait for cSemaphore. (%i)", errno); + } +#else + WaitForSingleObject( m_Handle, INFINITE); +#endif +} + +void cSemaphore::Signal() +{ +#ifndef _WIN32 + if( sem_post( (sem_t*)m_Handle ) != 0 ) + { + LOG("ERROR: Could not signal cSemaphore. (%i)", errno); + } +#else + ReleaseSemaphore( m_Handle, 1, NULL ); +#endif +} diff --git a/source/cSemaphore.h b/source/cSemaphore.h index 42966b410..fbe8907f1 100644 --- a/source/cSemaphore.h +++ b/source/cSemaphore.h @@ -1,17 +1,17 @@ -#pragma once - -class cSemaphore -{ -public: - cSemaphore( unsigned int a_MaxCount, unsigned int a_InitialCount = 0 ); - ~cSemaphore(); - - void Wait(); - void Signal(); -private: - void* m_Handle; // HANDLE pointer - -#ifndef _WIN32 - bool m_bNamed; -#endif -}; +#pragma once + +class cSemaphore +{ +public: + cSemaphore( unsigned int a_MaxCount, unsigned int a_InitialCount = 0 ); + ~cSemaphore(); + + void Wait(); + void Signal(); +private: + void* m_Handle; // HANDLE pointer + +#ifndef _WIN32 + bool m_bNamed; +#endif +}; diff --git a/source/cServer.cpp b/source/cServer.cpp index c0b38c88b..65691e0cf 100644 --- a/source/cServer.cpp +++ b/source/cServer.cpp @@ -1,738 +1,738 @@ - -// ReDucTor is an awesome guy who helped me a lot - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cServer.h" -#include "cClientHandle.h" -#include "cSleep.h" -#include "cTimer.h" -#include "cMonster.h" -#include "cSocket.h" -#include "cRoot.h" -#include "cWorld.h" -#include "ChunkDef.h" -#include "cPluginManager.h" -#include "cGroupManager.h" -#include "cChatColor.h" -#include "cPlayer.h" -#include "cInventory.h" -#include "cItem.h" -#include "cFurnaceRecipe.h" -#include "cTracer.h" -#include "cWebAdmin.h" -#include "cChunk.h" - -#include "MersenneTwister.h" - -#include "../iniFile/iniFile.h" -#include "Vector3f.h" - -#include "packets/cPacket_Chat.h" - -#include -#include -#include - - - - - -extern "C" { - #include "zlib.h" -} - - - -bool g_bWaterPhysics = false; - -typedef std::list< cClientHandle* > ClientList; - - - - - -struct cServer::sServerState -{ - sServerState() - : pListenThread( 0 ) - , pTickThread( 0 ) - , bStopListenThread( false ) - , bStopTickThread( false ) - {} - cSocket SListenClient; // socket listening for client calls - - cThread* pListenThread; bool bStopListenThread; - cThread* pTickThread; bool bStopTickThread; - - cEvent RestartEvent; - std::string ServerID; -}; - - - - - -cServer * cServer::GetServer() -{ - LOGWARN("WARNING: Using deprecated function cServer::GetServer() use cRoot::Get()->GetServer() instead!"); - return cRoot::Get()->GetServer(); -} - - - - - -void cServer::ServerListenThread( void *a_Args ) -{ - LOG("ServerListenThread"); - cServer* self = (cServer*)a_Args; - sServerState* m_pState = self->m_pState; - while( !m_pState->bStopListenThread ) - { - self->StartListenClient(); - } -} - - - - - -void cServer::ClientDestroying(const cClientHandle * a_Client) -{ - m_SocketThreads.StopReading(a_Client); -} - - - - - -void cServer::NotifyClientWrite(const cClientHandle * a_Client) -{ - m_NotifyWriteThread.NotifyClientWrite(a_Client); -} - - - - - -void cServer::WriteToClient(const cSocket * a_Socket, const AString & a_Data) -{ - m_SocketThreads.Write(a_Socket, a_Data); -} - - - - - -void cServer::QueueClientClose(const cSocket * a_Socket) -{ - m_SocketThreads.QueueClose(a_Socket); -} - - - - - -void cServer::RemoveClient(const cSocket * a_Socket) -{ - m_SocketThreads.RemoveClient(a_Socket); -} - - - - - -bool cServer::InitServer( int a_Port ) -{ - if( m_bIsConnected ) - { - LOGERROR("ERROR: Trying to initialize server while server is already running!"); - return false; - } - - printf("/============================\\\n"); - printf("| Custom Minecraft Server |\n"); - printf("| Created by Kevin Bansberg |\n"); - printf("| A.K.A. FakeTruth |\n"); - printf("| Monsters by Alex Sonek |\n"); - printf("| A.K.A. Duralex |\n"); - printf("| Stuff by Mattes D |\n"); - printf("| A.K.A. _Xoft(o) |\n"); - printf("\\============================/\n"); - printf("More info: WWW.MC-SERVER.ORG\n"); - printf(" WWW.AE-C.NET\n"); - printf(" WWW.RBTHINKTANK.COM\n"); - printf("email: faketruth@gmail.com\n\n"); - - LOG("Starting up server."); - LOGINFO("Compatible clients: %s, protocol version %d", MCS_CLIENT_VERSION, MCS_PROTOCOL_VERSION); - - if( cSocket::WSAStartup() != 0 ) // Only does anything on Windows, but whatever - { - LOGERROR("WSAStartup() != 0"); - return false; - } - - m_pState->SListenClient = cSocket::CreateSocket(); - - if( !m_pState->SListenClient.IsValid() ) - { - LOGERROR("m_SListenClient==INVALID_SOCKET (%s)", cSocket::GetErrorString( cSocket::GetLastError() ).c_str() ); - return false; - } - - if( m_pState->SListenClient.SetReuseAddress() == -1 ) - { - LOGERROR("setsockopt == -1"); - return false; - } - - cSocket::SockAddr_In local; - local.Family = cSocket::ADDRESS_FAMILY_INTERNET; - local.Address = cSocket::INTERNET_ADDRESS_ANY; - local.Port = (unsigned short)a_Port; // 25565 - - if( m_pState->SListenClient.Bind( local ) != 0 ) - { - LOGERROR("bind fail (%s)", cSocket::GetErrorString( cSocket::GetLastError() ).c_str() ); - return false; - } - - if( m_pState->SListenClient.Listen( 10 ) != 0) - { - LOGERROR("listen fail (%s)", cSocket::GetErrorString( cSocket::GetLastError() ).c_str() ); - return false; - } - - m_iServerPort = a_Port; - LOG("Port %i has been bound, server is open for connections", m_iServerPort); - m_bIsConnected = true; - - cIniFile IniFile("settings.ini"); - if (IniFile.ReadFile()) - { - g_bWaterPhysics = IniFile.GetValueB("Physics", "Water", false ); - - m_pState->ServerID = "-"; - if (IniFile.GetValueB("Authentication", "Authenticate")) - { - MTRand mtrand1; - unsigned int r1 = (mtrand1.randInt()%1147483647) + 1000000000; - unsigned int r2 = (mtrand1.randInt()%1147483647) + 1000000000; - std::ostringstream sid; - sid << std::hex << r1; - sid << std::hex << r2; - std::string ServerID = sid.str(); - ServerID.resize(16, '0'); - m_pState->ServerID = ServerID; - } - - m_ClientViewDistance = IniFile.GetValueSetI("Server", "DefaultViewDistance", cClientHandle::DEFAULT_VIEW_DISTANCE); - if (m_ClientViewDistance < cClientHandle::MIN_VIEW_DISTANCE) - { - m_ClientViewDistance = cClientHandle::MIN_VIEW_DISTANCE; - LOGINFO("Setting default viewdistance to the minimum of %d", m_ClientViewDistance); - } - if (m_ClientViewDistance > cClientHandle::MAX_VIEW_DISTANCE) - { - m_ClientViewDistance = cClientHandle::MAX_VIEW_DISTANCE; - LOGINFO("Setting default viewdistance to the maximum of %d", m_ClientViewDistance); - } - IniFile.WriteFile(); - } - - m_NotifyWriteThread.Start(this); - - return true; -} - - - - - -cServer::cServer() - : m_pState( new sServerState ) - , m_Millisecondsf( 0 ) - , m_Milliseconds( 0 ) - , m_bIsConnected( false ) - , m_iServerPort( 0 ) - , m_bRestarting( false ) -{ -} - - - - - -cServer::~cServer() -{ - // TODO: Shut down the server gracefully - if ( m_pState->SListenClient ) - { - m_pState->SListenClient.CloseSocket(); - } - m_pState->SListenClient = 0; - - m_pState->bStopListenThread = true; - delete m_pState->pListenThread; m_pState->pListenThread = NULL; - m_pState->bStopTickThread = true; - delete m_pState->pTickThread; m_pState->pTickThread = NULL; - - delete m_pState; -} - - - - - -// TODO - Need to modify this or something, so it broadcasts to all worlds? And move this to cWorld? -void cServer::Broadcast( const cPacket & a_Packet, cClientHandle* a_Exclude /* = 0 */ ) -{ - cCSLock Lock(m_CSClients); - for( ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr) - { - if ((*itr == a_Exclude) || !(*itr)->IsLoggedIn()) - { - continue; - } - (*itr)->Send( a_Packet ); - } -} - - - - - -void cServer::StartListenClient() -{ - cSocket SClient = m_pState->SListenClient.Accept(); - - if (!SClient.IsValid()) - { - return; - } - - const AString & ClientIP = SClient.GetIPString(); - if (ClientIP.empty()) - { - LOGWARN("cServer: A client connected, but didn't present its IP, disconnecting."); - SClient.CloseSocket(); - return; - } - - LOG("Client \"%s\" connected!", ClientIP.c_str()); - - cClientHandle *NewHandle = new cClientHandle(SClient, m_ClientViewDistance); - if (!m_SocketThreads.AddClient(&(NewHandle->GetSocket()), NewHandle)) - { - // For some reason SocketThreads have rejected the handle, clean it up - LOGERROR("Client \"%s\" cannot be handled, server probably unstable", SClient.GetIPString().c_str()); - SClient.CloseSocket(); - delete NewHandle; - return; - } - - cCSLock Lock(m_CSClients); - m_Clients.push_back( NewHandle ); -} - - - - - -bool cServer::Tick(float a_Dt) -{ - //LOG("1. Tick %0.2f", a_Dt); - if( a_Dt > 100.f ) a_Dt = 100.f; // Don't go over 1/10 second - - m_Millisecondsf += a_Dt; - if( m_Millisecondsf > 1.f ) - { - m_Milliseconds += (int)m_Millisecondsf; - m_Millisecondsf = m_Millisecondsf - (int)m_Millisecondsf; - } - - cRoot::Get()->TickWorlds( a_Dt ); // TODO - Maybe give all worlds their own thread? - - cClientHandleList RemoveClients; - { - cCSLock Lock(m_CSClients); - for (cClientHandleList::iterator itr = m_Clients.begin(); itr != m_Clients.end();) - { - if ((*itr)->IsDestroyed()) - { - RemoveClients.push_back(*itr); // Remove the client later, when CS is not held, to avoid deadlock ( http://forum.mc-server.org/showthread.php?tid=374 ) - itr = m_Clients.erase(itr); - continue; - } - (*itr)->Tick(a_Dt); - ++itr; - } // for itr - m_Clients[] - } - for (cClientHandleList::iterator itr = RemoveClients.begin(); itr != RemoveClients.end(); ++itr) - { - delete *itr; - } // for itr - RemoveClients[] - - cRoot::Get()->GetPluginManager()->Tick( a_Dt ); - - if( !m_bRestarting ) - { - return true; - } - else - { - m_bRestarting = false; - m_pState->RestartEvent.Set(); - return false; - } -} - - - - - -void ServerTickThread( void * a_Param ) -{ - LOG("ServerTickThread"); - cServer *CServerObj = (cServer*)a_Param; - - cTimer Timer; - - long long msPerTick = 50; // TODO - Put this in server config file - long long LastTime = Timer.GetNowTime(); - - bool bKeepGoing = true; - while( bKeepGoing ) - { - long long NowTime = Timer.GetNowTime(); - float DeltaTime = (float)(NowTime-LastTime); - bKeepGoing = CServerObj->Tick( DeltaTime ); - long long TickTime = Timer.GetNowTime() - NowTime; - - if( TickTime < msPerTick ) // Stretch tick time until it's at least msPerTick - { - cSleep::MilliSleep( (unsigned int)( msPerTick - TickTime ) ); - } - - LastTime = NowTime; - } - - LOG("TICK THREAD STOPPED"); -} - - - - - -void cServer::StartListenThread() -{ - m_pState->pListenThread = new cThread( ServerListenThread, this, "cServer::ServerListenThread" ); - m_pState->pTickThread = new cThread( ServerTickThread, this, "cServer::ServerTickThread" ); - m_pState->pListenThread->Start( true ); - m_pState->pTickThread->Start( true ); -} - - - - - -template -bool from_string( - T& t, - const std::string& s, - std::ios_base& (*f)(std::ios_base&) -) -{ - std::istringstream iss(s); - return !(iss >> f >> t).fail(); -} - - - - - -bool cServer::Command( cClientHandle & a_Client, const char* a_Cmd ) -{ - cPluginManager* PM = cRoot::Get()->GetPluginManager(); - if( PM->CallHook( cPluginManager::E_PLUGIN_CHAT, 2, a_Cmd, a_Client.GetPlayer() ) ) - { - return true; - } - return false; -} - - - - - -void cServer::ServerCommand( const char * a_Cmd ) -{ - AString Command( a_Cmd ); - AStringVector split = StringSplit( Command, " " ); - if( split.empty()) - { - return; - } - - if( split[0].compare( "help" ) == 0 ) - { - printf("================== ALL COMMANDS ===================\n"); - printf("help - Shows this message\n"); - printf("save-all - Saves all loaded chunks to disk\n"); - printf("list - Lists all players currently in server\n"); - printf("unload - Unloads all unused chunks\n"); - printf("numchunks - Shows number of chunks currently loaded\n"); - printf("chunkstats - Shows chunks statistics\n"); - printf("say - Sends a chat message to all players\n"); - printf("restart - Kicks all clients, and saves everything\n"); - printf(" and clears memory\n"); - printf("stop - Saves everything and closes server\n"); - printf("===================================================\n"); - return; - } - if( split[0].compare( "stop" ) == 0 || split[0].compare( "restart" ) == 0 ) - { - return; - } - if( split[0].compare( "save-all" ) == 0 ) - { - cRoot::Get()->SaveAllChunks(); // TODO - Force ALL worlds to save their chunks - return; - } - if (split[0].compare("unload") == 0) - { - LOG("Num loaded chunks before: %i", cRoot::Get()->GetTotalChunkCount() ); - cRoot::Get()->GetDefaultWorld()->UnloadUnusedChunks(); // TODO: Iterate through ALL worlds - LOG("Num loaded chunks after: %i", cRoot::Get()->GetTotalChunkCount() ); - return; - } - if( split[0].compare( "list" ) == 0 ) - { - class cPlayerLogger : public cPlayerListCallback - { - virtual bool Item(cPlayer * a_Player) override - { - LOG("\t%s @ %s", a_Player->GetName().c_str(), a_Player->GetClientHandle()->GetSocket().GetIPString().c_str()); - return false; - } - } Logger; - cRoot::Get()->ForEachPlayer(Logger); - return; - } - if( split[0].compare( "numchunks" ) == 0 ) - { - LOG("Num loaded chunks: %i", cRoot::Get()->GetTotalChunkCount() ); - return; - } - if (split[0].compare("chunkstats") == 0) - { - // TODO: For each world - int NumValid = 0; - int NumDirty = 0; - int NumInLighting = 0; - cWorld * World = cRoot::Get()->GetDefaultWorld(); - int NumInGenerator = World->GetGeneratorQueueLength(); - int NumInSaveQueue = World->GetStorageSaveQueueLength(); - int NumInLoadQueue = World->GetStorageLoadQueueLength(); - World->GetChunkStats(NumValid, NumDirty, NumInLighting); - LOG("Num loaded chunks: %d", NumValid); - LOG("Num dirty chunks: %d", NumDirty); - LOG("Num chunks in lighting queue: %d", NumInLighting); - LOG("Num chunks in generator queue: %d", NumInGenerator); - LOG("Num chunks in storage load queue: %d", NumInLoadQueue); - LOG("Num chunks in storage save queue: %d", NumInSaveQueue); - int Mem = NumValid * sizeof(cChunk); - LOG("Memory used by chunks: %d KiB (%d MiB)", (Mem + 1023) / 1024, (Mem + 1024 * 1024 - 1) / (1024 * 1024)); - LOG("Per-chunk memory size breakdown:"); - LOG(" block types: %6d bytes (%3d KiB)", sizeof(cChunkDef::BlockTypes), (sizeof(cChunkDef::BlockTypes) + 1023) / 1024); - LOG(" block metadata: %6d bytes (%3d KiB)", sizeof(cChunkDef::BlockNibbles), (sizeof(cChunkDef::BlockNibbles) + 1023) / 1024); - LOG(" block lighting: %6d bytes (%3d KiB)", 2 * sizeof(cChunkDef::BlockNibbles), (2 * sizeof(cChunkDef::BlockNibbles) + 1023) / 1024); - LOG(" heightmap: %6d bytes (%3d KiB)", sizeof(cChunkDef::HeightMap), (sizeof(cChunkDef::HeightMap) + 1023) / 1024); - LOG(" biomemap: %6d bytes (%3d KiB)", sizeof(cChunkDef::BiomeMap), (sizeof(cChunkDef::BiomeMap) + 1023) / 1024); - int Rest = sizeof(cChunk) - sizeof(cChunkDef::BlockTypes) - 3 * sizeof(cChunkDef::BlockNibbles) - sizeof(cChunkDef::HeightMap) - sizeof(cChunkDef::BiomeMap); - LOG(" other: %6d bytes (%3d KiB)", Rest, (Rest + 1023) / 1024); - return; - } - - if(split[0].compare("monsters") == 0 ) - { - // TODO: cWorld::ListMonsters(); - return; - } - - if(split.size() > 1) - { - if( split[0].compare( "say" ) == 0 ) - { - std::string Message = cChatColor::Purple + "[SERVER] " + Command.substr( Command.find_first_of("say") + 4 ); - LOG("%s", Message.c_str() ); - Broadcast( cPacket_Chat(Message) ); - return; - } - } - printf("Unknown command, type 'help' for all commands.\n"); - // LOG("You didn't enter anything? (%s)", a_Cmd.c_str() ); -} - - - - - -void cServer::SendMessage( const char* a_Message, cPlayer* a_Player /* = 0 */, bool a_bExclude /* = false */ ) -{ - cPacket_Chat Chat( a_Message ); - if( a_Player && !a_bExclude ) - { - cClientHandle* Client = a_Player->GetClientHandle(); - if( Client ) Client->Send( Chat ); - return; - } - - Broadcast( Chat, (a_Player)?a_Player->GetClientHandle():0 ); -} - - - - - -void cServer::Shutdown() -{ - m_bRestarting = true; - m_pState->RestartEvent.Wait(); - - cRoot::Get()->SaveAllChunks(); - - cCSLock Lock(m_CSClients); - for( ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr ) - { - delete *itr; - } - m_Clients.clear(); -} - - - - - -const AString & cServer::GetServerID(void) const -{ - return m_pState->ServerID; -} - - - - - -void cServer::KickUser(int a_ClientID, const AString & a_Reason) -{ - cCSLock Lock(m_CSClients); - for (ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr) - { - if ((*itr)->GetUniqueID() == a_ClientID) - { - (*itr)->Kick(a_Reason); - } - } // for itr - m_Clients[] -} - - - - - -void cServer::AuthenticateUser(int a_ClientID) -{ - cCSLock Lock(m_CSClients); - for (ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr) - { - if ((*itr)->GetUniqueID() == a_ClientID) - { - (*itr)->Authenticate(); - } - } // for itr - m_Clients[] -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cServer::cClientPacketThread: - -cServer::cNotifyWriteThread::cNotifyWriteThread(void) : - super("ClientPacketThread"), - m_Server(NULL) -{ -} - - - - - -cServer::cNotifyWriteThread::~cNotifyWriteThread() -{ - m_ShouldTerminate = true; - m_Event.Set(); - Wait(); -} - - - - - -bool cServer::cNotifyWriteThread::Start(cServer * a_Server) -{ - m_Server = a_Server; - return super::Start(); -} - - - - - -void cServer::cNotifyWriteThread::Execute(void) -{ - cClientHandleList Clients; - while (!m_ShouldTerminate) - { - cCSLock Lock(m_CS); - while (m_Clients.size() == 0) - { - cCSUnlock Unlock(Lock); - m_Event.Wait(); - if (m_ShouldTerminate) - { - return; - } - } - - // Copy the clients to notify and unlock the CS: - Clients.splice(Clients.begin(), m_Clients); - Lock.Unlock(); - - for (cClientHandleList::iterator itr = Clients.begin(); itr != Clients.end(); ++itr) - { - m_Server->m_SocketThreads.NotifyWrite(*itr); - } // for itr - Clients[] - Clients.clear(); - } // while (!mShouldTerminate) -} - - - - - -void cServer::cNotifyWriteThread::NotifyClientWrite(const cClientHandle * a_Client) -{ - { - cCSLock Lock(m_CS); - m_Clients.remove(const_cast(a_Client)); // Put it there only once - m_Clients.push_back(const_cast(a_Client)); - } - m_Event.Set(); -} - - - - + +// ReDucTor is an awesome guy who helped me a lot + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cServer.h" +#include "cClientHandle.h" +#include "cSleep.h" +#include "cTimer.h" +#include "cMonster.h" +#include "cSocket.h" +#include "cRoot.h" +#include "cWorld.h" +#include "ChunkDef.h" +#include "cPluginManager.h" +#include "cGroupManager.h" +#include "cChatColor.h" +#include "cPlayer.h" +#include "cInventory.h" +#include "cItem.h" +#include "cFurnaceRecipe.h" +#include "cTracer.h" +#include "cWebAdmin.h" +#include "cChunk.h" + +#include "MersenneTwister.h" + +#include "../iniFile/iniFile.h" +#include "Vector3f.h" + +#include "packets/cPacket_Chat.h" + +#include +#include +#include + + + + + +extern "C" { + #include "zlib.h" +} + + + +bool g_bWaterPhysics = false; + +typedef std::list< cClientHandle* > ClientList; + + + + + +struct cServer::sServerState +{ + sServerState() + : pListenThread( 0 ) + , pTickThread( 0 ) + , bStopListenThread( false ) + , bStopTickThread( false ) + {} + cSocket SListenClient; // socket listening for client calls + + cThread* pListenThread; bool bStopListenThread; + cThread* pTickThread; bool bStopTickThread; + + cEvent RestartEvent; + std::string ServerID; +}; + + + + + +cServer * cServer::GetServer() +{ + LOGWARN("WARNING: Using deprecated function cServer::GetServer() use cRoot::Get()->GetServer() instead!"); + return cRoot::Get()->GetServer(); +} + + + + + +void cServer::ServerListenThread( void *a_Args ) +{ + LOG("ServerListenThread"); + cServer* self = (cServer*)a_Args; + sServerState* m_pState = self->m_pState; + while( !m_pState->bStopListenThread ) + { + self->StartListenClient(); + } +} + + + + + +void cServer::ClientDestroying(const cClientHandle * a_Client) +{ + m_SocketThreads.StopReading(a_Client); +} + + + + + +void cServer::NotifyClientWrite(const cClientHandle * a_Client) +{ + m_NotifyWriteThread.NotifyClientWrite(a_Client); +} + + + + + +void cServer::WriteToClient(const cSocket * a_Socket, const AString & a_Data) +{ + m_SocketThreads.Write(a_Socket, a_Data); +} + + + + + +void cServer::QueueClientClose(const cSocket * a_Socket) +{ + m_SocketThreads.QueueClose(a_Socket); +} + + + + + +void cServer::RemoveClient(const cSocket * a_Socket) +{ + m_SocketThreads.RemoveClient(a_Socket); +} + + + + + +bool cServer::InitServer( int a_Port ) +{ + if( m_bIsConnected ) + { + LOGERROR("ERROR: Trying to initialize server while server is already running!"); + return false; + } + + printf("/============================\\\n"); + printf("| Custom Minecraft Server |\n"); + printf("| Created by Kevin Bansberg |\n"); + printf("| A.K.A. FakeTruth |\n"); + printf("| Monsters by Alex Sonek |\n"); + printf("| A.K.A. Duralex |\n"); + printf("| Stuff by Mattes D |\n"); + printf("| A.K.A. _Xoft(o) |\n"); + printf("\\============================/\n"); + printf("More info: WWW.MC-SERVER.ORG\n"); + printf(" WWW.AE-C.NET\n"); + printf(" WWW.RBTHINKTANK.COM\n"); + printf("email: faketruth@gmail.com\n\n"); + + LOG("Starting up server."); + LOGINFO("Compatible clients: %s, protocol version %d", MCS_CLIENT_VERSION, MCS_PROTOCOL_VERSION); + + if( cSocket::WSAStartup() != 0 ) // Only does anything on Windows, but whatever + { + LOGERROR("WSAStartup() != 0"); + return false; + } + + m_pState->SListenClient = cSocket::CreateSocket(); + + if( !m_pState->SListenClient.IsValid() ) + { + LOGERROR("m_SListenClient==INVALID_SOCKET (%s)", cSocket::GetErrorString( cSocket::GetLastError() ).c_str() ); + return false; + } + + if( m_pState->SListenClient.SetReuseAddress() == -1 ) + { + LOGERROR("setsockopt == -1"); + return false; + } + + cSocket::SockAddr_In local; + local.Family = cSocket::ADDRESS_FAMILY_INTERNET; + local.Address = cSocket::INTERNET_ADDRESS_ANY; + local.Port = (unsigned short)a_Port; // 25565 + + if( m_pState->SListenClient.Bind( local ) != 0 ) + { + LOGERROR("bind fail (%s)", cSocket::GetErrorString( cSocket::GetLastError() ).c_str() ); + return false; + } + + if( m_pState->SListenClient.Listen( 10 ) != 0) + { + LOGERROR("listen fail (%s)", cSocket::GetErrorString( cSocket::GetLastError() ).c_str() ); + return false; + } + + m_iServerPort = a_Port; + LOG("Port %i has been bound, server is open for connections", m_iServerPort); + m_bIsConnected = true; + + cIniFile IniFile("settings.ini"); + if (IniFile.ReadFile()) + { + g_bWaterPhysics = IniFile.GetValueB("Physics", "Water", false ); + + m_pState->ServerID = "-"; + if (IniFile.GetValueB("Authentication", "Authenticate")) + { + MTRand mtrand1; + unsigned int r1 = (mtrand1.randInt()%1147483647) + 1000000000; + unsigned int r2 = (mtrand1.randInt()%1147483647) + 1000000000; + std::ostringstream sid; + sid << std::hex << r1; + sid << std::hex << r2; + std::string ServerID = sid.str(); + ServerID.resize(16, '0'); + m_pState->ServerID = ServerID; + } + + m_ClientViewDistance = IniFile.GetValueSetI("Server", "DefaultViewDistance", cClientHandle::DEFAULT_VIEW_DISTANCE); + if (m_ClientViewDistance < cClientHandle::MIN_VIEW_DISTANCE) + { + m_ClientViewDistance = cClientHandle::MIN_VIEW_DISTANCE; + LOGINFO("Setting default viewdistance to the minimum of %d", m_ClientViewDistance); + } + if (m_ClientViewDistance > cClientHandle::MAX_VIEW_DISTANCE) + { + m_ClientViewDistance = cClientHandle::MAX_VIEW_DISTANCE; + LOGINFO("Setting default viewdistance to the maximum of %d", m_ClientViewDistance); + } + IniFile.WriteFile(); + } + + m_NotifyWriteThread.Start(this); + + return true; +} + + + + + +cServer::cServer() + : m_pState( new sServerState ) + , m_Millisecondsf( 0 ) + , m_Milliseconds( 0 ) + , m_bIsConnected( false ) + , m_iServerPort( 0 ) + , m_bRestarting( false ) +{ +} + + + + + +cServer::~cServer() +{ + // TODO: Shut down the server gracefully + if ( m_pState->SListenClient ) + { + m_pState->SListenClient.CloseSocket(); + } + m_pState->SListenClient = 0; + + m_pState->bStopListenThread = true; + delete m_pState->pListenThread; m_pState->pListenThread = NULL; + m_pState->bStopTickThread = true; + delete m_pState->pTickThread; m_pState->pTickThread = NULL; + + delete m_pState; +} + + + + + +// TODO - Need to modify this or something, so it broadcasts to all worlds? And move this to cWorld? +void cServer::Broadcast( const cPacket & a_Packet, cClientHandle* a_Exclude /* = 0 */ ) +{ + cCSLock Lock(m_CSClients); + for( ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr) + { + if ((*itr == a_Exclude) || !(*itr)->IsLoggedIn()) + { + continue; + } + (*itr)->Send( a_Packet ); + } +} + + + + + +void cServer::StartListenClient() +{ + cSocket SClient = m_pState->SListenClient.Accept(); + + if (!SClient.IsValid()) + { + return; + } + + const AString & ClientIP = SClient.GetIPString(); + if (ClientIP.empty()) + { + LOGWARN("cServer: A client connected, but didn't present its IP, disconnecting."); + SClient.CloseSocket(); + return; + } + + LOG("Client \"%s\" connected!", ClientIP.c_str()); + + cClientHandle *NewHandle = new cClientHandle(SClient, m_ClientViewDistance); + if (!m_SocketThreads.AddClient(&(NewHandle->GetSocket()), NewHandle)) + { + // For some reason SocketThreads have rejected the handle, clean it up + LOGERROR("Client \"%s\" cannot be handled, server probably unstable", SClient.GetIPString().c_str()); + SClient.CloseSocket(); + delete NewHandle; + return; + } + + cCSLock Lock(m_CSClients); + m_Clients.push_back( NewHandle ); +} + + + + + +bool cServer::Tick(float a_Dt) +{ + //LOG("1. Tick %0.2f", a_Dt); + if( a_Dt > 100.f ) a_Dt = 100.f; // Don't go over 1/10 second + + m_Millisecondsf += a_Dt; + if( m_Millisecondsf > 1.f ) + { + m_Milliseconds += (int)m_Millisecondsf; + m_Millisecondsf = m_Millisecondsf - (int)m_Millisecondsf; + } + + cRoot::Get()->TickWorlds( a_Dt ); // TODO - Maybe give all worlds their own thread? + + cClientHandleList RemoveClients; + { + cCSLock Lock(m_CSClients); + for (cClientHandleList::iterator itr = m_Clients.begin(); itr != m_Clients.end();) + { + if ((*itr)->IsDestroyed()) + { + RemoveClients.push_back(*itr); // Remove the client later, when CS is not held, to avoid deadlock ( http://forum.mc-server.org/showthread.php?tid=374 ) + itr = m_Clients.erase(itr); + continue; + } + (*itr)->Tick(a_Dt); + ++itr; + } // for itr - m_Clients[] + } + for (cClientHandleList::iterator itr = RemoveClients.begin(); itr != RemoveClients.end(); ++itr) + { + delete *itr; + } // for itr - RemoveClients[] + + cRoot::Get()->GetPluginManager()->Tick( a_Dt ); + + if( !m_bRestarting ) + { + return true; + } + else + { + m_bRestarting = false; + m_pState->RestartEvent.Set(); + return false; + } +} + + + + + +void ServerTickThread( void * a_Param ) +{ + LOG("ServerTickThread"); + cServer *CServerObj = (cServer*)a_Param; + + cTimer Timer; + + long long msPerTick = 50; // TODO - Put this in server config file + long long LastTime = Timer.GetNowTime(); + + bool bKeepGoing = true; + while( bKeepGoing ) + { + long long NowTime = Timer.GetNowTime(); + float DeltaTime = (float)(NowTime-LastTime); + bKeepGoing = CServerObj->Tick( DeltaTime ); + long long TickTime = Timer.GetNowTime() - NowTime; + + if( TickTime < msPerTick ) // Stretch tick time until it's at least msPerTick + { + cSleep::MilliSleep( (unsigned int)( msPerTick - TickTime ) ); + } + + LastTime = NowTime; + } + + LOG("TICK THREAD STOPPED"); +} + + + + + +void cServer::StartListenThread() +{ + m_pState->pListenThread = new cThread( ServerListenThread, this, "cServer::ServerListenThread" ); + m_pState->pTickThread = new cThread( ServerTickThread, this, "cServer::ServerTickThread" ); + m_pState->pListenThread->Start( true ); + m_pState->pTickThread->Start( true ); +} + + + + + +template +bool from_string( + T& t, + const std::string& s, + std::ios_base& (*f)(std::ios_base&) +) +{ + std::istringstream iss(s); + return !(iss >> f >> t).fail(); +} + + + + + +bool cServer::Command( cClientHandle & a_Client, const char* a_Cmd ) +{ + cPluginManager* PM = cRoot::Get()->GetPluginManager(); + if( PM->CallHook( cPluginManager::E_PLUGIN_CHAT, 2, a_Cmd, a_Client.GetPlayer() ) ) + { + return true; + } + return false; +} + + + + + +void cServer::ServerCommand( const char * a_Cmd ) +{ + AString Command( a_Cmd ); + AStringVector split = StringSplit( Command, " " ); + if( split.empty()) + { + return; + } + + if( split[0].compare( "help" ) == 0 ) + { + printf("================== ALL COMMANDS ===================\n"); + printf("help - Shows this message\n"); + printf("save-all - Saves all loaded chunks to disk\n"); + printf("list - Lists all players currently in server\n"); + printf("unload - Unloads all unused chunks\n"); + printf("numchunks - Shows number of chunks currently loaded\n"); + printf("chunkstats - Shows chunks statistics\n"); + printf("say - Sends a chat message to all players\n"); + printf("restart - Kicks all clients, and saves everything\n"); + printf(" and clears memory\n"); + printf("stop - Saves everything and closes server\n"); + printf("===================================================\n"); + return; + } + if( split[0].compare( "stop" ) == 0 || split[0].compare( "restart" ) == 0 ) + { + return; + } + if( split[0].compare( "save-all" ) == 0 ) + { + cRoot::Get()->SaveAllChunks(); // TODO - Force ALL worlds to save their chunks + return; + } + if (split[0].compare("unload") == 0) + { + LOG("Num loaded chunks before: %i", cRoot::Get()->GetTotalChunkCount() ); + cRoot::Get()->GetDefaultWorld()->UnloadUnusedChunks(); // TODO: Iterate through ALL worlds + LOG("Num loaded chunks after: %i", cRoot::Get()->GetTotalChunkCount() ); + return; + } + if( split[0].compare( "list" ) == 0 ) + { + class cPlayerLogger : public cPlayerListCallback + { + virtual bool Item(cPlayer * a_Player) override + { + LOG("\t%s @ %s", a_Player->GetName().c_str(), a_Player->GetClientHandle()->GetSocket().GetIPString().c_str()); + return false; + } + } Logger; + cRoot::Get()->ForEachPlayer(Logger); + return; + } + if( split[0].compare( "numchunks" ) == 0 ) + { + LOG("Num loaded chunks: %i", cRoot::Get()->GetTotalChunkCount() ); + return; + } + if (split[0].compare("chunkstats") == 0) + { + // TODO: For each world + int NumValid = 0; + int NumDirty = 0; + int NumInLighting = 0; + cWorld * World = cRoot::Get()->GetDefaultWorld(); + int NumInGenerator = World->GetGeneratorQueueLength(); + int NumInSaveQueue = World->GetStorageSaveQueueLength(); + int NumInLoadQueue = World->GetStorageLoadQueueLength(); + World->GetChunkStats(NumValid, NumDirty, NumInLighting); + LOG("Num loaded chunks: %d", NumValid); + LOG("Num dirty chunks: %d", NumDirty); + LOG("Num chunks in lighting queue: %d", NumInLighting); + LOG("Num chunks in generator queue: %d", NumInGenerator); + LOG("Num chunks in storage load queue: %d", NumInLoadQueue); + LOG("Num chunks in storage save queue: %d", NumInSaveQueue); + int Mem = NumValid * sizeof(cChunk); + LOG("Memory used by chunks: %d KiB (%d MiB)", (Mem + 1023) / 1024, (Mem + 1024 * 1024 - 1) / (1024 * 1024)); + LOG("Per-chunk memory size breakdown:"); + LOG(" block types: %6d bytes (%3d KiB)", sizeof(cChunkDef::BlockTypes), (sizeof(cChunkDef::BlockTypes) + 1023) / 1024); + LOG(" block metadata: %6d bytes (%3d KiB)", sizeof(cChunkDef::BlockNibbles), (sizeof(cChunkDef::BlockNibbles) + 1023) / 1024); + LOG(" block lighting: %6d bytes (%3d KiB)", 2 * sizeof(cChunkDef::BlockNibbles), (2 * sizeof(cChunkDef::BlockNibbles) + 1023) / 1024); + LOG(" heightmap: %6d bytes (%3d KiB)", sizeof(cChunkDef::HeightMap), (sizeof(cChunkDef::HeightMap) + 1023) / 1024); + LOG(" biomemap: %6d bytes (%3d KiB)", sizeof(cChunkDef::BiomeMap), (sizeof(cChunkDef::BiomeMap) + 1023) / 1024); + int Rest = sizeof(cChunk) - sizeof(cChunkDef::BlockTypes) - 3 * sizeof(cChunkDef::BlockNibbles) - sizeof(cChunkDef::HeightMap) - sizeof(cChunkDef::BiomeMap); + LOG(" other: %6d bytes (%3d KiB)", Rest, (Rest + 1023) / 1024); + return; + } + + if(split[0].compare("monsters") == 0 ) + { + // TODO: cWorld::ListMonsters(); + return; + } + + if(split.size() > 1) + { + if( split[0].compare( "say" ) == 0 ) + { + std::string Message = cChatColor::Purple + "[SERVER] " + Command.substr( Command.find_first_of("say") + 4 ); + LOG("%s", Message.c_str() ); + Broadcast( cPacket_Chat(Message) ); + return; + } + } + printf("Unknown command, type 'help' for all commands.\n"); + // LOG("You didn't enter anything? (%s)", a_Cmd.c_str() ); +} + + + + + +void cServer::SendMessage( const char* a_Message, cPlayer* a_Player /* = 0 */, bool a_bExclude /* = false */ ) +{ + cPacket_Chat Chat( a_Message ); + if( a_Player && !a_bExclude ) + { + cClientHandle* Client = a_Player->GetClientHandle(); + if( Client ) Client->Send( Chat ); + return; + } + + Broadcast( Chat, (a_Player)?a_Player->GetClientHandle():0 ); +} + + + + + +void cServer::Shutdown() +{ + m_bRestarting = true; + m_pState->RestartEvent.Wait(); + + cRoot::Get()->SaveAllChunks(); + + cCSLock Lock(m_CSClients); + for( ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr ) + { + delete *itr; + } + m_Clients.clear(); +} + + + + + +const AString & cServer::GetServerID(void) const +{ + return m_pState->ServerID; +} + + + + + +void cServer::KickUser(int a_ClientID, const AString & a_Reason) +{ + cCSLock Lock(m_CSClients); + for (ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr) + { + if ((*itr)->GetUniqueID() == a_ClientID) + { + (*itr)->Kick(a_Reason); + } + } // for itr - m_Clients[] +} + + + + + +void cServer::AuthenticateUser(int a_ClientID) +{ + cCSLock Lock(m_CSClients); + for (ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr) + { + if ((*itr)->GetUniqueID() == a_ClientID) + { + (*itr)->Authenticate(); + } + } // for itr - m_Clients[] +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cServer::cClientPacketThread: + +cServer::cNotifyWriteThread::cNotifyWriteThread(void) : + super("ClientPacketThread"), + m_Server(NULL) +{ +} + + + + + +cServer::cNotifyWriteThread::~cNotifyWriteThread() +{ + m_ShouldTerminate = true; + m_Event.Set(); + Wait(); +} + + + + + +bool cServer::cNotifyWriteThread::Start(cServer * a_Server) +{ + m_Server = a_Server; + return super::Start(); +} + + + + + +void cServer::cNotifyWriteThread::Execute(void) +{ + cClientHandleList Clients; + while (!m_ShouldTerminate) + { + cCSLock Lock(m_CS); + while (m_Clients.size() == 0) + { + cCSUnlock Unlock(Lock); + m_Event.Wait(); + if (m_ShouldTerminate) + { + return; + } + } + + // Copy the clients to notify and unlock the CS: + Clients.splice(Clients.begin(), m_Clients); + Lock.Unlock(); + + for (cClientHandleList::iterator itr = Clients.begin(); itr != Clients.end(); ++itr) + { + m_Server->m_SocketThreads.NotifyWrite(*itr); + } // for itr - Clients[] + Clients.clear(); + } // while (!mShouldTerminate) +} + + + + + +void cServer::cNotifyWriteThread::NotifyClientWrite(const cClientHandle * a_Client) +{ + { + cCSLock Lock(m_CS); + m_Clients.remove(const_cast(a_Client)); // Put it there only once + m_Clients.push_back(const_cast(a_Client)); + } + m_Event.Set(); +} + + + + diff --git a/source/cServer.h b/source/cServer.h index dc1de96cd..e0723f76a 100644 --- a/source/cServer.h +++ b/source/cServer.h @@ -1,132 +1,132 @@ - -// cServer.h - -// Interfaces to the cServer object representing the network server - - - - - -#pragma once -#ifndef CSERVER_H_INCLUDED -#define CSERVER_H_INCLUDED - -#include "cSocketThreads.h" - - - - - -class cPlayer; -class cClientHandle; -class cPacket; - -typedef std::list cClientHandleList; - - - - - -class cServer //tolua_export -{ //tolua_export -public: //tolua_export - static cServer * GetServer(); //tolua_export - - bool InitServer( int a_Port = 25565 ); - - int GetPort() { return m_iServerPort; } - bool IsConnected(){return m_bIsConnected;} // returns connection status - void StartListenClient(); // Listen to client - - void Broadcast(const cPacket & a_Packet, cClientHandle* a_Exclude = NULL); - - bool Tick(float a_Dt); - - void StartListenThread(); - - bool Command( cClientHandle & a_Client, const char* a_Cmd ); - void ServerCommand( const char* a_Cmd ); //tolua_export - void Shutdown(); - - void SendMessage( const char* a_Message, cPlayer* a_Player = 0, bool a_bExclude = false ); //tolua_export - - void KickUser(int a_ClientID, const AString & a_Reason); - void AuthenticateUser(int a_ClientID); // Called by cAuthenticator to auth the specified user - - static void ServerListenThread( void* a_Args ); - - const AString & GetServerID(void) const; - - void ClientDestroying(const cClientHandle * a_Client); // Called by cClientHandle::Destroy(); stop m_SocketThreads from calling back into a_Client - - void NotifyClientWrite(const cClientHandle * a_Client); // Notifies m_SocketThreads that client has something to be written - - void WriteToClient(const cSocket * a_Socket, const AString & a_Data); // Queues outgoing data for the socket through m_SocketThreads - - void QueueClientClose(const cSocket * a_Socket); // Queues the socket to close when all its outgoing data is sent - - void RemoveClient(const cSocket * a_Socket); // Removes the socket from m_SocketThreads - -private: - - friend class cRoot; // so cRoot can create and destroy cServer - - /// When NotifyClientWrite() is called, it is queued for this thread to process (to avoid deadlocks between cSocketThreads, cClientHandle and cChunkMap) - class cNotifyWriteThread : - public cIsThread - { - typedef cIsThread super; - - cEvent m_Event; // Set when m_Clients gets appended - cServer * m_Server; - - cCriticalSection m_CS; - cClientHandleList m_Clients; - - virtual void Execute(void); - - public: - - cNotifyWriteThread(void); - ~cNotifyWriteThread(); - - bool Start(cServer * a_Server); - - void NotifyClientWrite(const cClientHandle * a_Client); - } ; - - struct sServerState; - sServerState* m_pState; - - cNotifyWriteThread m_NotifyWriteThread; - - cCriticalSection m_CSClients; // Locks client list - cClientHandleList m_Clients; // Clients that are connected to the server - - cSocketThreads m_SocketThreads; - - int m_ClientViewDistance; // The default view distance for clients; settable in Settings.ini - - // Time since server was started - float m_Millisecondsf; - unsigned int m_Milliseconds; - - bool m_bIsConnected; // true - connected false - not connected - int m_iServerPort; - - bool m_bRestarting; - - cServer(); - ~cServer(); - -}; //tolua_export - - - - - -#endif // CSERVER_H_INCLUDED - - - - + +// cServer.h + +// Interfaces to the cServer object representing the network server + + + + + +#pragma once +#ifndef CSERVER_H_INCLUDED +#define CSERVER_H_INCLUDED + +#include "cSocketThreads.h" + + + + + +class cPlayer; +class cClientHandle; +class cPacket; + +typedef std::list cClientHandleList; + + + + + +class cServer //tolua_export +{ //tolua_export +public: //tolua_export + static cServer * GetServer(); //tolua_export + + bool InitServer( int a_Port = 25565 ); + + int GetPort() { return m_iServerPort; } + bool IsConnected(){return m_bIsConnected;} // returns connection status + void StartListenClient(); // Listen to client + + void Broadcast(const cPacket & a_Packet, cClientHandle* a_Exclude = NULL); + + bool Tick(float a_Dt); + + void StartListenThread(); + + bool Command( cClientHandle & a_Client, const char* a_Cmd ); + void ServerCommand( const char* a_Cmd ); //tolua_export + void Shutdown(); + + void SendMessage( const char* a_Message, cPlayer* a_Player = 0, bool a_bExclude = false ); //tolua_export + + void KickUser(int a_ClientID, const AString & a_Reason); + void AuthenticateUser(int a_ClientID); // Called by cAuthenticator to auth the specified user + + static void ServerListenThread( void* a_Args ); + + const AString & GetServerID(void) const; + + void ClientDestroying(const cClientHandle * a_Client); // Called by cClientHandle::Destroy(); stop m_SocketThreads from calling back into a_Client + + void NotifyClientWrite(const cClientHandle * a_Client); // Notifies m_SocketThreads that client has something to be written + + void WriteToClient(const cSocket * a_Socket, const AString & a_Data); // Queues outgoing data for the socket through m_SocketThreads + + void QueueClientClose(const cSocket * a_Socket); // Queues the socket to close when all its outgoing data is sent + + void RemoveClient(const cSocket * a_Socket); // Removes the socket from m_SocketThreads + +private: + + friend class cRoot; // so cRoot can create and destroy cServer + + /// When NotifyClientWrite() is called, it is queued for this thread to process (to avoid deadlocks between cSocketThreads, cClientHandle and cChunkMap) + class cNotifyWriteThread : + public cIsThread + { + typedef cIsThread super; + + cEvent m_Event; // Set when m_Clients gets appended + cServer * m_Server; + + cCriticalSection m_CS; + cClientHandleList m_Clients; + + virtual void Execute(void); + + public: + + cNotifyWriteThread(void); + ~cNotifyWriteThread(); + + bool Start(cServer * a_Server); + + void NotifyClientWrite(const cClientHandle * a_Client); + } ; + + struct sServerState; + sServerState* m_pState; + + cNotifyWriteThread m_NotifyWriteThread; + + cCriticalSection m_CSClients; // Locks client list + cClientHandleList m_Clients; // Clients that are connected to the server + + cSocketThreads m_SocketThreads; + + int m_ClientViewDistance; // The default view distance for clients; settable in Settings.ini + + // Time since server was started + float m_Millisecondsf; + unsigned int m_Milliseconds; + + bool m_bIsConnected; // true - connected false - not connected + int m_iServerPort; + + bool m_bRestarting; + + cServer(); + ~cServer(); + +}; //tolua_export + + + + + +#endif // CSERVER_H_INCLUDED + + + + diff --git a/source/cSheep.cpp b/source/cSheep.cpp index 921cd2d28..c9fed280a 100644 --- a/source/cSheep.cpp +++ b/source/cSheep.cpp @@ -1,65 +1,65 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cSheep.h" - - - - - -//Todo: Implement color - - - - - -cSheep::cSheep(void) : - m_IsSheared(false), - m_WoolColor(0) // TODO: E_META_WOOL_WHITE -{ - m_MobType = 91; - GetMonsterConfig("Sheep"); -} - - - - - -cSheep::~cSheep() -{ -} - - - - - -bool cSheep::IsA( const char* a_EntityType ) -{ - if (strcmp( a_EntityType, "cSheep" ) == 0) - { - return true; - } - return cMonster::IsA( a_EntityType ); -} - - - - - -void cSheep::KilledBy( cEntity* a_Killer ) -{ - // TODO: Check whether it is sheared - // TODO: Check color - - if (!m_IsSheared) - { - cItems Drops; - Drops.push_back(cItem(E_ITEM_WHITE_CLOTH, 1, m_WoolColor)); - m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); - } - - cMonster::KilledBy( a_Killer ); -} - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSheep.h" + + + + + +//Todo: Implement color + + + + + +cSheep::cSheep(void) : + m_IsSheared(false), + m_WoolColor(0) // TODO: E_META_WOOL_WHITE +{ + m_MobType = 91; + GetMonsterConfig("Sheep"); +} + + + + + +cSheep::~cSheep() +{ +} + + + + + +bool cSheep::IsA( const char* a_EntityType ) +{ + if (strcmp( a_EntityType, "cSheep" ) == 0) + { + return true; + } + return cMonster::IsA( a_EntityType ); +} + + + + + +void cSheep::KilledBy( cEntity* a_Killer ) +{ + // TODO: Check whether it is sheared + // TODO: Check color + + if (!m_IsSheared) + { + cItems Drops; + Drops.push_back(cItem(E_ITEM_WHITE_CLOTH, 1, m_WoolColor)); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + } + + cMonster::KilledBy( a_Killer ); +} + + + diff --git a/source/cSheep.h b/source/cSheep.h index 9faa25592..98faa266c 100644 --- a/source/cSheep.h +++ b/source/cSheep.h @@ -1,17 +1,17 @@ -#pragma once - -#include "cPassiveMonster.h" - -class cSheep : public cPassiveMonster -{ -public: - cSheep(); - ~cSheep(); - - bool m_IsSheared; - NIBBLETYPE m_WoolColor; // Uses E_META_WOOL_ constants for colors - - virtual bool IsA(const char * a_EntityType); - - virtual void KilledBy(cEntity * a_Killer); -}; +#pragma once + +#include "cPassiveMonster.h" + +class cSheep : public cPassiveMonster +{ +public: + cSheep(); + ~cSheep(); + + bool m_IsSheared; + NIBBLETYPE m_WoolColor; // Uses E_META_WOOL_ constants for colors + + virtual bool IsA(const char * a_EntityType); + + virtual void KilledBy(cEntity * a_Killer); +}; diff --git a/source/cSign.h b/source/cSign.h index ebdeb3031..9daa8234c 100644 --- a/source/cSign.h +++ b/source/cSign.h @@ -1,32 +1,32 @@ -#pragma once - -class cSign //tolua_export -{ //tolua_export -public: - static char RotationToMetaData( float a_Rotation ) //tolua_export - { //tolua_export - a_Rotation += 180 + (180/16); // So its not aligned with axis - if( a_Rotation > 360.f ) a_Rotation -= 360.f; - - a_Rotation = (a_Rotation/360) * 16; - - return ((char)a_Rotation) % 16; - } //tolua_export - static char DirectionToMetaData( char a_Direction ) //tolua_export - { //tolua_export - switch( a_Direction ) - { - case 0x2: - return 0x2; - case 0x3: - return 0x3; - case 0x4: - return 0x4; - case 0x5: - return 0x5; - default: - break; - }; - return 0x2; - } +#pragma once + +class cSign //tolua_export +{ //tolua_export +public: + static char RotationToMetaData( float a_Rotation ) //tolua_export + { //tolua_export + a_Rotation += 180 + (180/16); // So its not aligned with axis + if( a_Rotation > 360.f ) a_Rotation -= 360.f; + + a_Rotation = (a_Rotation/360) * 16; + + return ((char)a_Rotation) % 16; + } //tolua_export + static char DirectionToMetaData( char a_Direction ) //tolua_export + { //tolua_export + switch( a_Direction ) + { + case 0x2: + return 0x2; + case 0x3: + return 0x3; + case 0x4: + return 0x4; + case 0x5: + return 0x5; + default: + break; + }; + return 0x2; + } }; //tolua_export \ No newline at end of file diff --git a/source/cSignEntity.cpp b/source/cSignEntity.cpp index cf0a13650..80e10621e 100644 --- a/source/cSignEntity.cpp +++ b/source/cSignEntity.cpp @@ -1,140 +1,140 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cSignEntity.h" - -#include "cPlayer.h" -#include "cClientHandle.h" -#include "cWorld.h" -#include "cRoot.h" - -#include "packets/cPacket_UpdateSign.h" - -#include - - - - - -cSignEntity::cSignEntity(ENUM_BLOCK_ID a_BlockType, int a_X, int a_Y, int a_Z, cWorld * a_World) - : cBlockEntity(a_BlockType, a_X, a_Y, a_Z, a_World) -{ -} - - - - - -cSignEntity::~cSignEntity() -{ -} - - - - - -// It don't do anything when 'used' -void cSignEntity::UsedBy( cPlayer * a_Player ) -{ - (void)a_Player; -} - - - - - -void cSignEntity::SetLines( const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4 ) -{ - m_Line[0] = a_Line1; - m_Line[1] = a_Line2; - m_Line[2] = a_Line3; - m_Line[3] = a_Line4; -} - - - - - -void cSignEntity::SetLine( int a_Index, const AString & a_Line ) -{ - if( a_Index < 4 && a_Index > -1 ) - { - m_Line[a_Index] = a_Line; - } -} - - - - - -AString cSignEntity::GetLine( int a_Index ) const -{ - if( a_Index < 4 && a_Index > -1 ) - { - return m_Line[a_Index]; - } - return ""; -} - - - - - -cPacket * cSignEntity::GetPacket(void) -{ - cPacket_UpdateSign * Sign = new cPacket_UpdateSign; - Sign->m_PosX = m_PosX; - Sign->m_PosY = (short)m_PosY; - Sign->m_PosZ = m_PosZ; - Sign->m_Line1 = m_Line[0]; - Sign->m_Line2 = m_Line[1]; - Sign->m_Line3 = m_Line[2]; - Sign->m_Line4 = m_Line[3]; - return Sign; -} - - - - - -#define READ(File, Var) \ - if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \ - { \ - LOGERROR("ERROR READING cSignEntity %s FROM FILE (line %d)", #Var, __LINE__); \ - return false; \ - } - - - - - - -bool cSignEntity::LoadFromJson( const Json::Value & a_Value ) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - m_Line[0] = a_Value.get("Line1", "").asString(); - m_Line[1] = a_Value.get("Line2", "").asString(); - m_Line[2] = a_Value.get("Line3", "").asString(); - m_Line[3] = a_Value.get("Line4", "").asString(); - - return true; -} - -void cSignEntity::SaveToJson( Json::Value & a_Value ) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - a_Value["Line1"] = m_Line[0]; - a_Value["Line2"] = m_Line[1]; - a_Value["Line3"] = m_Line[2]; - a_Value["Line4"] = m_Line[3]; -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSignEntity.h" + +#include "cPlayer.h" +#include "cClientHandle.h" +#include "cWorld.h" +#include "cRoot.h" + +#include "packets/cPacket_UpdateSign.h" + +#include + + + + + +cSignEntity::cSignEntity(ENUM_BLOCK_ID a_BlockType, int a_X, int a_Y, int a_Z, cWorld * a_World) + : cBlockEntity(a_BlockType, a_X, a_Y, a_Z, a_World) +{ +} + + + + + +cSignEntity::~cSignEntity() +{ +} + + + + + +// It don't do anything when 'used' +void cSignEntity::UsedBy( cPlayer * a_Player ) +{ + (void)a_Player; +} + + + + + +void cSignEntity::SetLines( const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4 ) +{ + m_Line[0] = a_Line1; + m_Line[1] = a_Line2; + m_Line[2] = a_Line3; + m_Line[3] = a_Line4; +} + + + + + +void cSignEntity::SetLine( int a_Index, const AString & a_Line ) +{ + if( a_Index < 4 && a_Index > -1 ) + { + m_Line[a_Index] = a_Line; + } +} + + + + + +AString cSignEntity::GetLine( int a_Index ) const +{ + if( a_Index < 4 && a_Index > -1 ) + { + return m_Line[a_Index]; + } + return ""; +} + + + + + +cPacket * cSignEntity::GetPacket(void) +{ + cPacket_UpdateSign * Sign = new cPacket_UpdateSign; + Sign->m_PosX = m_PosX; + Sign->m_PosY = (short)m_PosY; + Sign->m_PosZ = m_PosZ; + Sign->m_Line1 = m_Line[0]; + Sign->m_Line2 = m_Line[1]; + Sign->m_Line3 = m_Line[2]; + Sign->m_Line4 = m_Line[3]; + return Sign; +} + + + + + +#define READ(File, Var) \ + if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \ + { \ + LOGERROR("ERROR READING cSignEntity %s FROM FILE (line %d)", #Var, __LINE__); \ + return false; \ + } + + + + + + +bool cSignEntity::LoadFromJson( const Json::Value & a_Value ) +{ + m_PosX = a_Value.get("x", 0).asInt(); + m_PosY = a_Value.get("y", 0).asInt(); + m_PosZ = a_Value.get("z", 0).asInt(); + + m_Line[0] = a_Value.get("Line1", "").asString(); + m_Line[1] = a_Value.get("Line2", "").asString(); + m_Line[2] = a_Value.get("Line3", "").asString(); + m_Line[3] = a_Value.get("Line4", "").asString(); + + return true; +} + +void cSignEntity::SaveToJson( Json::Value & a_Value ) +{ + a_Value["x"] = m_PosX; + a_Value["y"] = m_PosY; + a_Value["z"] = m_PosZ; + + a_Value["Line1"] = m_Line[0]; + a_Value["Line2"] = m_Line[1]; + a_Value["Line3"] = m_Line[2]; + a_Value["Line4"] = m_Line[3]; +} + + + + diff --git a/source/cSignEntity.h b/source/cSignEntity.h index 3b633c8af..5f6e60889 100644 --- a/source/cSignEntity.h +++ b/source/cSignEntity.h @@ -1,45 +1,45 @@ - -#pragma once - -#include "cBlockEntity.h" - - - - - -namespace Json -{ - class Value; -} - - - - - -class cSignEntity : - public cBlockEntity -{ -public: - cSignEntity(ENUM_BLOCK_ID a_BlockType, int a_X, int a_Y, int a_Z, cWorld * a_World); - virtual ~cSignEntity(); - - bool LoadFromJson( const Json::Value& a_Value ); - virtual void SaveToJson(Json::Value& a_Value ) override; - - void SetLines( const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4 ); - void SetLine( int a_Index, const AString & a_Line ); - - AString GetLine( int a_Index ) const; - - virtual void UsedBy( cPlayer * a_Player ) override; - - virtual cPacket * GetPacket(void) override; - -private: - - AString m_Line[4]; -}; - - - - + +#pragma once + +#include "cBlockEntity.h" + + + + + +namespace Json +{ + class Value; +} + + + + + +class cSignEntity : + public cBlockEntity +{ +public: + cSignEntity(ENUM_BLOCK_ID a_BlockType, int a_X, int a_Y, int a_Z, cWorld * a_World); + virtual ~cSignEntity(); + + bool LoadFromJson( const Json::Value& a_Value ); + virtual void SaveToJson(Json::Value& a_Value ) override; + + void SetLines( const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4 ); + void SetLine( int a_Index, const AString & a_Line ); + + AString GetLine( int a_Index ) const; + + virtual void UsedBy( cPlayer * a_Player ) override; + + virtual cPacket * GetPacket(void) override; + +private: + + AString m_Line[4]; +}; + + + + diff --git a/source/cSilverfish.cpp b/source/cSilverfish.cpp index c08129181..7302934b6 100644 --- a/source/cSilverfish.cpp +++ b/source/cSilverfish.cpp @@ -1,25 +1,25 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cSilverfish.h" - - - - - -cSilverfish::cSilverfish() -{ - m_MobType = 60; - GetMonsterConfig("Silverfish"); -} - -cSilverfish::~cSilverfish() -{ -} - -bool cSilverfish::IsA( const char* a_EntityType ) -{ - if( strcmp( a_EntityType, "cSilverfish" ) == 0 ) return true; - return cMonster::IsA( a_EntityType ); -} - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSilverfish.h" + + + + + +cSilverfish::cSilverfish() +{ + m_MobType = 60; + GetMonsterConfig("Silverfish"); +} + +cSilverfish::~cSilverfish() +{ +} + +bool cSilverfish::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cSilverfish" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + diff --git a/source/cSilverfish.h b/source/cSilverfish.h index 0a949c7e3..1cdc89e62 100644 --- a/source/cSilverfish.h +++ b/source/cSilverfish.h @@ -1,12 +1,12 @@ -#pragma once - -#include "cAggressiveMonster.h" - -class cSilverfish : public cAggressiveMonster -{ -public: - cSilverfish(); - ~cSilverfish(); - - virtual bool IsA( const char* a_EntityType ); -}; +#pragma once + +#include "cAggressiveMonster.h" + +class cSilverfish : public cAggressiveMonster +{ +public: + cSilverfish(); + ~cSilverfish(); + + virtual bool IsA( const char* a_EntityType ); +}; diff --git a/source/cSimulator.cpp b/source/cSimulator.cpp index 92cc0823c..377d69eb3 100644 --- a/source/cSimulator.cpp +++ b/source/cSimulator.cpp @@ -1,33 +1,33 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cSimulator.h" -#include "cWorld.h" -#include "Vector3i.h" -#include "BlockID.h" -#include "Defines.h" - - - - - -cSimulator::cSimulator( cWorld* a_World ) - : m_World(a_World) -{ - -} - -cSimulator::~cSimulator() -{ -} - -void cSimulator::WakeUp( int a_X, int a_Y, int a_Z ) -{ - AddBlock( a_X, a_Y, a_Z ); - AddBlock( a_X-1, a_Y, a_Z ); - AddBlock( a_X+1, a_Y, a_Z ); - AddBlock( a_X, a_Y-1, a_Z ); - AddBlock( a_X, a_Y+1, a_Z ); - AddBlock( a_X, a_Y, a_Z-1 ); - AddBlock( a_X, a_Y, a_Z+1 ); -} + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSimulator.h" +#include "cWorld.h" +#include "Vector3i.h" +#include "BlockID.h" +#include "Defines.h" + + + + + +cSimulator::cSimulator( cWorld* a_World ) + : m_World(a_World) +{ + +} + +cSimulator::~cSimulator() +{ +} + +void cSimulator::WakeUp( int a_X, int a_Y, int a_Z ) +{ + AddBlock( a_X, a_Y, a_Z ); + AddBlock( a_X-1, a_Y, a_Z ); + AddBlock( a_X+1, a_Y, a_Z ); + AddBlock( a_X, a_Y-1, a_Z ); + AddBlock( a_X, a_Y+1, a_Z ); + AddBlock( a_X, a_Y, a_Z-1 ); + AddBlock( a_X, a_Y, a_Z+1 ); +} diff --git a/source/cSimulator.h b/source/cSimulator.h index 4e92ec152..158e74b99 100644 --- a/source/cSimulator.h +++ b/source/cSimulator.h @@ -1,20 +1,20 @@ -#pragma once - -class Vector3i; -class cWorld; -class cSimulator -{ -public: - cSimulator( cWorld* a_World ); - ~cSimulator(); - - virtual void Simulate( float a_Dt ) = 0; - virtual void WakeUp( int a_X, int a_Y, int a_Z ); - - virtual bool IsAllowedBlock( char a_BlockID ) = 0; - -protected: - virtual void AddBlock(int a_X, int a_Y, int a_Z) = 0; - - cWorld * m_World; +#pragma once + +class Vector3i; +class cWorld; +class cSimulator +{ +public: + cSimulator( cWorld* a_World ); + ~cSimulator(); + + virtual void Simulate( float a_Dt ) = 0; + virtual void WakeUp( int a_X, int a_Y, int a_Z ); + + virtual bool IsAllowedBlock( char a_BlockID ) = 0; + +protected: + virtual void AddBlock(int a_X, int a_Y, int a_Z) = 0; + + cWorld * m_World; }; \ No newline at end of file diff --git a/source/cSimulatorManager.cpp b/source/cSimulatorManager.cpp index 0663e5fe6..0d7ef356d 100644 --- a/source/cSimulatorManager.cpp +++ b/source/cSimulatorManager.cpp @@ -1,67 +1,67 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cSimulatorManager.h" - - - - - -cSimulatorManager::cSimulatorManager() -{ - -} - - - - - -cSimulatorManager::~cSimulatorManager() -{ - for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr ) - { - delete *itr; - } // for itr - m_Simulators[] -} - - - - - -void cSimulatorManager::Simulate( float a_Dt ) -{ - m_Ticks++; - for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr ) - { - if(m_Ticks % (*itr)->second == 0) - (*itr)->first->Simulate(a_Dt); - } -} - - - - - -void cSimulatorManager::WakeUp(int a_X, int a_Y, int a_Z) -{ - for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr ) - { - (*itr)->first->WakeUp(a_X, a_Y, a_Z); - } -} - - - - - -void cSimulatorManager::RegisterSimulator(cSimulator *a_Simulator, short a_Rate) -{ - //TODO needs some checking - std::pair *Pair = new std::pair(a_Simulator, a_Rate); - - m_Simulators.push_back(Pair); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSimulatorManager.h" + + + + + +cSimulatorManager::cSimulatorManager() +{ + +} + + + + + +cSimulatorManager::~cSimulatorManager() +{ + for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr ) + { + delete *itr; + } // for itr - m_Simulators[] +} + + + + + +void cSimulatorManager::Simulate( float a_Dt ) +{ + m_Ticks++; + for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr ) + { + if(m_Ticks % (*itr)->second == 0) + (*itr)->first->Simulate(a_Dt); + } +} + + + + + +void cSimulatorManager::WakeUp(int a_X, int a_Y, int a_Z) +{ + for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr ) + { + (*itr)->first->WakeUp(a_X, a_Y, a_Z); + } +} + + + + + +void cSimulatorManager::RegisterSimulator(cSimulator *a_Simulator, short a_Rate) +{ + //TODO needs some checking + std::pair *Pair = new std::pair(a_Simulator, a_Rate); + + m_Simulators.push_back(Pair); +} + + + + diff --git a/source/cSimulatorManager.h b/source/cSimulatorManager.h index 1168e5af8..ec8804992 100644 --- a/source/cSimulatorManager.h +++ b/source/cSimulatorManager.h @@ -1,39 +1,39 @@ - -// cSimulatorManager.h - - - - -#pragma once - - - - -#include "cSimulator.h" - - - - - -class cSimulatorManager -{ -public: - cSimulatorManager(); - ~cSimulatorManager(); - - void Simulate( float a_Dt ); - void WakeUp(int a_X, int a_Y, int a_Z); - - void RegisterSimulator(cSimulator * a_Simulator, short a_Rate); // Takes ownership of the simulator object! - -protected: - - typedef std::vector *> cSimulators; - - cSimulators m_Simulators; - long long m_Ticks; -}; - - - - + +// cSimulatorManager.h + + + + +#pragma once + + + + +#include "cSimulator.h" + + + + + +class cSimulatorManager +{ +public: + cSimulatorManager(); + ~cSimulatorManager(); + + void Simulate( float a_Dt ); + void WakeUp(int a_X, int a_Y, int a_Z); + + void RegisterSimulator(cSimulator * a_Simulator, short a_Rate); // Takes ownership of the simulator object! + +protected: + + typedef std::vector *> cSimulators; + + cSimulators m_Simulators; + long long m_Ticks; +}; + + + + diff --git a/source/cSkeleton.cpp b/source/cSkeleton.cpp index eb6ea1234..69ee55d23 100644 --- a/source/cSkeleton.cpp +++ b/source/cSkeleton.cpp @@ -1,65 +1,65 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cSkeleton.h" - - - - - -cSkeleton::cSkeleton() -{ - m_MobType = 51; - GetMonsterConfig("Skeleton"); -} - - - - - -cSkeleton::~cSkeleton() -{ -} - - - - - -bool cSkeleton::IsA( const char* a_EntityType ) -{ - if( strcmp( a_EntityType, "cSkeleton" ) == 0 ) return true; - return cMonster::IsA( a_EntityType ); -} - - - - - -void cSkeleton::Tick(float a_Dt) -{ - cMonster::Tick(a_Dt); - - //TODO Outsource - //TODO should do lightcheck, not daylight -> mobs in the dark don´t burn - if (GetWorld()->GetWorldTime() < (12000 + 1000) && GetMetaData() != BURNING ) { //if daylight - SetMetaData(BURNING); // BURN, BABY, BURN! >:D - } -} - - - - - -void cSkeleton::KilledBy( cEntity* a_Killer ) -{ - cItems Drops; - AddRandomDropItem(Drops, 0, 2, E_ITEM_ARROW); - AddRandomDropItem(Drops, 0, 2, E_ITEM_BONE); - m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); - - cMonster::KilledBy( a_Killer ); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSkeleton.h" + + + + + +cSkeleton::cSkeleton() +{ + m_MobType = 51; + GetMonsterConfig("Skeleton"); +} + + + + + +cSkeleton::~cSkeleton() +{ +} + + + + + +bool cSkeleton::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cSkeleton" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cSkeleton::Tick(float a_Dt) +{ + cMonster::Tick(a_Dt); + + //TODO Outsource + //TODO should do lightcheck, not daylight -> mobs in the dark don´t burn + if (GetWorld()->GetWorldTime() < (12000 + 1000) && GetMetaData() != BURNING ) { //if daylight + SetMetaData(BURNING); // BURN, BABY, BURN! >:D + } +} + + + + + +void cSkeleton::KilledBy( cEntity* a_Killer ) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_ARROW); + AddRandomDropItem(Drops, 0, 2, E_ITEM_BONE); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cSkeleton.h b/source/cSkeleton.h index ca7ed2fe3..78eeb731f 100644 --- a/source/cSkeleton.h +++ b/source/cSkeleton.h @@ -1,16 +1,16 @@ -#pragma once - -#include "cAggressiveMonster.h" - -class cSkeleton : public cAggressiveMonster -{ -public: - cSkeleton(); - ~cSkeleton(); - - virtual bool IsA( const char* a_EntityType ); - - virtual void Tick(float a_Dt); - virtual void KilledBy( cEntity* a_Killer ); - -}; +#pragma once + +#include "cAggressiveMonster.h" + +class cSkeleton : public cAggressiveMonster +{ +public: + cSkeleton(); + ~cSkeleton(); + + virtual bool IsA( const char* a_EntityType ); + + virtual void Tick(float a_Dt); + virtual void KilledBy( cEntity* a_Killer ); + +}; diff --git a/source/cSleep.cpp b/source/cSleep.cpp index 77da5dd58..70fb06b40 100644 --- a/source/cSleep.cpp +++ b/source/cSleep.cpp @@ -1,19 +1,19 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#ifndef _WIN32 - #include -#endif - - - - - -void cSleep::MilliSleep( unsigned int a_MilliSeconds ) -{ -#ifdef _WIN32 - Sleep(a_MilliSeconds); // Don't tick too much -#else - usleep(a_MilliSeconds*1000); -#endif -} + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#ifndef _WIN32 + #include +#endif + + + + + +void cSleep::MilliSleep( unsigned int a_MilliSeconds ) +{ +#ifdef _WIN32 + Sleep(a_MilliSeconds); // Don't tick too much +#else + usleep(a_MilliSeconds*1000); +#endif +} diff --git a/source/cSleep.h b/source/cSleep.h index 20ca7fc7d..5298c15da 100644 --- a/source/cSleep.h +++ b/source/cSleep.h @@ -1,7 +1,7 @@ -#pragma once - -class cSleep -{ -public: - static void MilliSleep( unsigned int a_MilliSeconds ); +#pragma once + +class cSleep +{ +public: + static void MilliSleep( unsigned int a_MilliSeconds ); }; \ No newline at end of file diff --git a/source/cSlime.cpp b/source/cSlime.cpp index 7cef1bb14..c314caae3 100644 --- a/source/cSlime.cpp +++ b/source/cSlime.cpp @@ -1,52 +1,52 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cSlime.h" - -//TODO Implement sized slimes - - - - - -cSlime::cSlime() -{ - m_MobType = 55; - GetMonsterConfig("Slime"); -} - - - - - -cSlime::~cSlime() -{ -} - - - - - -bool cSlime::IsA( const char* a_EntityType ) -{ - if( strcmp( a_EntityType, "cSlime" ) == 0 ) return true; - return cMonster::IsA( a_EntityType ); -} - - - - - -void cSlime::KilledBy( cEntity* a_Killer ) -{ - //TODO: only when tiny - cItems Drops; - AddRandomDropItem(Drops, 0, 2, E_ITEM_SLIMEBALL); - m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); - - cMonster::KilledBy( a_Killer ); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSlime.h" + +//TODO Implement sized slimes + + + + + +cSlime::cSlime() +{ + m_MobType = 55; + GetMonsterConfig("Slime"); +} + + + + + +cSlime::~cSlime() +{ +} + + + + + +bool cSlime::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cSlime" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cSlime::KilledBy( cEntity* a_Killer ) +{ + //TODO: only when tiny + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_SLIMEBALL); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cSlime.h b/source/cSlime.h index 26953cc73..e2e108516 100644 --- a/source/cSlime.h +++ b/source/cSlime.h @@ -1,14 +1,14 @@ -#pragma once - -#include "cAggressiveMonster.h" - -class cSlime : public cAggressiveMonster -{ -public: - cSlime(); - ~cSlime(); - - virtual bool IsA( const char* a_EntityType ); - - virtual void KilledBy( cEntity* a_Killer ); -}; +#pragma once + +#include "cAggressiveMonster.h" + +class cSlime : public cAggressiveMonster +{ +public: + cSlime(); + ~cSlime(); + + virtual bool IsA( const char* a_EntityType ); + + virtual void KilledBy( cEntity* a_Killer ); +}; diff --git a/source/cSocket.cpp b/source/cSocket.cpp index 7fc67e258..09cdfac1d 100644 --- a/source/cSocket.cpp +++ b/source/cSocket.cpp @@ -1,354 +1,354 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cSocket.h" -#include "packets/cPacket.h" - -#ifndef _WIN32 - #include - #include - #include //inet_ntoa() -#else - #define socklen_t int -#endif - - - - - -cSocket::cSocket(xSocket a_Socket) - : m_Socket(a_Socket) -{ -} - - - - - -cSocket::~cSocket() -{ - // Do NOT close the socket; this class is an API wrapper, not a RAII! -} - - - - - -cSocket::operator const cSocket::xSocket() const -{ - return m_Socket; -} - - - - - -cSocket::xSocket cSocket::GetSocket() const -{ - return m_Socket; -} - - - - - -bool cSocket::IsValid(void) const -{ - #ifdef _WIN32 - return (m_Socket != INVALID_SOCKET); - #else // _WIN32 - return (m_Socket >= 0); - #endif // else _WIN32 -} - - - - - -void cSocket::CloseSocket() -{ - #ifdef _WIN32 - - closesocket(m_Socket); - - #else // _WIN32 - - if (shutdown(m_Socket, SHUT_RDWR) != 0)//SD_BOTH); - { - LOGWARN("Error on shutting down socket (%s): %s", m_IPString.c_str(), GetLastErrorString().c_str()); - } - if (close(m_Socket) != 0) - { - LOGWARN("Error closing socket (%s): %s", m_IPString.c_str(), GetLastErrorString().c_str()); - } - - #endif // else _WIN32 - - // Invalidate the socket so that this object can be re-used for another connection - m_Socket = INVALID_SOCKET; -} - - - - - -AString cSocket::GetErrorString( int a_ErrNo ) -{ - char buffer[ 1024 ]; - AString Out; - - #ifdef _WIN32 - - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, a_ErrNo, 0, buffer, ARRAYCOUNT(buffer), NULL); - Printf(Out, "%d: %s", a_ErrNo, buffer); - if (!Out.empty() && (Out[Out.length() - 1] == '\n')) - { - Out.erase(Out.length() - 2); - } - return Out; - - #else // _WIN32 - - // According to http://linux.die.net/man/3/strerror_r there are two versions of strerror_r(): - - #if ( _GNU_SOURCE ) // GNU version of strerror_r() - - char * res = strerror_r( errno, buffer, ARRAYCOUNT(buffer) ); - if( res != NULL ) - { - Printf(Out, "%d: %s", a_ErrNo, res); - return Out; - } - - #else // XSI version of strerror_r(): - - int res = strerror_r( errno, buffer, ARRAYCOUNT(buffer) ); - if( res == 0 ) - { - Printf(Out, "%d: %s", a_ErrNo, buffer); - return Out; - } - - #endif // strerror_r() version - - else - { - Printf(Out, "Error %d while getting error string for error #%d!", errno, a_ErrNo); - return Out; - } - - #endif // else _WIN32 -} - - - - -int cSocket::GetLastError() -{ -#ifdef _WIN32 - return WSAGetLastError(); -#else - return errno; -#endif -} - - - - - -int cSocket::SetReuseAddress() -{ -#ifdef _WIN32 - char yes = 1; -#else - int yes = 1; -#endif - return setsockopt(m_Socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); -} - - - - - -int cSocket::WSAStartup() -{ -#ifdef _WIN32 - WSADATA wsaData; - memset(&wsaData, 0, sizeof(wsaData)); - return ::WSAStartup(MAKEWORD(2, 2),&wsaData); -#else - return 0; -#endif -} - - - - - -cSocket cSocket::CreateSocket() -{ - return socket(AF_INET,SOCK_STREAM,0); -} - - - - - -unsigned long cSocket::INTERNET_ADDRESS_LOCALHOST(void) -{ - static unsigned long LocalHost = 0; - if (LocalHost == 0) - { - LocalHost = inet_addr("127.0.0.1"); // GCC won't accept this as a global var assignment - } - return LocalHost; -} - - - - - -int cSocket::Bind(SockAddr_In& a_Address) -{ - sockaddr_in local; - memset(&local, 0, sizeof(local)); - - local.sin_family = a_Address.Family; - local.sin_addr.s_addr = a_Address.Address; - local.sin_port = htons((u_short)a_Address.Port); - - return bind(m_Socket, (sockaddr*)&local, sizeof(local)); -} - - - - - -int cSocket::Listen(int a_Backlog) -{ - return listen(m_Socket, a_Backlog); -} - - - - - -cSocket cSocket::Accept() -{ - sockaddr_in from; - socklen_t fromlen=sizeof(from); - - cSocket SClient = accept(m_Socket, (sockaddr*)&from, &fromlen); - - if (from.sin_addr.s_addr && SClient.IsValid()) // Get IP in string form - { - SClient.m_IPString = inet_ntoa(from.sin_addr); - //LOG("cSocket::Accept() %s", SClient.m_IPString); - } - - return SClient; -} - - - - - -int cSocket::Connect(SockAddr_In & a_Address) -{ - sockaddr_in local; - - local.sin_family = a_Address.Family; - local.sin_addr.s_addr = a_Address.Address; - local.sin_port = htons((u_short)a_Address.Port); - - return connect(m_Socket, (sockaddr *)&local, sizeof(local)); -} - - - - - -int cSocket::Connect(const AString & a_HostNameOrAddr, unsigned short a_Port) -{ - // First try IP Address string to hostent conversion, because it's faster - unsigned long addr = inet_addr(a_HostNameOrAddr.c_str()); - hostent * hp = gethostbyaddr((char*)&addr, sizeof(addr), AF_INET); - if (hp == NULL) - { - // It is not an IP Address string, but rather a regular hostname, resolve: - hp = gethostbyname(a_HostNameOrAddr.c_str()); - if (hp == NULL) - { - LOGWARN("cTCPLink: Could not resolve hostname \"%s\"", a_HostNameOrAddr.c_str()); - CloseSocket(); - return false; - } - } - - sockaddr_in server; - server.sin_addr.s_addr = *((unsigned long*)hp->h_addr); - server.sin_family = AF_INET; - server.sin_port = htons( (unsigned short)a_Port ); - return connect(m_Socket, (sockaddr *)&server, sizeof(server)); -} - - - - - -int cSocket::Receive(char* a_Buffer, unsigned int a_Length, unsigned int a_Flags) -{ - return recv(m_Socket, a_Buffer, a_Length, a_Flags); -} - - - - - -int cSocket::Send(const char * a_Buffer, unsigned int a_Length) -{ - return send(m_Socket, a_Buffer, a_Length, 0); -} - - - - - -int cSocket::Send(const cPacket * a_Packet) -{ - AString Serialized; - a_Packet->Serialize(Serialized); - return Send(Serialized.data(), Serialized.size()); -} - - - - - -int cSocket::Send(const cPacket & a_Packet) -{ - AString Serialized; - a_Packet.Serialize(Serialized); - return Send(Serialized.data(), Serialized.size()); -} - - - - - -unsigned short cSocket::GetPort(void) const -{ - ASSERT(IsValid()); - - sockaddr_in Addr; - socklen_t AddrSize = sizeof(Addr); - if (getsockname(m_Socket, (sockaddr *)&Addr, &AddrSize) != 0) - { - return 0; - } - return ntohs(Addr.sin_port); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSocket.h" +#include "packets/cPacket.h" + +#ifndef _WIN32 + #include + #include + #include //inet_ntoa() +#else + #define socklen_t int +#endif + + + + + +cSocket::cSocket(xSocket a_Socket) + : m_Socket(a_Socket) +{ +} + + + + + +cSocket::~cSocket() +{ + // Do NOT close the socket; this class is an API wrapper, not a RAII! +} + + + + + +cSocket::operator const cSocket::xSocket() const +{ + return m_Socket; +} + + + + + +cSocket::xSocket cSocket::GetSocket() const +{ + return m_Socket; +} + + + + + +bool cSocket::IsValid(void) const +{ + #ifdef _WIN32 + return (m_Socket != INVALID_SOCKET); + #else // _WIN32 + return (m_Socket >= 0); + #endif // else _WIN32 +} + + + + + +void cSocket::CloseSocket() +{ + #ifdef _WIN32 + + closesocket(m_Socket); + + #else // _WIN32 + + if (shutdown(m_Socket, SHUT_RDWR) != 0)//SD_BOTH); + { + LOGWARN("Error on shutting down socket (%s): %s", m_IPString.c_str(), GetLastErrorString().c_str()); + } + if (close(m_Socket) != 0) + { + LOGWARN("Error closing socket (%s): %s", m_IPString.c_str(), GetLastErrorString().c_str()); + } + + #endif // else _WIN32 + + // Invalidate the socket so that this object can be re-used for another connection + m_Socket = INVALID_SOCKET; +} + + + + + +AString cSocket::GetErrorString( int a_ErrNo ) +{ + char buffer[ 1024 ]; + AString Out; + + #ifdef _WIN32 + + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, a_ErrNo, 0, buffer, ARRAYCOUNT(buffer), NULL); + Printf(Out, "%d: %s", a_ErrNo, buffer); + if (!Out.empty() && (Out[Out.length() - 1] == '\n')) + { + Out.erase(Out.length() - 2); + } + return Out; + + #else // _WIN32 + + // According to http://linux.die.net/man/3/strerror_r there are two versions of strerror_r(): + + #if ( _GNU_SOURCE ) // GNU version of strerror_r() + + char * res = strerror_r( errno, buffer, ARRAYCOUNT(buffer) ); + if( res != NULL ) + { + Printf(Out, "%d: %s", a_ErrNo, res); + return Out; + } + + #else // XSI version of strerror_r(): + + int res = strerror_r( errno, buffer, ARRAYCOUNT(buffer) ); + if( res == 0 ) + { + Printf(Out, "%d: %s", a_ErrNo, buffer); + return Out; + } + + #endif // strerror_r() version + + else + { + Printf(Out, "Error %d while getting error string for error #%d!", errno, a_ErrNo); + return Out; + } + + #endif // else _WIN32 +} + + + + +int cSocket::GetLastError() +{ +#ifdef _WIN32 + return WSAGetLastError(); +#else + return errno; +#endif +} + + + + + +int cSocket::SetReuseAddress() +{ +#ifdef _WIN32 + char yes = 1; +#else + int yes = 1; +#endif + return setsockopt(m_Socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); +} + + + + + +int cSocket::WSAStartup() +{ +#ifdef _WIN32 + WSADATA wsaData; + memset(&wsaData, 0, sizeof(wsaData)); + return ::WSAStartup(MAKEWORD(2, 2),&wsaData); +#else + return 0; +#endif +} + + + + + +cSocket cSocket::CreateSocket() +{ + return socket(AF_INET,SOCK_STREAM,0); +} + + + + + +unsigned long cSocket::INTERNET_ADDRESS_LOCALHOST(void) +{ + static unsigned long LocalHost = 0; + if (LocalHost == 0) + { + LocalHost = inet_addr("127.0.0.1"); // GCC won't accept this as a global var assignment + } + return LocalHost; +} + + + + + +int cSocket::Bind(SockAddr_In& a_Address) +{ + sockaddr_in local; + memset(&local, 0, sizeof(local)); + + local.sin_family = a_Address.Family; + local.sin_addr.s_addr = a_Address.Address; + local.sin_port = htons((u_short)a_Address.Port); + + return bind(m_Socket, (sockaddr*)&local, sizeof(local)); +} + + + + + +int cSocket::Listen(int a_Backlog) +{ + return listen(m_Socket, a_Backlog); +} + + + + + +cSocket cSocket::Accept() +{ + sockaddr_in from; + socklen_t fromlen=sizeof(from); + + cSocket SClient = accept(m_Socket, (sockaddr*)&from, &fromlen); + + if (from.sin_addr.s_addr && SClient.IsValid()) // Get IP in string form + { + SClient.m_IPString = inet_ntoa(from.sin_addr); + //LOG("cSocket::Accept() %s", SClient.m_IPString); + } + + return SClient; +} + + + + + +int cSocket::Connect(SockAddr_In & a_Address) +{ + sockaddr_in local; + + local.sin_family = a_Address.Family; + local.sin_addr.s_addr = a_Address.Address; + local.sin_port = htons((u_short)a_Address.Port); + + return connect(m_Socket, (sockaddr *)&local, sizeof(local)); +} + + + + + +int cSocket::Connect(const AString & a_HostNameOrAddr, unsigned short a_Port) +{ + // First try IP Address string to hostent conversion, because it's faster + unsigned long addr = inet_addr(a_HostNameOrAddr.c_str()); + hostent * hp = gethostbyaddr((char*)&addr, sizeof(addr), AF_INET); + if (hp == NULL) + { + // It is not an IP Address string, but rather a regular hostname, resolve: + hp = gethostbyname(a_HostNameOrAddr.c_str()); + if (hp == NULL) + { + LOGWARN("cTCPLink: Could not resolve hostname \"%s\"", a_HostNameOrAddr.c_str()); + CloseSocket(); + return false; + } + } + + sockaddr_in server; + server.sin_addr.s_addr = *((unsigned long*)hp->h_addr); + server.sin_family = AF_INET; + server.sin_port = htons( (unsigned short)a_Port ); + return connect(m_Socket, (sockaddr *)&server, sizeof(server)); +} + + + + + +int cSocket::Receive(char* a_Buffer, unsigned int a_Length, unsigned int a_Flags) +{ + return recv(m_Socket, a_Buffer, a_Length, a_Flags); +} + + + + + +int cSocket::Send(const char * a_Buffer, unsigned int a_Length) +{ + return send(m_Socket, a_Buffer, a_Length, 0); +} + + + + + +int cSocket::Send(const cPacket * a_Packet) +{ + AString Serialized; + a_Packet->Serialize(Serialized); + return Send(Serialized.data(), Serialized.size()); +} + + + + + +int cSocket::Send(const cPacket & a_Packet) +{ + AString Serialized; + a_Packet.Serialize(Serialized); + return Send(Serialized.data(), Serialized.size()); +} + + + + + +unsigned short cSocket::GetPort(void) const +{ + ASSERT(IsValid()); + + sockaddr_in Addr; + socklen_t AddrSize = sizeof(Addr); + if (getsockname(m_Socket, (sockaddr *)&Addr, &AddrSize) != 0) + { + return 0; + } + return ntohs(Addr.sin_port); +} + + + + diff --git a/source/cSocket.h b/source/cSocket.h index 21a7cf3c2..0ed7b1a4e 100644 --- a/source/cSocket.h +++ b/source/cSocket.h @@ -1,87 +1,87 @@ - -#pragma once - - - - - -class cPacket; - - - - - -class cSocket -{ -public: -#ifdef _WIN32 - typedef SOCKET xSocket; -#else - typedef int xSocket; - static const int INVALID_SOCKET = -1; -#endif - - cSocket(void) : m_Socket(INVALID_SOCKET) {} - cSocket(xSocket a_Socket); - ~cSocket(); - - bool IsValid(void) const; - void CloseSocket(); - - operator const xSocket() const; - xSocket GetSocket() const; - - bool operator == (const cSocket & a_Other) {return m_Socket == a_Other.m_Socket; } - - void SetSocket( xSocket a_Socket ); - - int SetReuseAddress(); - static int WSAStartup(); - - static AString GetErrorString( int a_ErrNo ); - static int GetLastError(); - static AString GetLastErrorString(void) - { - return GetErrorString(GetLastError()); - } - - static cSocket CreateSocket(); - - inline static bool IsSocketError( int a_ReturnedValue ) - { -#ifdef _WIN32 - return (a_ReturnedValue == SOCKET_ERROR || a_ReturnedValue == 0); -#else - return (a_ReturnedValue <= 0); -#endif - } - - struct SockAddr_In - { - short Family; - unsigned short Port; - unsigned long Address; - }; - - static const short ADDRESS_FAMILY_INTERNET = 2; - static const unsigned long INTERNET_ADDRESS_ANY = 0; - static unsigned long INTERNET_ADDRESS_LOCALHOST(void); // 127.0.0.1 represented in network byteorder; must be a function due to GCC :( - - int Bind( SockAddr_In& a_Address ); - int Listen( int a_Backlog ); - cSocket Accept(); - int Connect(SockAddr_In & a_Address); // Returns 0 on success, !0 on failure - int Connect(const AString & a_HostNameOrAddr, unsigned short a_Port); // Returns 0 on success, !0 on failure - int Receive( char* a_Buffer, unsigned int a_Length, unsigned int a_Flags ); - int Send (const char * a_Buffer, unsigned int a_Length); - int Send (const cPacket * a_Packet); // Sends the packet, doesn't handle partial sends - int Send (const cPacket & a_Packet); // Sends the packet, doesn't handle partial sends - - unsigned short GetPort(void) const; // Returns 0 on failure - - const AString & GetIPString(void) const { return m_IPString; } - -private: - xSocket m_Socket; - AString m_IPString; + +#pragma once + + + + + +class cPacket; + + + + + +class cSocket +{ +public: +#ifdef _WIN32 + typedef SOCKET xSocket; +#else + typedef int xSocket; + static const int INVALID_SOCKET = -1; +#endif + + cSocket(void) : m_Socket(INVALID_SOCKET) {} + cSocket(xSocket a_Socket); + ~cSocket(); + + bool IsValid(void) const; + void CloseSocket(); + + operator const xSocket() const; + xSocket GetSocket() const; + + bool operator == (const cSocket & a_Other) {return m_Socket == a_Other.m_Socket; } + + void SetSocket( xSocket a_Socket ); + + int SetReuseAddress(); + static int WSAStartup(); + + static AString GetErrorString( int a_ErrNo ); + static int GetLastError(); + static AString GetLastErrorString(void) + { + return GetErrorString(GetLastError()); + } + + static cSocket CreateSocket(); + + inline static bool IsSocketError( int a_ReturnedValue ) + { +#ifdef _WIN32 + return (a_ReturnedValue == SOCKET_ERROR || a_ReturnedValue == 0); +#else + return (a_ReturnedValue <= 0); +#endif + } + + struct SockAddr_In + { + short Family; + unsigned short Port; + unsigned long Address; + }; + + static const short ADDRESS_FAMILY_INTERNET = 2; + static const unsigned long INTERNET_ADDRESS_ANY = 0; + static unsigned long INTERNET_ADDRESS_LOCALHOST(void); // 127.0.0.1 represented in network byteorder; must be a function due to GCC :( + + int Bind( SockAddr_In& a_Address ); + int Listen( int a_Backlog ); + cSocket Accept(); + int Connect(SockAddr_In & a_Address); // Returns 0 on success, !0 on failure + int Connect(const AString & a_HostNameOrAddr, unsigned short a_Port); // Returns 0 on success, !0 on failure + int Receive( char* a_Buffer, unsigned int a_Length, unsigned int a_Flags ); + int Send (const char * a_Buffer, unsigned int a_Length); + int Send (const cPacket * a_Packet); // Sends the packet, doesn't handle partial sends + int Send (const cPacket & a_Packet); // Sends the packet, doesn't handle partial sends + + unsigned short GetPort(void) const; // Returns 0 on failure + + const AString & GetIPString(void) const { return m_IPString; } + +private: + xSocket m_Socket; + AString m_IPString; }; \ No newline at end of file diff --git a/source/cSocketThreads.cpp b/source/cSocketThreads.cpp index fbef2a2c3..b27523972 100644 --- a/source/cSocketThreads.cpp +++ b/source/cSocketThreads.cpp @@ -1,715 +1,715 @@ - -// cSocketThreads.cpp - -// Implements the cSocketThreads class representing the heart of MCS's client networking. -// This object takes care of network communication, groups sockets into threads and uses as little threads as possible for full read / write support -// For more detail, see http://forum.mc-server.org/showthread.php?tid=327 - -#include "Globals.h" -#include "cSocketThreads.h" -#include "cClientHandle.h" -// #include "packets/cPacket_RelativeEntityMoveLook.h" - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cSocketThreads: - -cSocketThreads::cSocketThreads(void) -{ - LOG("cSocketThreads startup"); -} - - - - - -cSocketThreads::~cSocketThreads() -{ - for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) - { - delete *itr; - } // for itr - m_Threads[] - m_Threads.clear(); -} - - - - - - -bool cSocketThreads::AddClient(cSocket * a_Socket, cCallback * a_Client) -{ - // Add a (socket, client) pair for processing, data from a_Socket is to be sent to a_Client - - // Try to add to existing threads: - cCSLock Lock(m_CS); - for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) - { - if ((*itr)->IsValid() && (*itr)->HasEmptySlot()) - { - (*itr)->AddClient(a_Socket, a_Client); - return true; - } - } - - // No thread has free space, create a new one: - LOG("Creating a new cSocketThread (currently have %d)", m_Threads.size()); - cSocketThread * Thread = new cSocketThread(this); - if (!Thread->Start()) - { - // There was an error launching the thread (but it was already logged along with the reason) - LOGERROR("A new cSocketThread failed to start"); - delete Thread; - return false; - } - Thread->AddClient(a_Socket, a_Client); - m_Threads.push_back(Thread); - return true; -} - - - - - -void cSocketThreads::RemoveClient(const cSocket * a_Socket) -{ - // Remove the socket (and associated client) from processing - - cCSLock Lock(m_CS); - for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) - { - if ((*itr)->RemoveSocket(a_Socket)) - { - return; - } - } // for itr - m_Threads[] - - // Cannot assert here, this may actually happen legally, since cClientHandle has to clean up the socket and it may have already closed in the meantime - // ASSERT(!"Removing an unknown socket"); -} - - - - - -void cSocketThreads::RemoveClient(const cCallback * a_Client) -{ - // Remove the associated socket and the client from processing - - cCSLock Lock(m_CS); - for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) - { - if ((*itr)->RemoveClient(a_Client)) - { - return; - } - } // for itr - m_Threads[] - - ASSERT(!"Removing an unknown client"); -} - - - - - -void cSocketThreads::NotifyWrite(const cCallback * a_Client) -{ - // Notifies the thread responsible for a_Client that the client has something to write - - cCSLock Lock(m_CS); - for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) - { - if ((*itr)->NotifyWrite(a_Client)) - { - return; - } - } // for itr - m_Threads[] - - // Cannot assert - this normally happens if a client disconnects and has pending packets, the cServer::cNotifyWriteThread will call this on invalid clients too - // ASSERT(!"Notifying write to an unknown client"); -} - - - - - -void cSocketThreads::Write(const cSocket * a_Socket, const AString & a_Data) -{ - // Puts a_Data into outgoing data queue for a_Socket - - if (!a_Socket->IsValid()) - { - // Socket already closed, ignore the request - return; - } - - cCSLock Lock(m_CS); - for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) - { - if ((*itr)->Write(a_Socket, a_Data)) - { - return; - } - } // for itr - m_Threads[] - - // This may be perfectly legal, if the socket has been destroyed and the client is finishing up - // ASSERT(!"Writing to an unknown socket"); -} - - - - - -/// Stops reading from the socket - when this call returns, no more calls to the callbacks are made -void cSocketThreads::StopReading(const cCallback * a_Client) -{ - cCSLock Lock(m_CS); - for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) - { - if ((*itr)->StopReading(a_Client)) - { - return; - } - } // for itr - m_Threads[] - - // Cannot assert, this normally happens if the socket is closed before the client deinitializes - // ASSERT(!"Stopping reading on an unknown client"); -} - - - - - -/// Queues the socket for closing, as soon as its outgoing data is sent -void cSocketThreads::QueueClose(const cSocket * a_Socket) -{ - if (!a_Socket->IsValid()) - { - // Already closed, ignore the request - return; - } - - cCSLock Lock(m_CS); - for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) - { - if ((*itr)->QueueClose(a_Socket)) - { - return; - } - } // for itr - m_Threads[] - - ASSERT(!"Queueing close of an unknown socket"); -} - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cSocketThreads::cSocketThread: - -cSocketThreads::cSocketThread::cSocketThread(cSocketThreads * a_Parent) : - cIsThread("cSocketThread"), - m_Parent(a_Parent), - m_NumSlots(0) -{ - // Nothing needed yet -} - - - - - -cSocketThreads::cSocketThread::~cSocketThread() -{ - m_ShouldTerminate = true; - - // Notify the thread: - ASSERT(m_ControlSocket2.IsValid()); - m_ControlSocket2.Send("a", 1); - - // Wait for the thread to finish: - Wait(); - - // Close the control sockets: - m_ControlSocket1.CloseSocket(); - m_ControlSocket2.CloseSocket(); -} - - - - - -void cSocketThreads::cSocketThread::AddClient(cSocket * a_Socket, cCallback * a_Client) -{ - ASSERT(m_NumSlots < MAX_SLOTS); // Use HasEmptySlot() to check before adding - - m_Slots[m_NumSlots].m_Client = a_Client; - m_Slots[m_NumSlots].m_Socket = a_Socket; - m_Slots[m_NumSlots].m_Outgoing.clear(); - m_NumSlots++; - - // Notify the thread of the change: - ASSERT(m_ControlSocket2.IsValid()); - m_ControlSocket2.Send("a", 1); -} - - - - - -bool cSocketThreads::cSocketThread::RemoveClient(const cCallback * a_Client) -{ - // Returns true if removed, false if not found - - if (m_NumSlots == 0) - { - return false; - } - - for (int i = m_NumSlots - 1; i >= 0 ; --i) - { - if (m_Slots[i].m_Client != a_Client) - { - continue; - } - - // Found, remove it: - m_Slots[i] = m_Slots[--m_NumSlots]; - - // Notify the thread of the change: - ASSERT(m_ControlSocket2.IsValid()); - m_ControlSocket2.Send("r", 1); - return true; - } // for i - m_Slots[] - - // Not found - return false; -} - - - - - -bool cSocketThreads::cSocketThread::RemoveSocket(const cSocket * a_Socket) -{ - // Returns true if removed, false if not found - - for (int i = m_NumSlots - 1; i >= 0 ; --i) - { - if (m_Slots[i].m_Socket != a_Socket) - { - continue; - } - - // Found, remove it: - m_Slots[i] = m_Slots[--m_NumSlots]; - - // Notify the thread of the change: - ASSERT(m_ControlSocket2.IsValid()); - m_ControlSocket2.Send("r", 1); - return true; - } // for i - m_Slots[] - - // Not found - return false; -} - - - - - -bool cSocketThreads::cSocketThread::HasClient(const cCallback * a_Client) const -{ - for (int i = m_NumSlots - 1; i >= 0; --i) - { - if (m_Slots[i].m_Client == a_Client) - { - return true; - } - } // for i - m_Slots[] - return false; -} - - - - - -bool cSocketThreads::cSocketThread::HasSocket(const cSocket * a_Socket) const -{ - for (int i = m_NumSlots - 1; i >= 0; --i) - { - if (m_Slots[i].m_Socket->GetSocket() == a_Socket->GetSocket()) - { - return true; - } - } // for i - m_Slots[] - return false; -} - - - - - -bool cSocketThreads::cSocketThread::NotifyWrite(const cCallback * a_Client) -{ - if (HasClient(a_Client)) - { - // Notify the thread that there's another packet in the queue: - ASSERT(m_ControlSocket2.IsValid()); - m_ControlSocket2.Send("q", 1); - return true; - } - return false; -} - - - - - -bool cSocketThreads::cSocketThread::Write(const cSocket * a_Socket, const AString & a_Data) -{ - // Returns true if socket handled by this thread - for (int i = m_NumSlots - 1; i >= 0; --i) - { - if (m_Slots[i].m_Socket == a_Socket) - { - m_Slots[i].m_Outgoing.append(a_Data); - - // Notify the thread that there's data in the queue: - ASSERT(m_ControlSocket2.IsValid()); - m_ControlSocket2.Send("q", 1); - - return true; - } - } // for i - m_Slots[] - return false; -} - - - - - -bool cSocketThreads::cSocketThread::StopReading (const cCallback * a_Client) -{ - // Returns true if client handled by this thread - for (int i = m_NumSlots - 1; i >= 0; --i) - { - if (m_Slots[i].m_Client == a_Client) - { - m_Slots[i].m_Client = NULL; - m_Slots[i].m_ShouldClose = false; - - // Notify the thread that there's a stop reading request: - ASSERT(m_ControlSocket2.IsValid()); - m_ControlSocket2.Send("s", 1); - - return true; - } - } // for i - m_Slots[] - return false; -} - - - - - -bool cSocketThreads::cSocketThread::QueueClose(const cSocket * a_Socket) -{ - // Returns true if socket handled by this thread - for (int i = m_NumSlots - 1; i >= 0; --i) - { - if (m_Slots[i].m_Socket == a_Socket) - { - ASSERT(m_Slots[i].m_Client == NULL); // Should have stopped reading first - m_Slots[i].m_ShouldClose = true; - - // Notify the thread that there's a close queued (in case its conditions are already met): - ASSERT(m_ControlSocket2.IsValid()); - m_ControlSocket2.Send("c", 1); - - return true; - } - } // for i - m_Slots[] - return false; -} - - - - - -bool cSocketThreads::cSocketThread::Start(void) -{ - // Create the control socket listener - m_ControlSocket2 = cSocket::CreateSocket(); - if (!m_ControlSocket2.IsValid()) - { - LOGERROR("Cannot create a Control socket for a cSocketThread (\"%s\"); continuing, but server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); - return false; - } - cSocket::SockAddr_In Addr; - Addr.Family = cSocket::ADDRESS_FAMILY_INTERNET; - Addr.Address = cSocket::INTERNET_ADDRESS_LOCALHOST(); - Addr.Port = 0; // Any free port is okay - if (m_ControlSocket2.Bind(Addr) != 0) - { - LOGERROR("Cannot bind a Control socket for a cSocketThread (\"%s\"); continuing, but server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); - m_ControlSocket2.CloseSocket(); - return false; - } - if (m_ControlSocket2.Listen(1) != 0) - { - LOGERROR("Cannot listen on a Control socket for a cSocketThread (\"%s\"); continuing, but server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); - m_ControlSocket2.CloseSocket(); - return false; - } - if (m_ControlSocket2.GetPort() == 0) - { - LOGERROR("Cannot determine Control socket port (\"%s\"); conitnuing, but the server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); - m_ControlSocket2.CloseSocket(); - return false; - } - - // Start the thread - if (!super::Start()) - { - LOGERROR("Cannot start new cSocketThread"); - m_ControlSocket2.CloseSocket(); - return false; - } - - // Finish connecting the control socket by accepting connection from the thread's socket - cSocket tmp = m_ControlSocket2.Accept(); - if (!tmp.IsValid()) - { - LOGERROR("Cannot link Control sockets for a cSocketThread (\"%s\"); continuing, but server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); - m_ControlSocket2.CloseSocket(); - return false; - } - m_ControlSocket2.CloseSocket(); - m_ControlSocket2 = tmp; - - return true; -} - - - - - -void cSocketThreads::cSocketThread::Execute(void) -{ - // Connect the "client" part of the Control socket: - m_ControlSocket1 = cSocket::CreateSocket(); - cSocket::SockAddr_In Addr; - Addr.Family = cSocket::ADDRESS_FAMILY_INTERNET; - Addr.Address = cSocket::INTERNET_ADDRESS_LOCALHOST(); - Addr.Port = m_ControlSocket2.GetPort(); - ASSERT(Addr.Port != 0); // We checked in the Start() method, but let's be sure - if (m_ControlSocket1.Connect(Addr) != 0) - { - LOGERROR("Cannot connect Control sockets for a cSocketThread (\"%s\"); continuing, but the server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); - m_ControlSocket2.CloseSocket(); - return; - } - - // The main thread loop: - while (!m_ShouldTerminate) - { - // Put all sockets into the Read set: - fd_set fdRead; - cSocket::xSocket Highest = m_ControlSocket1.GetSocket(); - - PrepareSet(&fdRead, Highest); - - // Wait for the sockets: - if (select(Highest + 1, &fdRead, NULL, NULL, NULL) == -1) - { - LOG("select(R) call failed in cSocketThread: \"%s\"", cSocket::GetLastErrorString().c_str()); - continue; - } - - ReadFromSockets(&fdRead); - - // Test sockets for writing: - fd_set fdWrite; - Highest = m_ControlSocket1.GetSocket(); - PrepareSet(&fdWrite, Highest); - timeval Timeout; - Timeout.tv_sec = 0; - Timeout.tv_usec = 0; - if (select(Highest + 1, NULL, &fdWrite, NULL, &Timeout) == -1) - { - LOG("select(W) call failed in cSocketThread: \"%s\"", cSocket::GetLastErrorString().c_str()); - continue; - } - - WriteToSockets(&fdWrite); - - RemoveClosedSockets(); - } // while (!mShouldTerminate) -} - - - - - -void cSocketThreads::cSocketThread::PrepareSet(fd_set * a_Set, cSocket::xSocket & a_Highest) -{ - FD_ZERO(a_Set); - FD_SET(m_ControlSocket1.GetSocket(), a_Set); - - cCSLock Lock(m_Parent->m_CS); - for (int i = m_NumSlots - 1; i >= 0; --i) - { - if (!m_Slots[i].m_Socket->IsValid()) - { - continue; - } - cSocket::xSocket s = m_Slots[i].m_Socket->GetSocket(); - FD_SET(s, a_Set); - if (s > a_Highest) - { - a_Highest = s; - } - } // for i - m_Slots[] -} - - - - - -void cSocketThreads::cSocketThread::ReadFromSockets(fd_set * a_Read) -{ - // Read on available sockets: - - // Reset Control socket state: - if (FD_ISSET(m_ControlSocket1.GetSocket(), a_Read)) - { - char Dummy[128]; - m_ControlSocket1.Receive(Dummy, sizeof(Dummy), 0); - } - - // Read from clients: - cCSLock Lock(m_Parent->m_CS); - for (int i = m_NumSlots - 1; i >= 0; --i) - { - if (!FD_ISSET(m_Slots[i].m_Socket->GetSocket(), a_Read)) - { - continue; - } - char Buffer[1024]; - int Received = m_Slots[i].m_Socket->Receive(Buffer, ARRAYCOUNT(Buffer), 0); - if (Received == 0) - { - // The socket has been closed by the remote party, close our socket and let it be removed after we process all reading - m_Slots[i].m_Socket->CloseSocket(); - if (m_Slots[i].m_Client != NULL) - { - m_Slots[i].m_Client->SocketClosed(); - } - } - else if (Received > 0) - { - if (m_Slots[i].m_Client != NULL) - { - m_Slots[i].m_Client->DataReceived(Buffer, Received); - } - } - else - { - // The socket has encountered an error, close it and let it be removed after we process all reading - m_Slots[i].m_Socket->CloseSocket(); - if (m_Slots[i].m_Client != NULL) - { - m_Slots[i].m_Client->SocketClosed(); - } - } - } // for i - m_Slots[] -} - - - - - -void cSocketThreads::cSocketThread::WriteToSockets(fd_set * a_Write) -{ - // Write to available client sockets: - cCSLock Lock(m_Parent->m_CS); - for (int i = m_NumSlots - 1; i >= 0; --i) - { - if (!FD_ISSET(m_Slots[i].m_Socket->GetSocket(), a_Write)) - { - continue; - } - if (m_Slots[i].m_Outgoing.empty()) - { - // Request another chunk of outgoing data: - if (m_Slots[i].m_Client != NULL) - { - m_Slots[i].m_Client->GetOutgoingData(m_Slots[i].m_Outgoing); - } - if (m_Slots[i].m_Outgoing.empty()) - { - // Nothing ready - if ((m_Slots[i].m_Client == NULL) && m_Slots[i].m_ShouldClose) - { - // Socket was queued for closing and there's no more data to send, close it now: - m_Slots[i].m_Socket->CloseSocket(); - m_Slots[i] = m_Slots[--m_NumSlots]; - } - continue; - } - } // if (outgoing data is empty) - - int Sent = m_Slots[i].m_Socket->Send(m_Slots[i].m_Outgoing.data(), m_Slots[i].m_Outgoing.size()); - if (Sent < 0) - { - int Err = cSocket::GetLastError(); - LOGWARNING("Error %d while writing to client \"%s\", disconnecting. \"%s\"", Err, m_Slots[i].m_Socket->GetIPString().c_str(), cSocket::GetErrorString(Err).c_str()); - m_Slots[i].m_Socket->CloseSocket(); - if (m_Slots[i].m_Client != NULL) - { - m_Slots[i].m_Client->SocketClosed(); - } - return; - } - m_Slots[i].m_Outgoing.erase(0, Sent); - - // _X: If there's data left, it means the client is not reading fast enough, the server would unnecessarily spin in the main loop with zero actions taken; so signalling is disabled - // This means that if there's data left, it will be sent only when there's incoming data or someone queues another packet (for any socket handled by this thread) - /* - // If there's any data left, signalize the Control socket: - if (!m_Slots[i].m_Outgoing.empty()) - { - ASSERT(m_ControlSocket2.IsValid()); - m_ControlSocket2.Send("q", 1); - } - */ - } // for i - m_Slots[i] -} - - - - - -void cSocketThreads::cSocketThread::RemoveClosedSockets(void) -{ - // Removes sockets that have closed from m_Slots[] - - cCSLock Lock(m_Parent->m_CS); - for (int i = m_NumSlots - 1; i >= 0; --i) - { - if (m_Slots[i].m_Socket->IsValid()) - { - continue; - } - m_Slots[i] = m_Slots[--m_NumSlots]; - } // for i - m_Slots[] -} - - - - + +// cSocketThreads.cpp + +// Implements the cSocketThreads class representing the heart of MCS's client networking. +// This object takes care of network communication, groups sockets into threads and uses as little threads as possible for full read / write support +// For more detail, see http://forum.mc-server.org/showthread.php?tid=327 + +#include "Globals.h" +#include "cSocketThreads.h" +#include "cClientHandle.h" +// #include "packets/cPacket_RelativeEntityMoveLook.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cSocketThreads: + +cSocketThreads::cSocketThreads(void) +{ + LOG("cSocketThreads startup"); +} + + + + + +cSocketThreads::~cSocketThreads() +{ + for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) + { + delete *itr; + } // for itr - m_Threads[] + m_Threads.clear(); +} + + + + + + +bool cSocketThreads::AddClient(cSocket * a_Socket, cCallback * a_Client) +{ + // Add a (socket, client) pair for processing, data from a_Socket is to be sent to a_Client + + // Try to add to existing threads: + cCSLock Lock(m_CS); + for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) + { + if ((*itr)->IsValid() && (*itr)->HasEmptySlot()) + { + (*itr)->AddClient(a_Socket, a_Client); + return true; + } + } + + // No thread has free space, create a new one: + LOG("Creating a new cSocketThread (currently have %d)", m_Threads.size()); + cSocketThread * Thread = new cSocketThread(this); + if (!Thread->Start()) + { + // There was an error launching the thread (but it was already logged along with the reason) + LOGERROR("A new cSocketThread failed to start"); + delete Thread; + return false; + } + Thread->AddClient(a_Socket, a_Client); + m_Threads.push_back(Thread); + return true; +} + + + + + +void cSocketThreads::RemoveClient(const cSocket * a_Socket) +{ + // Remove the socket (and associated client) from processing + + cCSLock Lock(m_CS); + for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) + { + if ((*itr)->RemoveSocket(a_Socket)) + { + return; + } + } // for itr - m_Threads[] + + // Cannot assert here, this may actually happen legally, since cClientHandle has to clean up the socket and it may have already closed in the meantime + // ASSERT(!"Removing an unknown socket"); +} + + + + + +void cSocketThreads::RemoveClient(const cCallback * a_Client) +{ + // Remove the associated socket and the client from processing + + cCSLock Lock(m_CS); + for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) + { + if ((*itr)->RemoveClient(a_Client)) + { + return; + } + } // for itr - m_Threads[] + + ASSERT(!"Removing an unknown client"); +} + + + + + +void cSocketThreads::NotifyWrite(const cCallback * a_Client) +{ + // Notifies the thread responsible for a_Client that the client has something to write + + cCSLock Lock(m_CS); + for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) + { + if ((*itr)->NotifyWrite(a_Client)) + { + return; + } + } // for itr - m_Threads[] + + // Cannot assert - this normally happens if a client disconnects and has pending packets, the cServer::cNotifyWriteThread will call this on invalid clients too + // ASSERT(!"Notifying write to an unknown client"); +} + + + + + +void cSocketThreads::Write(const cSocket * a_Socket, const AString & a_Data) +{ + // Puts a_Data into outgoing data queue for a_Socket + + if (!a_Socket->IsValid()) + { + // Socket already closed, ignore the request + return; + } + + cCSLock Lock(m_CS); + for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) + { + if ((*itr)->Write(a_Socket, a_Data)) + { + return; + } + } // for itr - m_Threads[] + + // This may be perfectly legal, if the socket has been destroyed and the client is finishing up + // ASSERT(!"Writing to an unknown socket"); +} + + + + + +/// Stops reading from the socket - when this call returns, no more calls to the callbacks are made +void cSocketThreads::StopReading(const cCallback * a_Client) +{ + cCSLock Lock(m_CS); + for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) + { + if ((*itr)->StopReading(a_Client)) + { + return; + } + } // for itr - m_Threads[] + + // Cannot assert, this normally happens if the socket is closed before the client deinitializes + // ASSERT(!"Stopping reading on an unknown client"); +} + + + + + +/// Queues the socket for closing, as soon as its outgoing data is sent +void cSocketThreads::QueueClose(const cSocket * a_Socket) +{ + if (!a_Socket->IsValid()) + { + // Already closed, ignore the request + return; + } + + cCSLock Lock(m_CS); + for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) + { + if ((*itr)->QueueClose(a_Socket)) + { + return; + } + } // for itr - m_Threads[] + + ASSERT(!"Queueing close of an unknown socket"); +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cSocketThreads::cSocketThread: + +cSocketThreads::cSocketThread::cSocketThread(cSocketThreads * a_Parent) : + cIsThread("cSocketThread"), + m_Parent(a_Parent), + m_NumSlots(0) +{ + // Nothing needed yet +} + + + + + +cSocketThreads::cSocketThread::~cSocketThread() +{ + m_ShouldTerminate = true; + + // Notify the thread: + ASSERT(m_ControlSocket2.IsValid()); + m_ControlSocket2.Send("a", 1); + + // Wait for the thread to finish: + Wait(); + + // Close the control sockets: + m_ControlSocket1.CloseSocket(); + m_ControlSocket2.CloseSocket(); +} + + + + + +void cSocketThreads::cSocketThread::AddClient(cSocket * a_Socket, cCallback * a_Client) +{ + ASSERT(m_NumSlots < MAX_SLOTS); // Use HasEmptySlot() to check before adding + + m_Slots[m_NumSlots].m_Client = a_Client; + m_Slots[m_NumSlots].m_Socket = a_Socket; + m_Slots[m_NumSlots].m_Outgoing.clear(); + m_NumSlots++; + + // Notify the thread of the change: + ASSERT(m_ControlSocket2.IsValid()); + m_ControlSocket2.Send("a", 1); +} + + + + + +bool cSocketThreads::cSocketThread::RemoveClient(const cCallback * a_Client) +{ + // Returns true if removed, false if not found + + if (m_NumSlots == 0) + { + return false; + } + + for (int i = m_NumSlots - 1; i >= 0 ; --i) + { + if (m_Slots[i].m_Client != a_Client) + { + continue; + } + + // Found, remove it: + m_Slots[i] = m_Slots[--m_NumSlots]; + + // Notify the thread of the change: + ASSERT(m_ControlSocket2.IsValid()); + m_ControlSocket2.Send("r", 1); + return true; + } // for i - m_Slots[] + + // Not found + return false; +} + + + + + +bool cSocketThreads::cSocketThread::RemoveSocket(const cSocket * a_Socket) +{ + // Returns true if removed, false if not found + + for (int i = m_NumSlots - 1; i >= 0 ; --i) + { + if (m_Slots[i].m_Socket != a_Socket) + { + continue; + } + + // Found, remove it: + m_Slots[i] = m_Slots[--m_NumSlots]; + + // Notify the thread of the change: + ASSERT(m_ControlSocket2.IsValid()); + m_ControlSocket2.Send("r", 1); + return true; + } // for i - m_Slots[] + + // Not found + return false; +} + + + + + +bool cSocketThreads::cSocketThread::HasClient(const cCallback * a_Client) const +{ + for (int i = m_NumSlots - 1; i >= 0; --i) + { + if (m_Slots[i].m_Client == a_Client) + { + return true; + } + } // for i - m_Slots[] + return false; +} + + + + + +bool cSocketThreads::cSocketThread::HasSocket(const cSocket * a_Socket) const +{ + for (int i = m_NumSlots - 1; i >= 0; --i) + { + if (m_Slots[i].m_Socket->GetSocket() == a_Socket->GetSocket()) + { + return true; + } + } // for i - m_Slots[] + return false; +} + + + + + +bool cSocketThreads::cSocketThread::NotifyWrite(const cCallback * a_Client) +{ + if (HasClient(a_Client)) + { + // Notify the thread that there's another packet in the queue: + ASSERT(m_ControlSocket2.IsValid()); + m_ControlSocket2.Send("q", 1); + return true; + } + return false; +} + + + + + +bool cSocketThreads::cSocketThread::Write(const cSocket * a_Socket, const AString & a_Data) +{ + // Returns true if socket handled by this thread + for (int i = m_NumSlots - 1; i >= 0; --i) + { + if (m_Slots[i].m_Socket == a_Socket) + { + m_Slots[i].m_Outgoing.append(a_Data); + + // Notify the thread that there's data in the queue: + ASSERT(m_ControlSocket2.IsValid()); + m_ControlSocket2.Send("q", 1); + + return true; + } + } // for i - m_Slots[] + return false; +} + + + + + +bool cSocketThreads::cSocketThread::StopReading (const cCallback * a_Client) +{ + // Returns true if client handled by this thread + for (int i = m_NumSlots - 1; i >= 0; --i) + { + if (m_Slots[i].m_Client == a_Client) + { + m_Slots[i].m_Client = NULL; + m_Slots[i].m_ShouldClose = false; + + // Notify the thread that there's a stop reading request: + ASSERT(m_ControlSocket2.IsValid()); + m_ControlSocket2.Send("s", 1); + + return true; + } + } // for i - m_Slots[] + return false; +} + + + + + +bool cSocketThreads::cSocketThread::QueueClose(const cSocket * a_Socket) +{ + // Returns true if socket handled by this thread + for (int i = m_NumSlots - 1; i >= 0; --i) + { + if (m_Slots[i].m_Socket == a_Socket) + { + ASSERT(m_Slots[i].m_Client == NULL); // Should have stopped reading first + m_Slots[i].m_ShouldClose = true; + + // Notify the thread that there's a close queued (in case its conditions are already met): + ASSERT(m_ControlSocket2.IsValid()); + m_ControlSocket2.Send("c", 1); + + return true; + } + } // for i - m_Slots[] + return false; +} + + + + + +bool cSocketThreads::cSocketThread::Start(void) +{ + // Create the control socket listener + m_ControlSocket2 = cSocket::CreateSocket(); + if (!m_ControlSocket2.IsValid()) + { + LOGERROR("Cannot create a Control socket for a cSocketThread (\"%s\"); continuing, but server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); + return false; + } + cSocket::SockAddr_In Addr; + Addr.Family = cSocket::ADDRESS_FAMILY_INTERNET; + Addr.Address = cSocket::INTERNET_ADDRESS_LOCALHOST(); + Addr.Port = 0; // Any free port is okay + if (m_ControlSocket2.Bind(Addr) != 0) + { + LOGERROR("Cannot bind a Control socket for a cSocketThread (\"%s\"); continuing, but server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); + m_ControlSocket2.CloseSocket(); + return false; + } + if (m_ControlSocket2.Listen(1) != 0) + { + LOGERROR("Cannot listen on a Control socket for a cSocketThread (\"%s\"); continuing, but server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); + m_ControlSocket2.CloseSocket(); + return false; + } + if (m_ControlSocket2.GetPort() == 0) + { + LOGERROR("Cannot determine Control socket port (\"%s\"); conitnuing, but the server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); + m_ControlSocket2.CloseSocket(); + return false; + } + + // Start the thread + if (!super::Start()) + { + LOGERROR("Cannot start new cSocketThread"); + m_ControlSocket2.CloseSocket(); + return false; + } + + // Finish connecting the control socket by accepting connection from the thread's socket + cSocket tmp = m_ControlSocket2.Accept(); + if (!tmp.IsValid()) + { + LOGERROR("Cannot link Control sockets for a cSocketThread (\"%s\"); continuing, but server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); + m_ControlSocket2.CloseSocket(); + return false; + } + m_ControlSocket2.CloseSocket(); + m_ControlSocket2 = tmp; + + return true; +} + + + + + +void cSocketThreads::cSocketThread::Execute(void) +{ + // Connect the "client" part of the Control socket: + m_ControlSocket1 = cSocket::CreateSocket(); + cSocket::SockAddr_In Addr; + Addr.Family = cSocket::ADDRESS_FAMILY_INTERNET; + Addr.Address = cSocket::INTERNET_ADDRESS_LOCALHOST(); + Addr.Port = m_ControlSocket2.GetPort(); + ASSERT(Addr.Port != 0); // We checked in the Start() method, but let's be sure + if (m_ControlSocket1.Connect(Addr) != 0) + { + LOGERROR("Cannot connect Control sockets for a cSocketThread (\"%s\"); continuing, but the server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); + m_ControlSocket2.CloseSocket(); + return; + } + + // The main thread loop: + while (!m_ShouldTerminate) + { + // Put all sockets into the Read set: + fd_set fdRead; + cSocket::xSocket Highest = m_ControlSocket1.GetSocket(); + + PrepareSet(&fdRead, Highest); + + // Wait for the sockets: + if (select(Highest + 1, &fdRead, NULL, NULL, NULL) == -1) + { + LOG("select(R) call failed in cSocketThread: \"%s\"", cSocket::GetLastErrorString().c_str()); + continue; + } + + ReadFromSockets(&fdRead); + + // Test sockets for writing: + fd_set fdWrite; + Highest = m_ControlSocket1.GetSocket(); + PrepareSet(&fdWrite, Highest); + timeval Timeout; + Timeout.tv_sec = 0; + Timeout.tv_usec = 0; + if (select(Highest + 1, NULL, &fdWrite, NULL, &Timeout) == -1) + { + LOG("select(W) call failed in cSocketThread: \"%s\"", cSocket::GetLastErrorString().c_str()); + continue; + } + + WriteToSockets(&fdWrite); + + RemoveClosedSockets(); + } // while (!mShouldTerminate) +} + + + + + +void cSocketThreads::cSocketThread::PrepareSet(fd_set * a_Set, cSocket::xSocket & a_Highest) +{ + FD_ZERO(a_Set); + FD_SET(m_ControlSocket1.GetSocket(), a_Set); + + cCSLock Lock(m_Parent->m_CS); + for (int i = m_NumSlots - 1; i >= 0; --i) + { + if (!m_Slots[i].m_Socket->IsValid()) + { + continue; + } + cSocket::xSocket s = m_Slots[i].m_Socket->GetSocket(); + FD_SET(s, a_Set); + if (s > a_Highest) + { + a_Highest = s; + } + } // for i - m_Slots[] +} + + + + + +void cSocketThreads::cSocketThread::ReadFromSockets(fd_set * a_Read) +{ + // Read on available sockets: + + // Reset Control socket state: + if (FD_ISSET(m_ControlSocket1.GetSocket(), a_Read)) + { + char Dummy[128]; + m_ControlSocket1.Receive(Dummy, sizeof(Dummy), 0); + } + + // Read from clients: + cCSLock Lock(m_Parent->m_CS); + for (int i = m_NumSlots - 1; i >= 0; --i) + { + if (!FD_ISSET(m_Slots[i].m_Socket->GetSocket(), a_Read)) + { + continue; + } + char Buffer[1024]; + int Received = m_Slots[i].m_Socket->Receive(Buffer, ARRAYCOUNT(Buffer), 0); + if (Received == 0) + { + // The socket has been closed by the remote party, close our socket and let it be removed after we process all reading + m_Slots[i].m_Socket->CloseSocket(); + if (m_Slots[i].m_Client != NULL) + { + m_Slots[i].m_Client->SocketClosed(); + } + } + else if (Received > 0) + { + if (m_Slots[i].m_Client != NULL) + { + m_Slots[i].m_Client->DataReceived(Buffer, Received); + } + } + else + { + // The socket has encountered an error, close it and let it be removed after we process all reading + m_Slots[i].m_Socket->CloseSocket(); + if (m_Slots[i].m_Client != NULL) + { + m_Slots[i].m_Client->SocketClosed(); + } + } + } // for i - m_Slots[] +} + + + + + +void cSocketThreads::cSocketThread::WriteToSockets(fd_set * a_Write) +{ + // Write to available client sockets: + cCSLock Lock(m_Parent->m_CS); + for (int i = m_NumSlots - 1; i >= 0; --i) + { + if (!FD_ISSET(m_Slots[i].m_Socket->GetSocket(), a_Write)) + { + continue; + } + if (m_Slots[i].m_Outgoing.empty()) + { + // Request another chunk of outgoing data: + if (m_Slots[i].m_Client != NULL) + { + m_Slots[i].m_Client->GetOutgoingData(m_Slots[i].m_Outgoing); + } + if (m_Slots[i].m_Outgoing.empty()) + { + // Nothing ready + if ((m_Slots[i].m_Client == NULL) && m_Slots[i].m_ShouldClose) + { + // Socket was queued for closing and there's no more data to send, close it now: + m_Slots[i].m_Socket->CloseSocket(); + m_Slots[i] = m_Slots[--m_NumSlots]; + } + continue; + } + } // if (outgoing data is empty) + + int Sent = m_Slots[i].m_Socket->Send(m_Slots[i].m_Outgoing.data(), m_Slots[i].m_Outgoing.size()); + if (Sent < 0) + { + int Err = cSocket::GetLastError(); + LOGWARNING("Error %d while writing to client \"%s\", disconnecting. \"%s\"", Err, m_Slots[i].m_Socket->GetIPString().c_str(), cSocket::GetErrorString(Err).c_str()); + m_Slots[i].m_Socket->CloseSocket(); + if (m_Slots[i].m_Client != NULL) + { + m_Slots[i].m_Client->SocketClosed(); + } + return; + } + m_Slots[i].m_Outgoing.erase(0, Sent); + + // _X: If there's data left, it means the client is not reading fast enough, the server would unnecessarily spin in the main loop with zero actions taken; so signalling is disabled + // This means that if there's data left, it will be sent only when there's incoming data or someone queues another packet (for any socket handled by this thread) + /* + // If there's any data left, signalize the Control socket: + if (!m_Slots[i].m_Outgoing.empty()) + { + ASSERT(m_ControlSocket2.IsValid()); + m_ControlSocket2.Send("q", 1); + } + */ + } // for i - m_Slots[i] +} + + + + + +void cSocketThreads::cSocketThread::RemoveClosedSockets(void) +{ + // Removes sockets that have closed from m_Slots[] + + cCSLock Lock(m_Parent->m_CS); + for (int i = m_NumSlots - 1; i >= 0; --i) + { + if (m_Slots[i].m_Socket->IsValid()) + { + continue; + } + m_Slots[i] = m_Slots[--m_NumSlots]; + } // for i - m_Slots[] +} + + + + diff --git a/source/cSocketThreads.h b/source/cSocketThreads.h index a8174a115..b13ecf02d 100644 --- a/source/cSocketThreads.h +++ b/source/cSocketThreads.h @@ -1,174 +1,174 @@ - -// cSocketThreads.h - -// Interfaces to the cSocketThreads class representing the heart of MCS's client networking. -// This object takes care of network communication, groups sockets into threads and uses as little threads as possible for full read / write support -// For more detail, see http://forum.mc-server.org/showthread.php?tid=327 - -/* -Additional details: -When a client is terminating a connection: -- they call the StopReading() method to disable callbacks for the incoming data -- they call the Write() method to queue any outstanding outgoing data -- they call the QueueClose() method to queue the socket to close after outgoing data has been sent. -When a socket slot is marked as having no callback, it is kept alive until its outgoing data queue is empty and its m_ShouldClose flag is set. -This means that the socket can be written to several times before finally closing it via QueueClose() -*/ - - - - - -/// How many clients should one thread handle? (must be less than FD_SETSIZE - 1 for your platform) -#define MAX_SLOTS 63 - - - - - -#pragma once -#ifndef CSOCKETTHREADS_H_INCLUDED -#define CSOCKETTHREADS_H_INCLUDED - -#include "packets/cPacket.h" -#include "cIsThread.h" - - - - -// Check MAX_SLOTS: -#if MAX_SLOTS >= FD_SETSIZE - #error "MAX_SLOTS must be less than FD_SETSIZE - 1 for your platform! (otherwise select() won't work)" -#endif - - - - - -// fwd: -class cSocket; -class cClientHandle; - - - - - -class cSocketThreads -{ -public: - - // Clients of cSocketThreads must implement this interface to be able to communicate - class cCallback - { - public: - /// Called when data is received from the remote party - virtual void DataReceived(const char * a_Data, int a_Size) = 0; - - /// Called when data can be sent to remote party; the function is supposed to append outgoing data to a_Data - virtual void GetOutgoingData(AString & a_Data) = 0; - - /// Called when the socket has been closed for any reason - virtual void SocketClosed(void) = 0; - } ; - - - cSocketThreads(void); - ~cSocketThreads(); - - /// Add a (socket, client) pair for processing, data from a_Socket is to be sent to a_Client; returns true if successful - bool AddClient(cSocket * a_Socket, cCallback * a_Client); - - /// Remove the socket (and associated client) from processing - void RemoveClient(const cSocket * a_Socket); - - /// Remove the associated socket and the client from processing - void RemoveClient(const cCallback * a_Client); - - /// Notify the thread responsible for a_Client that the client has something to write - void NotifyWrite(const cCallback * a_Client); - - /// Puts a_Data into outgoing data queue for a_Socket - void Write(const cSocket * a_Socket, const AString & a_Data); - - /// Stops reading from the socket - when this call returns, no more calls to the callbacks are made - void StopReading(const cCallback * a_Client); - - /// Queues the socket for closing, as soon as its outgoing data is sent - void QueueClose(const cSocket * a_Socket); - -private: - - class cSocketThread : - public cIsThread - { - typedef cIsThread super; - - public: - - cSocketThread(cSocketThreads * a_Parent); - ~cSocketThread(); - - // All these methods assume parent's m_CS is locked - bool HasEmptySlot(void) const {return m_NumSlots < MAX_SLOTS; } - bool IsEmpty (void) const {return m_NumSlots == 0; } - - void AddClient (cSocket * a_Socket, cCallback * a_Client); - bool RemoveClient(const cCallback * a_Client); // Returns true if removed, false if not found - bool RemoveSocket(const cSocket * a_Socket); // Returns true if removed, false if not found - bool HasClient (const cCallback * a_Client) const; - bool HasSocket (const cSocket * a_Socket) const; - bool NotifyWrite (const cCallback * a_Client); // Returns true if client handled by this thread - bool Write (const cSocket * a_Socket, const AString & a_Data); // Returns true if socket handled by this thread - bool StopReading (const cCallback * a_Client); // Returns true if client handled by this thread - bool QueueClose (const cSocket * a_Socket); // Returns true if socket handled by this thread - - bool Start(void); // Hide the cIsThread's Start method, we need to provide our own startup to create the control socket - - bool IsValid(void) const {return m_ControlSocket2.IsValid(); } // If the Control socket dies, the thread is not valid anymore - - private: - - cSocketThreads * m_Parent; - - // Two ends of the control socket, the first is select()-ed, the second is written to for notifications - cSocket m_ControlSocket1; - cSocket m_ControlSocket2; - - // Socket-client-packetqueues triplets. - // Manipulation with these assumes that the parent's m_CS is locked - struct sSlot - { - cSocket * m_Socket; - cCallback * m_Client; - AString m_Outgoing; // If sending writes only partial data, the rest is stored here for another send - bool m_ShouldClose; // If true, the socket is to be closed after sending all outgoing data - } ; - sSlot m_Slots[MAX_SLOTS]; - int m_NumSlots; // Number of slots actually used - - virtual void Execute(void) override; - - void AddOrUpdatePacket(int a_Slot, cPacket * a_Packet); // Adds the packet to the specified slot, or updates an existing packet in that queue (EntityMoveLook filtering) - - void PrepareSet (fd_set * a_Set, cSocket::xSocket & a_Highest); // Puts all sockets into the set, along with m_ControlSocket1 - void ReadFromSockets(fd_set * a_Read); // Reads from sockets indicated in a_Read - void WriteToSockets (fd_set * a_Write); // Writes to sockets indicated in a_Write - void RemoveClosedSockets(void); // Removes sockets that have closed from m_Slots[] - } ; - - typedef std::list cSocketThreadList; - - - cCriticalSection m_CS; - cSocketThreadList m_Threads; -} ; - - - - - -#endif // CSOCKETTHREADS_H_INCLUDED - - - - + +// cSocketThreads.h + +// Interfaces to the cSocketThreads class representing the heart of MCS's client networking. +// This object takes care of network communication, groups sockets into threads and uses as little threads as possible for full read / write support +// For more detail, see http://forum.mc-server.org/showthread.php?tid=327 + +/* +Additional details: +When a client is terminating a connection: +- they call the StopReading() method to disable callbacks for the incoming data +- they call the Write() method to queue any outstanding outgoing data +- they call the QueueClose() method to queue the socket to close after outgoing data has been sent. +When a socket slot is marked as having no callback, it is kept alive until its outgoing data queue is empty and its m_ShouldClose flag is set. +This means that the socket can be written to several times before finally closing it via QueueClose() +*/ + + + + + +/// How many clients should one thread handle? (must be less than FD_SETSIZE - 1 for your platform) +#define MAX_SLOTS 63 + + + + + +#pragma once +#ifndef CSOCKETTHREADS_H_INCLUDED +#define CSOCKETTHREADS_H_INCLUDED + +#include "packets/cPacket.h" +#include "cIsThread.h" + + + + +// Check MAX_SLOTS: +#if MAX_SLOTS >= FD_SETSIZE + #error "MAX_SLOTS must be less than FD_SETSIZE - 1 for your platform! (otherwise select() won't work)" +#endif + + + + + +// fwd: +class cSocket; +class cClientHandle; + + + + + +class cSocketThreads +{ +public: + + // Clients of cSocketThreads must implement this interface to be able to communicate + class cCallback + { + public: + /// Called when data is received from the remote party + virtual void DataReceived(const char * a_Data, int a_Size) = 0; + + /// Called when data can be sent to remote party; the function is supposed to append outgoing data to a_Data + virtual void GetOutgoingData(AString & a_Data) = 0; + + /// Called when the socket has been closed for any reason + virtual void SocketClosed(void) = 0; + } ; + + + cSocketThreads(void); + ~cSocketThreads(); + + /// Add a (socket, client) pair for processing, data from a_Socket is to be sent to a_Client; returns true if successful + bool AddClient(cSocket * a_Socket, cCallback * a_Client); + + /// Remove the socket (and associated client) from processing + void RemoveClient(const cSocket * a_Socket); + + /// Remove the associated socket and the client from processing + void RemoveClient(const cCallback * a_Client); + + /// Notify the thread responsible for a_Client that the client has something to write + void NotifyWrite(const cCallback * a_Client); + + /// Puts a_Data into outgoing data queue for a_Socket + void Write(const cSocket * a_Socket, const AString & a_Data); + + /// Stops reading from the socket - when this call returns, no more calls to the callbacks are made + void StopReading(const cCallback * a_Client); + + /// Queues the socket for closing, as soon as its outgoing data is sent + void QueueClose(const cSocket * a_Socket); + +private: + + class cSocketThread : + public cIsThread + { + typedef cIsThread super; + + public: + + cSocketThread(cSocketThreads * a_Parent); + ~cSocketThread(); + + // All these methods assume parent's m_CS is locked + bool HasEmptySlot(void) const {return m_NumSlots < MAX_SLOTS; } + bool IsEmpty (void) const {return m_NumSlots == 0; } + + void AddClient (cSocket * a_Socket, cCallback * a_Client); + bool RemoveClient(const cCallback * a_Client); // Returns true if removed, false if not found + bool RemoveSocket(const cSocket * a_Socket); // Returns true if removed, false if not found + bool HasClient (const cCallback * a_Client) const; + bool HasSocket (const cSocket * a_Socket) const; + bool NotifyWrite (const cCallback * a_Client); // Returns true if client handled by this thread + bool Write (const cSocket * a_Socket, const AString & a_Data); // Returns true if socket handled by this thread + bool StopReading (const cCallback * a_Client); // Returns true if client handled by this thread + bool QueueClose (const cSocket * a_Socket); // Returns true if socket handled by this thread + + bool Start(void); // Hide the cIsThread's Start method, we need to provide our own startup to create the control socket + + bool IsValid(void) const {return m_ControlSocket2.IsValid(); } // If the Control socket dies, the thread is not valid anymore + + private: + + cSocketThreads * m_Parent; + + // Two ends of the control socket, the first is select()-ed, the second is written to for notifications + cSocket m_ControlSocket1; + cSocket m_ControlSocket2; + + // Socket-client-packetqueues triplets. + // Manipulation with these assumes that the parent's m_CS is locked + struct sSlot + { + cSocket * m_Socket; + cCallback * m_Client; + AString m_Outgoing; // If sending writes only partial data, the rest is stored here for another send + bool m_ShouldClose; // If true, the socket is to be closed after sending all outgoing data + } ; + sSlot m_Slots[MAX_SLOTS]; + int m_NumSlots; // Number of slots actually used + + virtual void Execute(void) override; + + void AddOrUpdatePacket(int a_Slot, cPacket * a_Packet); // Adds the packet to the specified slot, or updates an existing packet in that queue (EntityMoveLook filtering) + + void PrepareSet (fd_set * a_Set, cSocket::xSocket & a_Highest); // Puts all sockets into the set, along with m_ControlSocket1 + void ReadFromSockets(fd_set * a_Read); // Reads from sockets indicated in a_Read + void WriteToSockets (fd_set * a_Write); // Writes to sockets indicated in a_Write + void RemoveClosedSockets(void); // Removes sockets that have closed from m_Slots[] + } ; + + typedef std::list cSocketThreadList; + + + cCriticalSection m_CS; + cSocketThreadList m_Threads; +} ; + + + + + +#endif // CSOCKETTHREADS_H_INCLUDED + + + + diff --git a/source/cSpider.cpp b/source/cSpider.cpp index 47f4e2750..516a941d4 100644 --- a/source/cSpider.cpp +++ b/source/cSpider.cpp @@ -1,50 +1,50 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cSpider.h" - - - - - -cSpider::cSpider() -{ - m_MobType = 52; - GetMonsterConfig("Spider"); -} - - - - - -cSpider::~cSpider() -{ -} - - - - - -bool cSpider::IsA( const char* a_EntityType ) -{ - if( strcmp( a_EntityType, "cSpider" ) == 0 ) return true; - return cMonster::IsA( a_EntityType ); -} - - - - - -void cSpider::KilledBy( cEntity* a_Killer ) -{ - cItems Drops; - AddRandomDropItem(Drops, 0, 2, E_ITEM_STRING); - AddRandomDropItem(Drops, 0, 1, E_ITEM_SPIDER_EYE); - m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); - - cMonster::KilledBy( a_Killer ); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSpider.h" + + + + + +cSpider::cSpider() +{ + m_MobType = 52; + GetMonsterConfig("Spider"); +} + + + + + +cSpider::~cSpider() +{ +} + + + + + +bool cSpider::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cSpider" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cSpider::KilledBy( cEntity* a_Killer ) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_STRING); + AddRandomDropItem(Drops, 0, 1, E_ITEM_SPIDER_EYE); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cSpider.h b/source/cSpider.h index 7ffc818e4..ea7d4ba4f 100644 --- a/source/cSpider.h +++ b/source/cSpider.h @@ -1,14 +1,14 @@ -#pragma once - -#include "cAggressiveMonster.h" - -class cSpider : public cAggressiveMonster -{ -public: - cSpider(); - ~cSpider(); - - virtual bool IsA( const char* a_EntityType ); - - virtual void KilledBy( cEntity* a_Killer ); -}; +#pragma once + +#include "cAggressiveMonster.h" + +class cSpider : public cAggressiveMonster +{ +public: + cSpider(); + ~cSpider(); + + virtual bool IsA( const char* a_EntityType ); + + virtual void KilledBy( cEntity* a_Killer ); +}; diff --git a/source/cSquid.cpp b/source/cSquid.cpp index 52c0cbf30..735df1be0 100644 --- a/source/cSquid.cpp +++ b/source/cSquid.cpp @@ -1,60 +1,60 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cSquid.h" -#include "Vector3d.h" - - - - - -cSquid::cSquid() -{ - m_MobType = 94; - GetMonsterConfig("Squid"); - m_NoWater = 0.f; -} - -cSquid::~cSquid() -{ - -} - -bool cSquid::IsA( const char* a_EntityType ) -{ - if( strcmp( a_EntityType, "cSquid" ) == 0 ) return true; - return cMonster::IsA( a_EntityType ); -} - - - - - -void cSquid::KilledBy( cEntity* a_Killer ) -{ - // Drops 0-3 Ink Sacs - cItems Drops; - AddRandomDropItem(Drops, 0, 3, E_ITEM_DYE, E_META_DYE_BLACK); - m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); - - cMonster::KilledBy( a_Killer ); -} - - - - - -void cSquid::Tick(float a_Dt) -{ - cPassiveMonster::Tick(a_Dt); - - Vector3d Pos = GetPosition(); - - - //TODO Not a real behavior, but cool :D - if(!IsBlockWater(GetWorld()->GetBlock((int) Pos.x, (int) Pos.y, (int) Pos.z)) && GetMetaData() != BURNING) - { - SetMetaData(BURNING); - } - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSquid.h" +#include "Vector3d.h" + + + + + +cSquid::cSquid() +{ + m_MobType = 94; + GetMonsterConfig("Squid"); + m_NoWater = 0.f; +} + +cSquid::~cSquid() +{ + +} + +bool cSquid::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cSquid" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cSquid::KilledBy( cEntity* a_Killer ) +{ + // Drops 0-3 Ink Sacs + cItems Drops; + AddRandomDropItem(Drops, 0, 3, E_ITEM_DYE, E_META_DYE_BLACK); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + cMonster::KilledBy( a_Killer ); +} + + + + + +void cSquid::Tick(float a_Dt) +{ + cPassiveMonster::Tick(a_Dt); + + Vector3d Pos = GetPosition(); + + + //TODO Not a real behavior, but cool :D + if(!IsBlockWater(GetWorld()->GetBlock((int) Pos.x, (int) Pos.y, (int) Pos.z)) && GetMetaData() != BURNING) + { + SetMetaData(BURNING); + } + } \ No newline at end of file diff --git a/source/cSquid.h b/source/cSquid.h index 069172efd..93b82d0eb 100644 --- a/source/cSquid.h +++ b/source/cSquid.h @@ -1,18 +1,18 @@ -#pragma once - -#include "cPassiveMonster.h" - -class cSquid : public cPassiveMonster -{ -public: - cSquid(); - ~cSquid(); - - virtual void Tick(float a_Dt); - - virtual bool IsA( const char* a_EntityType ); - virtual void KilledBy( cEntity* a_Killer ); - -protected: - float m_NoWater; -}; +#pragma once + +#include "cPassiveMonster.h" + +class cSquid : public cPassiveMonster +{ +public: + cSquid(); + ~cSquid(); + + virtual void Tick(float a_Dt); + + virtual bool IsA( const char* a_EntityType ); + virtual void KilledBy( cEntity* a_Killer ); + +protected: + float m_NoWater; +}; diff --git a/source/cStairs.h b/source/cStairs.h index 01fe7017a..d796dc56d 100644 --- a/source/cStairs.h +++ b/source/cStairs.h @@ -1,28 +1,28 @@ -#pragma once - -class cStairs //tolua_export -{ //tolua_export -public: - static char RotationToMetaData( float a_Rotation, int a_Direction ) //tolua_export - { //tolua_export - a_Rotation += 90 + 45; // So its not aligned with axis - int result = 0x0; - if( a_Direction == 0) - { - - result = 0x4; - } - - if( a_Rotation > 360.f ) a_Rotation -= 360.f; - if( a_Rotation >= 0.f && a_Rotation < 90.f ) - return result; - else if( a_Rotation >= 180 && a_Rotation < 270 ) - result += 0x1; - else if( a_Rotation >= 90 && a_Rotation < 180 ) - result += 0x2; - else - result += 0x3; - - return result; - } //tolua_export -}; //tolua_export +#pragma once + +class cStairs //tolua_export +{ //tolua_export +public: + static char RotationToMetaData( float a_Rotation, int a_Direction ) //tolua_export + { //tolua_export + a_Rotation += 90 + 45; // So its not aligned with axis + int result = 0x0; + if( a_Direction == 0) + { + + result = 0x4; + } + + if( a_Rotation > 360.f ) a_Rotation -= 360.f; + if( a_Rotation >= 0.f && a_Rotation < 90.f ) + return result; + else if( a_Rotation >= 180 && a_Rotation < 270 ) + result += 0x1; + else if( a_Rotation >= 90 && a_Rotation < 180 ) + result += 0x2; + else + result += 0x3; + + return result; + } //tolua_export +}; //tolua_export diff --git a/source/cStep.h b/source/cStep.h index 122a09191..9fe0131ed 100644 --- a/source/cStep.h +++ b/source/cStep.h @@ -1,15 +1,15 @@ -#pragma once - -class cStep //tolua_export -{ //tolua_export -public: - static char DirectionToMetaData( int a_Direction ) //tolua_export - { //tolua_export - int result = 0x0; - if( a_Direction == 0) - { - result = 0x8; - } - return result; - } //tolua_export -}; //tolua_export +#pragma once + +class cStep //tolua_export +{ //tolua_export +public: + static char DirectionToMetaData( int a_Direction ) //tolua_export + { //tolua_export + int result = 0x0; + if( a_Direction == 0) + { + result = 0x8; + } + return result; + } //tolua_export +}; //tolua_export diff --git a/source/cStringMap.cpp b/source/cStringMap.cpp index 7907efc34..26b9cf5fe 100644 --- a/source/cStringMap.cpp +++ b/source/cStringMap.cpp @@ -1,23 +1,23 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cStringMap.h" - - - - - -unsigned int cStringMap::size() const -{ - return m_StringMap.size(); -} - -void cStringMap::clear() -{ - m_StringMap.clear(); -} - -std::string & cStringMap::get( const std::string & index ) -{ - return m_StringMap[index]; + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cStringMap.h" + + + + + +unsigned int cStringMap::size() const +{ + return m_StringMap.size(); +} + +void cStringMap::clear() +{ + m_StringMap.clear(); +} + +std::string & cStringMap::get( const std::string & index ) +{ + return m_StringMap[index]; } \ No newline at end of file diff --git a/source/cStringMap.h b/source/cStringMap.h index e6b61c171..1cf20048d 100644 --- a/source/cStringMap.h +++ b/source/cStringMap.h @@ -1,29 +1,29 @@ - -// A std::map interface for Lua - -#pragma once - -#include "tolua++.h" - - - - - -class cStringMap // tolua_export -{ // tolua_export -public: // tolua_export - cStringMap(std::map< std::string, std::string > a_StringMap) : m_StringMap( a_StringMap ) {} - void clear(); // tolua_export - - unsigned int size() const; // tolua_export - - std::string & get( const std::string & index ); //tolua_export - - std::map< std::string, std::string >& GetStringMap() { return m_StringMap; } -private: - std::map< std::string, std::string > m_StringMap; -}; // tolua_export - - - - + +// A std::map interface for Lua + +#pragma once + +#include "tolua++.h" + + + + + +class cStringMap // tolua_export +{ // tolua_export +public: // tolua_export + cStringMap(std::map< std::string, std::string > a_StringMap) : m_StringMap( a_StringMap ) {} + void clear(); // tolua_export + + unsigned int size() const; // tolua_export + + std::string & get( const std::string & index ); //tolua_export + + std::map< std::string, std::string >& GetStringMap() { return m_StringMap; } +private: + std::map< std::string, std::string > m_StringMap; +}; // tolua_export + + + + diff --git a/source/cSurvivalInventory.cpp b/source/cSurvivalInventory.cpp index 4a573572d..5ed91cf70 100644 --- a/source/cSurvivalInventory.cpp +++ b/source/cSurvivalInventory.cpp @@ -1,95 +1,95 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cSurvivalInventory.h" -#include "cPlayer.h" -#include "cClientHandle.h" -#include "cWindow.h" -#include "cItem.h" -#include "CraftingRecipes.h" -#include "cRoot.h" -#include "packets/cPacket_WindowClick.h" - - - - - -cSurvivalInventory::~cSurvivalInventory() -{ - -} - -cSurvivalInventory::cSurvivalInventory(cPlayer* a_Owner) - : cInventory(a_Owner) -{ - -} - -void cSurvivalInventory::Clicked( cPacket* a_ClickPacket ) -{ - cPacket_WindowClick *Packet = reinterpret_cast(a_ClickPacket); - bool bDontCook = false; - if( GetWindow() ) - { - // Override for craft result slot - if( Packet->m_SlotNum == (short)c_CraftOffset ) - { - LOG("In craft slot: %i x %i !!", m_Slots[c_CraftOffset].m_ItemID, m_Slots[c_CraftOffset].m_ItemCount ); - cItem* DraggingItem = GetWindow()->GetDraggingItem(); - if( DraggingItem->IsEmpty() ) - { - *DraggingItem = m_Slots[c_CraftOffset]; - m_Slots[c_CraftOffset].Empty(); - } - else if( DraggingItem->Equals( m_Slots[c_CraftOffset] ) ) - { - if( DraggingItem->m_ItemCount + m_Slots[c_CraftOffset].m_ItemCount <= 64 ) - { - DraggingItem->m_ItemCount += m_Slots[c_CraftOffset].m_ItemCount; - m_Slots[0].Empty(); - } - else - { - bDontCook = true; - } - } - else - { - bDontCook = true; - } - LOG("Dragging Dish %i", DraggingItem->m_ItemCount ); - } - else - { - GetWindow()->Clicked( Packet, *m_Owner ); - } - } - else - { - LOG("No Inventory window! WTF"); - } - - if ((Packet->m_SlotNum >= (short)c_CraftOffset) && (Packet->m_SlotNum < (short)(c_CraftOffset + c_CraftSlots + 1))) - { - cCraftingGrid Grid(m_Slots + c_CraftOffset + 1, 2, 2); - cCraftingRecipe Recipe(Grid); - - cRoot::Get()->GetCraftingRecipes()->GetRecipe(m_Owner, Grid, Recipe); - - if ((Packet->m_SlotNum == 0) && !bDontCook) - { - // Consume the items from the crafting grid: - Recipe.ConsumeIngredients(Grid); - - // Propagate grid back to m_Slots: - Grid.CopyToItems(m_Slots + c_CraftOffset + 1); - - // Get the recipe for the new grid contents: - cRoot::Get()->GetCraftingRecipes()->GetRecipe(m_Owner, Grid, Recipe); - } - m_Slots[c_CraftOffset] = Recipe.GetResult(); - LOGD("%s cooked: %i x %i !!", m_Owner->GetName().c_str(), m_Slots[c_CraftOffset].m_ItemID, m_Slots[c_CraftOffset].m_ItemCount ); - SendWholeInventory( m_Owner->GetClientHandle() ); - } - SendSlot( 0 ); -} + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSurvivalInventory.h" +#include "cPlayer.h" +#include "cClientHandle.h" +#include "cWindow.h" +#include "cItem.h" +#include "CraftingRecipes.h" +#include "cRoot.h" +#include "packets/cPacket_WindowClick.h" + + + + + +cSurvivalInventory::~cSurvivalInventory() +{ + +} + +cSurvivalInventory::cSurvivalInventory(cPlayer* a_Owner) + : cInventory(a_Owner) +{ + +} + +void cSurvivalInventory::Clicked( cPacket* a_ClickPacket ) +{ + cPacket_WindowClick *Packet = reinterpret_cast(a_ClickPacket); + bool bDontCook = false; + if( GetWindow() ) + { + // Override for craft result slot + if( Packet->m_SlotNum == (short)c_CraftOffset ) + { + LOG("In craft slot: %i x %i !!", m_Slots[c_CraftOffset].m_ItemID, m_Slots[c_CraftOffset].m_ItemCount ); + cItem* DraggingItem = GetWindow()->GetDraggingItem(); + if( DraggingItem->IsEmpty() ) + { + *DraggingItem = m_Slots[c_CraftOffset]; + m_Slots[c_CraftOffset].Empty(); + } + else if( DraggingItem->Equals( m_Slots[c_CraftOffset] ) ) + { + if( DraggingItem->m_ItemCount + m_Slots[c_CraftOffset].m_ItemCount <= 64 ) + { + DraggingItem->m_ItemCount += m_Slots[c_CraftOffset].m_ItemCount; + m_Slots[0].Empty(); + } + else + { + bDontCook = true; + } + } + else + { + bDontCook = true; + } + LOG("Dragging Dish %i", DraggingItem->m_ItemCount ); + } + else + { + GetWindow()->Clicked( Packet, *m_Owner ); + } + } + else + { + LOG("No Inventory window! WTF"); + } + + if ((Packet->m_SlotNum >= (short)c_CraftOffset) && (Packet->m_SlotNum < (short)(c_CraftOffset + c_CraftSlots + 1))) + { + cCraftingGrid Grid(m_Slots + c_CraftOffset + 1, 2, 2); + cCraftingRecipe Recipe(Grid); + + cRoot::Get()->GetCraftingRecipes()->GetRecipe(m_Owner, Grid, Recipe); + + if ((Packet->m_SlotNum == 0) && !bDontCook) + { + // Consume the items from the crafting grid: + Recipe.ConsumeIngredients(Grid); + + // Propagate grid back to m_Slots: + Grid.CopyToItems(m_Slots + c_CraftOffset + 1); + + // Get the recipe for the new grid contents: + cRoot::Get()->GetCraftingRecipes()->GetRecipe(m_Owner, Grid, Recipe); + } + m_Slots[c_CraftOffset] = Recipe.GetResult(); + LOGD("%s cooked: %i x %i !!", m_Owner->GetName().c_str(), m_Slots[c_CraftOffset].m_ItemID, m_Slots[c_CraftOffset].m_ItemCount ); + SendWholeInventory( m_Owner->GetClientHandle() ); + } + SendSlot( 0 ); +} diff --git a/source/cSurvivalInventory.h b/source/cSurvivalInventory.h index 6c527f1d2..2061de2b0 100644 --- a/source/cSurvivalInventory.h +++ b/source/cSurvivalInventory.h @@ -1,22 +1,22 @@ - -#pragma once - -#include "cInventory.h" - - - - - -class cSurvivalInventory //tolua_export - : public cInventory -{ //tolua_export -public: - cSurvivalInventory(cPlayer* a_Owner); - ~cSurvivalInventory(); - - virtual void Clicked( cPacket* a_ClickPacket ); -}; //tolua_export - - - - + +#pragma once + +#include "cInventory.h" + + + + + +class cSurvivalInventory //tolua_export + : public cInventory +{ //tolua_export +public: + cSurvivalInventory(cPlayer* a_Owner); + ~cSurvivalInventory(); + + virtual void Clicked( cPacket* a_ClickPacket ); +}; //tolua_export + + + + diff --git a/source/cTCPLink.cpp b/source/cTCPLink.cpp index 0ade65d55..22151b32a 100644 --- a/source/cTCPLink.cpp +++ b/source/cTCPLink.cpp @@ -1,129 +1,129 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cTCPLink.h" -#include "cSocket.h" - - - - - -#ifdef _WIN32 - #define MSG_NOSIGNAL (0) -#endif -#ifdef __MACH__ - #define MSG_NOSIGNAL (0) -#endif - - - - - -cTCPLink::cTCPLink() - : m_Socket( 0 ) - , m_StopEvent( new cEvent() ) -{ -} - -cTCPLink::~cTCPLink() -{ - if( m_Socket ) - { - CloseSocket(); - m_StopEvent->Wait(); - } - delete m_StopEvent; -} - -void cTCPLink::CloseSocket() -{ - if( m_Socket ) - { - m_Socket.CloseSocket(); - m_Socket = 0; - } -} - -bool cTCPLink::Connect( const AString & a_Address, unsigned int a_Port ) -{ - if( m_Socket ) - { - LOGWARN("WARNING: cTCPLink Connect() called while still connected. ALWAYS disconnect before re-connecting!"); - } - - m_Socket = cSocket::CreateSocket(); - if( !m_Socket.IsValid() ) - { - LOGERROR("cTCPLink: Failed to create socket"); - return false; - } - - if (m_Socket.Connect(a_Address, a_Port) != 0) - { - LOGWARN("cTCPLink: Cannot connect to server \"%s\" (%s)", m_Socket.GetLastErrorString().c_str()); - m_Socket.CloseSocket(); - return false; - } - - cThread( ReceiveThread, this ); - - return true; -} - - - - - -int cTCPLink::Send(const char * a_Data, unsigned int a_Size, int a_Flags /* = 0 */ ) -{ - (void)a_Flags; - if (!m_Socket.IsValid()) - { - LOGWARN("cTCPLink: Trying to send data without a valid connection!"); - return -1; - } - return m_Socket.Send(a_Data, a_Size); -} - - - - - -int cTCPLink::SendMessage(const char * a_Message, int a_Flags /* = 0 */ ) -{ - (void)a_Flags; - if (!m_Socket.IsValid()) - { - LOGWARN("cTCPLink: Trying to send message without a valid connection!"); - return -1; - } - return m_Socket.Send(a_Message, strlen(a_Message)); -} - - - - - -void cTCPLink::ReceiveThread( void* a_Param) -{ - cTCPLink* self = (cTCPLink*)a_Param; - cSocket Socket = self->m_Socket; - int Received = 0; - do - { - char Data[256]; - Received = Socket.Receive(Data, sizeof(Data), 0); - self->ReceivedData( Data, ((Received > 0) ? Received : -1) ); - } while ( Received > 0 ); - - LOGINFO("cTCPLink Disconnected (%i)", Received ); - - if (Socket == self->m_Socket) - { - self->m_StopEvent->Set(); - } -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cTCPLink.h" +#include "cSocket.h" + + + + + +#ifdef _WIN32 + #define MSG_NOSIGNAL (0) +#endif +#ifdef __MACH__ + #define MSG_NOSIGNAL (0) +#endif + + + + + +cTCPLink::cTCPLink() + : m_Socket( 0 ) + , m_StopEvent( new cEvent() ) +{ +} + +cTCPLink::~cTCPLink() +{ + if( m_Socket ) + { + CloseSocket(); + m_StopEvent->Wait(); + } + delete m_StopEvent; +} + +void cTCPLink::CloseSocket() +{ + if( m_Socket ) + { + m_Socket.CloseSocket(); + m_Socket = 0; + } +} + +bool cTCPLink::Connect( const AString & a_Address, unsigned int a_Port ) +{ + if( m_Socket ) + { + LOGWARN("WARNING: cTCPLink Connect() called while still connected. ALWAYS disconnect before re-connecting!"); + } + + m_Socket = cSocket::CreateSocket(); + if( !m_Socket.IsValid() ) + { + LOGERROR("cTCPLink: Failed to create socket"); + return false; + } + + if (m_Socket.Connect(a_Address, a_Port) != 0) + { + LOGWARN("cTCPLink: Cannot connect to server \"%s\" (%s)", m_Socket.GetLastErrorString().c_str()); + m_Socket.CloseSocket(); + return false; + } + + cThread( ReceiveThread, this ); + + return true; +} + + + + + +int cTCPLink::Send(const char * a_Data, unsigned int a_Size, int a_Flags /* = 0 */ ) +{ + (void)a_Flags; + if (!m_Socket.IsValid()) + { + LOGWARN("cTCPLink: Trying to send data without a valid connection!"); + return -1; + } + return m_Socket.Send(a_Data, a_Size); +} + + + + + +int cTCPLink::SendMessage(const char * a_Message, int a_Flags /* = 0 */ ) +{ + (void)a_Flags; + if (!m_Socket.IsValid()) + { + LOGWARN("cTCPLink: Trying to send message without a valid connection!"); + return -1; + } + return m_Socket.Send(a_Message, strlen(a_Message)); +} + + + + + +void cTCPLink::ReceiveThread( void* a_Param) +{ + cTCPLink* self = (cTCPLink*)a_Param; + cSocket Socket = self->m_Socket; + int Received = 0; + do + { + char Data[256]; + Received = Socket.Receive(Data, sizeof(Data), 0); + self->ReceivedData( Data, ((Received > 0) ? Received : -1) ); + } while ( Received > 0 ); + + LOGINFO("cTCPLink Disconnected (%i)", Received ); + + if (Socket == self->m_Socket) + { + self->m_StopEvent->Set(); + } +} + + + + diff --git a/source/cTCPLink.h b/source/cTCPLink.h index ea38f9b7b..0bba84243 100644 --- a/source/cTCPLink.h +++ b/source/cTCPLink.h @@ -1,22 +1,22 @@ -#pragma once - -#include "cSocket.h" - -class cTCPLink //tolua_export -{ //tolua_export -public: //tolua_export - cTCPLink(); //tolua_export - ~cTCPLink(); //tolua_export - - bool Connect (const AString & a_Address, unsigned int a_Port ); //tolua_export - int Send (const char * a_Data, unsigned int a_Size, int a_Flags = 0 ); //tolua_export - int SendMessage(const char * a_Message, int a_Flags = 0 ); //tolua_export - void CloseSocket(); //tolua_export -protected: //tolua_export - virtual void ReceivedData( char a_Data[256], int a_Size ) = 0; //tolua_export - - static void ReceiveThread( void* a_Param ); - - cSocket m_Socket; - cEvent* m_StopEvent; -}; //tolua_export +#pragma once + +#include "cSocket.h" + +class cTCPLink //tolua_export +{ //tolua_export +public: //tolua_export + cTCPLink(); //tolua_export + ~cTCPLink(); //tolua_export + + bool Connect (const AString & a_Address, unsigned int a_Port ); //tolua_export + int Send (const char * a_Data, unsigned int a_Size, int a_Flags = 0 ); //tolua_export + int SendMessage(const char * a_Message, int a_Flags = 0 ); //tolua_export + void CloseSocket(); //tolua_export +protected: //tolua_export + virtual void ReceivedData( char a_Data[256], int a_Size ) = 0; //tolua_export + + static void ReceiveThread( void* a_Param ); + + cSocket m_Socket; + cEvent* m_StopEvent; +}; //tolua_export diff --git a/source/cThread.cpp b/source/cThread.cpp index 3197fdcd6..f07a973b5 100644 --- a/source/cThread.cpp +++ b/source/cThread.cpp @@ -1,118 +1,118 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - - - - - -// When in MSVC, the debugger provides "thread naming" by catching special exceptions. Interface here: -#ifdef _MSC_VER -// -// Usage: SetThreadName (-1, "MainThread"); -// -typedef struct tagTHREADNAME_INFO -{ - DWORD dwType; // must be 0x1000 - LPCSTR szName; // pointer to name (in user addr space) - DWORD dwThreadID; // thread ID (-1=caller thread) - DWORD dwFlags; // reserved for future use, must be zero -} THREADNAME_INFO; - -void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName) -{ - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = szThreadName; - info.dwThreadID = dwThreadID; - info.dwFlags = 0; - - __try - { - RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (DWORD*)&info ); - } - __except(EXCEPTION_CONTINUE_EXECUTION) - { - } -} -#endif // _MSC_VER - - - - - -cThread::cThread( ThreadFunc a_ThreadFunction, void* a_Param, const char* a_ThreadName /* = 0 */ ) - : m_ThreadFunction( a_ThreadFunction ) - , m_Param( a_Param ) - , m_Event( new cEvent() ) - , m_StopEvent( 0 ) - , m_ThreadName( 0 ) -{ - if( a_ThreadName ) - { - m_ThreadName = new char[ strlen(a_ThreadName)+1 ]; - strcpy(m_ThreadName, a_ThreadName); - } -} - -cThread::~cThread() -{ - delete m_Event; - - if( m_StopEvent ) - { - m_StopEvent->Wait(); - delete m_StopEvent; - } - - delete [] m_ThreadName; -} - -void cThread::Start( bool a_bWaitOnDelete /* = true */ ) -{ - if( a_bWaitOnDelete ) - m_StopEvent = new cEvent(); - -#ifndef _WIN32 - pthread_t SndThread; - if( pthread_create( &SndThread, NULL, MyThread, this) ) - LOGERROR("ERROR: Could not create thread!"); -#else - DWORD ThreadID = 0; - HANDLE hThread = CreateThread( 0 // security - ,0 // stack size - , (LPTHREAD_START_ROUTINE) MyThread // function name - ,this // parameters - ,0 // flags - ,&ThreadID ); // thread id - CloseHandle( hThread ); - - if( m_ThreadName ) - { - SetThreadName(ThreadID, m_ThreadName ); - } -#endif - - // Wait until thread has actually been created - m_Event->Wait(); -} - -#ifdef _WIN32 -unsigned long cThread::MyThread(void* a_Param ) -#else -void *cThread::MyThread( void *a_Param ) -#endif -{ - cThread* self = (cThread*)a_Param; - cEvent* StopEvent = self->m_StopEvent; - - ThreadFunc* ThreadFunction = self->m_ThreadFunction; - void* ThreadParam = self->m_Param; - - // Set event to let other thread know this thread has been created and it's safe to delete the cThread object - self->m_Event->Set(); - - ThreadFunction( ThreadParam ); - - if( StopEvent ) StopEvent->Set(); - return 0; -} + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + + + + + +// When in MSVC, the debugger provides "thread naming" by catching special exceptions. Interface here: +#ifdef _MSC_VER +// +// Usage: SetThreadName (-1, "MainThread"); +// +typedef struct tagTHREADNAME_INFO +{ + DWORD dwType; // must be 0x1000 + LPCSTR szName; // pointer to name (in user addr space) + DWORD dwThreadID; // thread ID (-1=caller thread) + DWORD dwFlags; // reserved for future use, must be zero +} THREADNAME_INFO; + +void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName) +{ + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = szThreadName; + info.dwThreadID = dwThreadID; + info.dwFlags = 0; + + __try + { + RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (DWORD*)&info ); + } + __except(EXCEPTION_CONTINUE_EXECUTION) + { + } +} +#endif // _MSC_VER + + + + + +cThread::cThread( ThreadFunc a_ThreadFunction, void* a_Param, const char* a_ThreadName /* = 0 */ ) + : m_ThreadFunction( a_ThreadFunction ) + , m_Param( a_Param ) + , m_Event( new cEvent() ) + , m_StopEvent( 0 ) + , m_ThreadName( 0 ) +{ + if( a_ThreadName ) + { + m_ThreadName = new char[ strlen(a_ThreadName)+1 ]; + strcpy(m_ThreadName, a_ThreadName); + } +} + +cThread::~cThread() +{ + delete m_Event; + + if( m_StopEvent ) + { + m_StopEvent->Wait(); + delete m_StopEvent; + } + + delete [] m_ThreadName; +} + +void cThread::Start( bool a_bWaitOnDelete /* = true */ ) +{ + if( a_bWaitOnDelete ) + m_StopEvent = new cEvent(); + +#ifndef _WIN32 + pthread_t SndThread; + if( pthread_create( &SndThread, NULL, MyThread, this) ) + LOGERROR("ERROR: Could not create thread!"); +#else + DWORD ThreadID = 0; + HANDLE hThread = CreateThread( 0 // security + ,0 // stack size + , (LPTHREAD_START_ROUTINE) MyThread // function name + ,this // parameters + ,0 // flags + ,&ThreadID ); // thread id + CloseHandle( hThread ); + + if( m_ThreadName ) + { + SetThreadName(ThreadID, m_ThreadName ); + } +#endif + + // Wait until thread has actually been created + m_Event->Wait(); +} + +#ifdef _WIN32 +unsigned long cThread::MyThread(void* a_Param ) +#else +void *cThread::MyThread( void *a_Param ) +#endif +{ + cThread* self = (cThread*)a_Param; + cEvent* StopEvent = self->m_StopEvent; + + ThreadFunc* ThreadFunction = self->m_ThreadFunction; + void* ThreadParam = self->m_Param; + + // Set event to let other thread know this thread has been created and it's safe to delete the cThread object + self->m_Event->Set(); + + ThreadFunction( ThreadParam ); + + if( StopEvent ) StopEvent->Set(); + return 0; +} diff --git a/source/cThread.h b/source/cThread.h index 4fb001e67..5707e4bac 100644 --- a/source/cThread.h +++ b/source/cThread.h @@ -1,26 +1,26 @@ -#pragma once - -class cThread -{ -public: - typedef void (ThreadFunc)(void*); - cThread( ThreadFunc a_ThreadFunction, void* a_Param, const char* a_ThreadName = 0 ); - ~cThread(); - - void Start( bool a_bWaitOnDelete = true ); - void WaitForThread(); -private: - ThreadFunc* m_ThreadFunction; - -#ifdef _WIN32 - static unsigned long MyThread(void* a_Param ); -#else - static void *MyThread( void *lpParam ); -#endif - - void* m_Param; - cEvent* m_Event; - cEvent* m_StopEvent; - - char* m_ThreadName; +#pragma once + +class cThread +{ +public: + typedef void (ThreadFunc)(void*); + cThread( ThreadFunc a_ThreadFunction, void* a_Param, const char* a_ThreadName = 0 ); + ~cThread(); + + void Start( bool a_bWaitOnDelete = true ); + void WaitForThread(); +private: + ThreadFunc* m_ThreadFunction; + +#ifdef _WIN32 + static unsigned long MyThread(void* a_Param ); +#else + static void *MyThread( void *lpParam ); +#endif + + void* m_Param; + cEvent* m_Event; + cEvent* m_StopEvent; + + char* m_ThreadName; }; \ No newline at end of file diff --git a/source/cTimer.cpp b/source/cTimer.cpp index 8fa0c2715..a68ad2480 100644 --- a/source/cTimer.cpp +++ b/source/cTimer.cpp @@ -1,40 +1,40 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cTimer.h" - - - - - - -cTimer::cTimer() -#ifdef _WIN32 - : m_TicksPerSecond( new LARGE_INTEGER ) -#endif -{ -#ifdef _WIN32 - QueryPerformanceFrequency( (LARGE_INTEGER*)m_TicksPerSecond ); -#endif -} - -cTimer::~cTimer() -{ -#ifdef _WIN32 - delete (LARGE_INTEGER*)m_TicksPerSecond; -#endif -} - -long long cTimer::GetNowTime() -{ -#ifdef _WIN32 - LARGE_INTEGER now; - QueryPerformanceCounter( &now ); - LARGE_INTEGER & tps = *((LARGE_INTEGER*)m_TicksPerSecond); - return ((now.QuadPart*1000) / tps.QuadPart ); -#else - struct timeval now; - gettimeofday(&now, NULL); - return (long long)(now.tv_sec*1000 + now.tv_usec/1000); -#endif + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cTimer.h" + + + + + + +cTimer::cTimer() +#ifdef _WIN32 + : m_TicksPerSecond( new LARGE_INTEGER ) +#endif +{ +#ifdef _WIN32 + QueryPerformanceFrequency( (LARGE_INTEGER*)m_TicksPerSecond ); +#endif +} + +cTimer::~cTimer() +{ +#ifdef _WIN32 + delete (LARGE_INTEGER*)m_TicksPerSecond; +#endif +} + +long long cTimer::GetNowTime() +{ +#ifdef _WIN32 + LARGE_INTEGER now; + QueryPerformanceCounter( &now ); + LARGE_INTEGER & tps = *((LARGE_INTEGER*)m_TicksPerSecond); + return ((now.QuadPart*1000) / tps.QuadPart ); +#else + struct timeval now; + gettimeofday(&now, NULL); + return (long long)(now.tv_sec*1000 + now.tv_usec/1000); +#endif } \ No newline at end of file diff --git a/source/cTimer.h b/source/cTimer.h index 52afda8bb..5969d0fc9 100644 --- a/source/cTimer.h +++ b/source/cTimer.h @@ -1,15 +1,15 @@ -#pragma once - -class cTimer -{ -public: - cTimer(); - ~cTimer(); - - long long GetNowTime(); -private: - -#ifdef _WIN32 - void* m_TicksPerSecond; // LARGE_INTEGER* -#endif +#pragma once + +class cTimer +{ +public: + cTimer(); + ~cTimer(); + + long long GetNowTime(); +private: + +#ifdef _WIN32 + void* m_TicksPerSecond; // LARGE_INTEGER* +#endif }; \ No newline at end of file diff --git a/source/cTorch.h b/source/cTorch.h index 6bb2291b2..c45916dbf 100644 --- a/source/cTorch.h +++ b/source/cTorch.h @@ -1,94 +1,94 @@ -#pragma once - -#include "Vector3i.h" - -class cTorch //tolua_export -{ //tolua_export -public: - - static char DirectionToMetaData( char a_Direction ) //tolua_export - { //tolua_export - switch( a_Direction ) - { - case 0x0: - return 0x0; - case 0x1: - return 0x5; //standing on floor - case 0x2: - return 0x4; // south - case 0x3: - return 0x3; // north - case 0x4: - return 0x2; // west - case 0x5: - return 0x1; // east - default: - break; - }; - return 0x0; - } //tolua_export - - static char MetaDataToDirection( char a_MetaData ) //tolua_export - { //tolua_export - switch( a_MetaData ) - { - case 0x0: - return 0x0; - case 0x1: - return 0x5; - case 0x2: - return 0x4; - case 0x3: - return 0x3; - case 0x4: - return 0x2; - case 0x5: - return 0x1; - default: - break; - }; - return 0x0; - } //tolua_export - - static bool IsAttachedTo( const Vector3i & a_TorchPos, char a_TorchMeta, const Vector3i & a_BlockPos ) - { - switch( a_TorchMeta ) - { - case 0x0: - case 0x5: // On floor - if( (a_TorchPos - a_BlockPos).Equals( Vector3i(0, 1, 0 ) ) ) - { - return true; - } - break; - case 0x4: // South -Z - if( (a_TorchPos - a_BlockPos).Equals( Vector3i(0, 0, -1 ) ) ) - { - return true; - } - break; - case 0x3: // North +Z - if( (a_TorchPos - a_BlockPos).Equals( Vector3i(0, 0, 1 ) ) ) - { - return true; - } - break; - case 0x2: // West -X - if( (a_TorchPos - a_BlockPos).Equals( Vector3i(-1, 0, 0 ) ) ) - { - return true; - } - break; - case 0x1: // East +X - if( (a_TorchPos - a_BlockPos).Equals( Vector3i( 1, 0, 0 ) ) ) - { - return true; - } - break; - default: - break; - }; - return false; - } - +#pragma once + +#include "Vector3i.h" + +class cTorch //tolua_export +{ //tolua_export +public: + + static char DirectionToMetaData( char a_Direction ) //tolua_export + { //tolua_export + switch( a_Direction ) + { + case 0x0: + return 0x0; + case 0x1: + return 0x5; //standing on floor + case 0x2: + return 0x4; // south + case 0x3: + return 0x3; // north + case 0x4: + return 0x2; // west + case 0x5: + return 0x1; // east + default: + break; + }; + return 0x0; + } //tolua_export + + static char MetaDataToDirection( char a_MetaData ) //tolua_export + { //tolua_export + switch( a_MetaData ) + { + case 0x0: + return 0x0; + case 0x1: + return 0x5; + case 0x2: + return 0x4; + case 0x3: + return 0x3; + case 0x4: + return 0x2; + case 0x5: + return 0x1; + default: + break; + }; + return 0x0; + } //tolua_export + + static bool IsAttachedTo( const Vector3i & a_TorchPos, char a_TorchMeta, const Vector3i & a_BlockPos ) + { + switch( a_TorchMeta ) + { + case 0x0: + case 0x5: // On floor + if( (a_TorchPos - a_BlockPos).Equals( Vector3i(0, 1, 0 ) ) ) + { + return true; + } + break; + case 0x4: // South -Z + if( (a_TorchPos - a_BlockPos).Equals( Vector3i(0, 0, -1 ) ) ) + { + return true; + } + break; + case 0x3: // North +Z + if( (a_TorchPos - a_BlockPos).Equals( Vector3i(0, 0, 1 ) ) ) + { + return true; + } + break; + case 0x2: // West -X + if( (a_TorchPos - a_BlockPos).Equals( Vector3i(-1, 0, 0 ) ) ) + { + return true; + } + break; + case 0x1: // East +X + if( (a_TorchPos - a_BlockPos).Equals( Vector3i( 1, 0, 0 ) ) ) + { + return true; + } + break; + default: + break; + }; + return false; + } + }; //tolua_export \ No newline at end of file diff --git a/source/cTracer.cpp b/source/cTracer.cpp index 5cfc41b60..fba0f908c 100644 --- a/source/cTracer.cpp +++ b/source/cTracer.cpp @@ -1,350 +1,350 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cTracer.h" -#include "cWorld.h" - -#include "Vector3f.h" -#include "Vector3i.h" -#include "Vector3d.h" - -#include "BlockID.h" -#include "cEntity.h" - -#include "Defines.h" - -#ifndef _WIN32 - #include // abs() -#endif - -cTracer::cTracer(cWorld* a_World) - : m_World( a_World ) -{ - m_NormalTable[0].Set(-1, 0, 0); - m_NormalTable[1].Set( 0, 0,-1); - m_NormalTable[2].Set( 1, 0, 0); - m_NormalTable[3].Set( 0, 0, 1); - m_NormalTable[4].Set( 0, 1, 0); - m_NormalTable[5].Set( 0,-1, 0); -} - -cTracer::~cTracer() -{ -} - -float cTracer::SigNum( float a_Num ) -{ - if (a_Num < 0.f) return -1.f; - if (a_Num > 0.f) return 1.f; - return 0.f; -} - -void cTracer::SetValues( const Vector3f & a_Start, const Vector3f & a_Direction ) -{ - // calculate the direction of the ray (linear algebra) - dir = a_Direction; - - // decide which direction to start walking in - step.x = (int) SigNum(dir.x); - step.y = (int) SigNum(dir.y); - step.z = (int) SigNum(dir.z); - - // normalize the direction vector - if( dir.SqrLength() > 0.f ) dir.Normalize(); - - // how far we must move in the ray direction before - // we encounter a new voxel in x-direction - // same but y-direction - if( dir.x != 0.f ) tDelta.x = 1/fabs(dir.x); - else tDelta.x = 0; - if( dir.y != 0.f ) tDelta.y = 1/fabs(dir.y); - else tDelta.y = 0; - if( dir.z != 0.f ) tDelta.z = 1/fabs(dir.z); - else tDelta.z = 0; - - // start voxel coordinates - // use your - // transformer - // function here - pos.x = (int)floorf(a_Start.x); - pos.y = (int)floorf(a_Start.y); - pos.z = (int)floorf(a_Start.z); - - // calculate distance to first intersection in the voxel we start from - if(dir.x < 0) - { - tMax.x = ((float)pos.x - a_Start.x) / dir.x; - } - else - { - tMax.x = (((float)pos.x + 1) - a_Start.x) / dir.x; - } - - if(dir.y < 0) - { - tMax.y = ((float)pos.y - a_Start.y) / dir.y; - } - else - { - tMax.y = (((float)pos.y + 1) - a_Start.y) / dir.y; - } - - if(dir.z < 0) - { - tMax.z = ((float)pos.z - a_Start.z) / dir.z; - } - else - { - tMax.z = (((float)pos.z + 1) - a_Start.z) / dir.z; - } -} - -int cTracer::Trace( const Vector3f & a_Start, const Vector3f & a_Direction, int a_Distance) -{ - SetValues( a_Start, a_Direction ); - - const Vector3f End = a_Start + (dir * (float)a_Distance); - - // end voxel coordinates - end1.x = (int)floorf(End.x); - end1.y = (int)floorf(End.y); - end1.z = (int)floorf(End.z); - - // check if first is occupied - if( pos.Equals( end1 ) ) - { - LOG("WARNING: cTracer: Start and end in same block"); - return 0; - } - - bool reachedX = false, reachedY = false, reachedZ = false; - - int Iterations = 0; - while ( Iterations < a_Distance ) - { - Iterations++; - if(tMax.x < tMax.y && tMax.x < tMax.z) - { - tMax.x += tDelta.x; - pos.x += step.x; - } - else if(tMax.y < tMax.z) - { - tMax.y += tDelta.y; - pos.y += step.y; - } - else - { - tMax.z += tDelta.z; - pos.z += step.z; - } - - if(step.x > 0.0f) - { - if(pos.x >= end1.x) - { - reachedX = true; - } - } - else if(pos.x <= end1.x) - { - reachedX = true; - } - - if(step.y > 0.0f) - { - if(pos.y >= end1.y) - { - reachedY = true; - } - } - else if(pos.y <= end1.y) - { - reachedY = true; - } - - if(step.z > 0.0f) - { - if(pos.z >= end1.z) - { - reachedZ = true; - } - } - else if(pos.z <= end1.z) - { - reachedZ = true; - } - - if (reachedX && reachedY && reachedZ) - { - return false; - } - - char BlockID = m_World->GetBlock( pos.x, pos.y, pos.z ); - //No collision with water ;) - if ( BlockID != E_BLOCK_AIR || IsBlockWater(BlockID)) - { - BlockHitPosition = pos; - int Normal = GetHitNormal(a_Start, End, pos ); - if(Normal > 0) - { - HitNormal = m_NormalTable[Normal-1]; - } - return 1; - } - } - return 0; -} - -// return 1 = hit, other is not hit -int LinesCross(float x0,float y0,float x1,float y1,float x2,float y2,float x3,float y3) -{ - //float linx, liny; - - float d=(x1-x0)*(y3-y2)-(y1-y0)*(x3-x2); - if (abs(d)<0.001) {return 0;} - float AB=((y0-y2)*(x3-x2)-(x0-x2)*(y3-y2))/d; - if (AB>=0.0 && AB<=1.0) - { - float CD=((y0-y2)*(x1-x0)-(x0-x2)*(y1-y0))/d; - if (CD>=0.0 && CD<=1.0) - { - //linx=x0+AB*(x1-x0); - //liny=y0+AB*(y1-y0); - return 1; - } - } - return 0; -} - -// intersect3D_SegmentPlane(): intersect a segment and a plane -// Input: a_Ray = a segment, and a_Plane = a plane = {Point V0; Vector n;} -// Output: *I0 = the intersect point (when it exists) -// Return: 0 = disjoint (no intersection) -// 1 = intersection in the unique point *I0 -// 2 = the segment lies in the plane -int cTracer::intersect3D_SegmentPlane( const Vector3f & a_Origin, const Vector3f & a_End, const Vector3f & a_PlanePos, const Vector3f & a_PlaneNormal ) -{ - Vector3f u = a_End - a_Origin;//a_Ray.P1 - S.P0; - Vector3f w = a_Origin - a_PlanePos;//S.P0 - Pn.V0; - - float D = a_PlaneNormal.Dot( u );//dot(Pn.n, u); - float N = -(a_PlaneNormal.Dot( w ) );//-dot(a_Plane.n, w); - - const float EPSILON = 0.0001f; - if (fabs(D) < EPSILON) { // segment is parallel to plane - if (N == 0) // segment lies in plane - return 2; - return 0; // no intersection - } - // they are not parallel - // compute intersect param - float sI = N / D; - if (sI < 0 || sI > 1) - return 0; // no intersection - - //Vector3f I ( a_Ray->GetOrigin() + sI * u );//S.P0 + sI * u; // compute segment intersect point - RealHit = a_Origin + u * sI; - return 1; -} - -int cTracer::GetHitNormal(const Vector3f & start, const Vector3f & end, const Vector3i & a_BlockPos) -{ - Vector3i SmallBlockPos = a_BlockPos; - char BlockID = m_World->GetBlock( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z ); - - if( BlockID == E_BLOCK_AIR || IsBlockWater(BlockID)) - return 0; - - Vector3f BlockPos; - BlockPos = Vector3f(SmallBlockPos); - - Vector3f Look = (end - start); - Look.Normalize(); - - float dot = Look.Dot( Vector3f(-1, 0, 0) ); // first face normal is x -1 - if(dot < 0) - { - int Lines = LinesCross( start.x, start.y, end.x, end.y, BlockPos.x, BlockPos.y, BlockPos.x, BlockPos.y + 1 ); - if(Lines == 1) - { - Lines = LinesCross( start.x, start.z, end.x, end.z, BlockPos.x, BlockPos.z, BlockPos.x, BlockPos.z + 1 ); - if(Lines == 1) - { - intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(-1, 0, 0) ); - return 1; - } - } - } - dot = Look.Dot( Vector3f(0, 0, -1) ); // second face normal is z -1 - if(dot < 0) - { - int Lines = LinesCross( start.z, start.y, end.z, end.y, BlockPos.z, BlockPos.y, BlockPos.z, BlockPos.y + 1 ); - if(Lines == 1) - { - Lines = LinesCross( start.z, start.x, end.z, end.x, BlockPos.z, BlockPos.x, BlockPos.z, BlockPos.x + 1 ); - if(Lines == 1) - { - intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(0, 0, -1) ); - return 2; - } - } - } - dot = Look.Dot( Vector3f(1, 0, 0) ); // third face normal is x 1 - if(dot < 0) - { - int Lines = LinesCross( start.x, start.y, end.x, end.y, BlockPos.x + 1, BlockPos.y, BlockPos.x + 1, BlockPos.y + 1 ); - if(Lines == 1) - { - Lines = LinesCross( start.x, start.z, end.x, end.z, BlockPos.x + 1, BlockPos.z, BlockPos.x + 1, BlockPos.z + 1 ); - if(Lines == 1) - { - intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(1, 0, 0), Vector3f(1, 0, 0) ); - return 3; - } - } - } - dot = Look.Dot( Vector3f(0, 0, 1) ); // fourth face normal is z 1 - if(dot < 0) - { - int Lines = LinesCross( start.z, start.y, end.z, end.y, BlockPos.z + 1, BlockPos.y, BlockPos.z + 1, BlockPos.y + 1 ); - if(Lines == 1) - { - Lines = LinesCross( start.z, start.x, end.z, end.x, BlockPos.z + 1, BlockPos.x, BlockPos.z + 1, BlockPos.x + 1 ); - if(Lines == 1) - { - intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(0, 0, 1), Vector3f(0, 0, 1) ); - return 4; - } - } - } - dot = Look.Dot( Vector3f(0, 1, 0) ); // fifth face normal is y 1 - if(dot < 0) - { - int Lines = LinesCross( start.y, start.x, end.y, end.x, BlockPos.y + 1, BlockPos.x, BlockPos.y + 1, BlockPos.x + 1 ); - if(Lines == 1) - { - Lines = LinesCross( start.y, start.z, end.y, end.z, BlockPos.y + 1, BlockPos.z, BlockPos.y + 1, BlockPos.z + 1 ); - if(Lines == 1) - { - intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(0, 1, 0), Vector3f(0, 1, 0) ); - return 5; - } - } - } - dot = Look.Dot( Vector3f(0, -1, 0) ); // sixth face normal is y -1 - if(dot < 0) - { - int Lines = LinesCross( start.y, start.x, end.y, end.x, BlockPos.y, BlockPos.x, BlockPos.y, BlockPos.x + 1 ); - if(Lines == 1) - { - Lines = LinesCross( start.y, start.z, end.y, end.z, BlockPos.y, BlockPos.z, BlockPos.y, BlockPos.z + 1 ); - if(Lines == 1) - { - intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(0, -1, 0) ); - return 6; - } - } - } - return 0; -} + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cTracer.h" +#include "cWorld.h" + +#include "Vector3f.h" +#include "Vector3i.h" +#include "Vector3d.h" + +#include "BlockID.h" +#include "cEntity.h" + +#include "Defines.h" + +#ifndef _WIN32 + #include // abs() +#endif + +cTracer::cTracer(cWorld* a_World) + : m_World( a_World ) +{ + m_NormalTable[0].Set(-1, 0, 0); + m_NormalTable[1].Set( 0, 0,-1); + m_NormalTable[2].Set( 1, 0, 0); + m_NormalTable[3].Set( 0, 0, 1); + m_NormalTable[4].Set( 0, 1, 0); + m_NormalTable[5].Set( 0,-1, 0); +} + +cTracer::~cTracer() +{ +} + +float cTracer::SigNum( float a_Num ) +{ + if (a_Num < 0.f) return -1.f; + if (a_Num > 0.f) return 1.f; + return 0.f; +} + +void cTracer::SetValues( const Vector3f & a_Start, const Vector3f & a_Direction ) +{ + // calculate the direction of the ray (linear algebra) + dir = a_Direction; + + // decide which direction to start walking in + step.x = (int) SigNum(dir.x); + step.y = (int) SigNum(dir.y); + step.z = (int) SigNum(dir.z); + + // normalize the direction vector + if( dir.SqrLength() > 0.f ) dir.Normalize(); + + // how far we must move in the ray direction before + // we encounter a new voxel in x-direction + // same but y-direction + if( dir.x != 0.f ) tDelta.x = 1/fabs(dir.x); + else tDelta.x = 0; + if( dir.y != 0.f ) tDelta.y = 1/fabs(dir.y); + else tDelta.y = 0; + if( dir.z != 0.f ) tDelta.z = 1/fabs(dir.z); + else tDelta.z = 0; + + // start voxel coordinates + // use your + // transformer + // function here + pos.x = (int)floorf(a_Start.x); + pos.y = (int)floorf(a_Start.y); + pos.z = (int)floorf(a_Start.z); + + // calculate distance to first intersection in the voxel we start from + if(dir.x < 0) + { + tMax.x = ((float)pos.x - a_Start.x) / dir.x; + } + else + { + tMax.x = (((float)pos.x + 1) - a_Start.x) / dir.x; + } + + if(dir.y < 0) + { + tMax.y = ((float)pos.y - a_Start.y) / dir.y; + } + else + { + tMax.y = (((float)pos.y + 1) - a_Start.y) / dir.y; + } + + if(dir.z < 0) + { + tMax.z = ((float)pos.z - a_Start.z) / dir.z; + } + else + { + tMax.z = (((float)pos.z + 1) - a_Start.z) / dir.z; + } +} + +int cTracer::Trace( const Vector3f & a_Start, const Vector3f & a_Direction, int a_Distance) +{ + SetValues( a_Start, a_Direction ); + + const Vector3f End = a_Start + (dir * (float)a_Distance); + + // end voxel coordinates + end1.x = (int)floorf(End.x); + end1.y = (int)floorf(End.y); + end1.z = (int)floorf(End.z); + + // check if first is occupied + if( pos.Equals( end1 ) ) + { + LOG("WARNING: cTracer: Start and end in same block"); + return 0; + } + + bool reachedX = false, reachedY = false, reachedZ = false; + + int Iterations = 0; + while ( Iterations < a_Distance ) + { + Iterations++; + if(tMax.x < tMax.y && tMax.x < tMax.z) + { + tMax.x += tDelta.x; + pos.x += step.x; + } + else if(tMax.y < tMax.z) + { + tMax.y += tDelta.y; + pos.y += step.y; + } + else + { + tMax.z += tDelta.z; + pos.z += step.z; + } + + if(step.x > 0.0f) + { + if(pos.x >= end1.x) + { + reachedX = true; + } + } + else if(pos.x <= end1.x) + { + reachedX = true; + } + + if(step.y > 0.0f) + { + if(pos.y >= end1.y) + { + reachedY = true; + } + } + else if(pos.y <= end1.y) + { + reachedY = true; + } + + if(step.z > 0.0f) + { + if(pos.z >= end1.z) + { + reachedZ = true; + } + } + else if(pos.z <= end1.z) + { + reachedZ = true; + } + + if (reachedX && reachedY && reachedZ) + { + return false; + } + + char BlockID = m_World->GetBlock( pos.x, pos.y, pos.z ); + //No collision with water ;) + if ( BlockID != E_BLOCK_AIR || IsBlockWater(BlockID)) + { + BlockHitPosition = pos; + int Normal = GetHitNormal(a_Start, End, pos ); + if(Normal > 0) + { + HitNormal = m_NormalTable[Normal-1]; + } + return 1; + } + } + return 0; +} + +// return 1 = hit, other is not hit +int LinesCross(float x0,float y0,float x1,float y1,float x2,float y2,float x3,float y3) +{ + //float linx, liny; + + float d=(x1-x0)*(y3-y2)-(y1-y0)*(x3-x2); + if (abs(d)<0.001) {return 0;} + float AB=((y0-y2)*(x3-x2)-(x0-x2)*(y3-y2))/d; + if (AB>=0.0 && AB<=1.0) + { + float CD=((y0-y2)*(x1-x0)-(x0-x2)*(y1-y0))/d; + if (CD>=0.0 && CD<=1.0) + { + //linx=x0+AB*(x1-x0); + //liny=y0+AB*(y1-y0); + return 1; + } + } + return 0; +} + +// intersect3D_SegmentPlane(): intersect a segment and a plane +// Input: a_Ray = a segment, and a_Plane = a plane = {Point V0; Vector n;} +// Output: *I0 = the intersect point (when it exists) +// Return: 0 = disjoint (no intersection) +// 1 = intersection in the unique point *I0 +// 2 = the segment lies in the plane +int cTracer::intersect3D_SegmentPlane( const Vector3f & a_Origin, const Vector3f & a_End, const Vector3f & a_PlanePos, const Vector3f & a_PlaneNormal ) +{ + Vector3f u = a_End - a_Origin;//a_Ray.P1 - S.P0; + Vector3f w = a_Origin - a_PlanePos;//S.P0 - Pn.V0; + + float D = a_PlaneNormal.Dot( u );//dot(Pn.n, u); + float N = -(a_PlaneNormal.Dot( w ) );//-dot(a_Plane.n, w); + + const float EPSILON = 0.0001f; + if (fabs(D) < EPSILON) { // segment is parallel to plane + if (N == 0) // segment lies in plane + return 2; + return 0; // no intersection + } + // they are not parallel + // compute intersect param + float sI = N / D; + if (sI < 0 || sI > 1) + return 0; // no intersection + + //Vector3f I ( a_Ray->GetOrigin() + sI * u );//S.P0 + sI * u; // compute segment intersect point + RealHit = a_Origin + u * sI; + return 1; +} + +int cTracer::GetHitNormal(const Vector3f & start, const Vector3f & end, const Vector3i & a_BlockPos) +{ + Vector3i SmallBlockPos = a_BlockPos; + char BlockID = m_World->GetBlock( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z ); + + if( BlockID == E_BLOCK_AIR || IsBlockWater(BlockID)) + return 0; + + Vector3f BlockPos; + BlockPos = Vector3f(SmallBlockPos); + + Vector3f Look = (end - start); + Look.Normalize(); + + float dot = Look.Dot( Vector3f(-1, 0, 0) ); // first face normal is x -1 + if(dot < 0) + { + int Lines = LinesCross( start.x, start.y, end.x, end.y, BlockPos.x, BlockPos.y, BlockPos.x, BlockPos.y + 1 ); + if(Lines == 1) + { + Lines = LinesCross( start.x, start.z, end.x, end.z, BlockPos.x, BlockPos.z, BlockPos.x, BlockPos.z + 1 ); + if(Lines == 1) + { + intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(-1, 0, 0) ); + return 1; + } + } + } + dot = Look.Dot( Vector3f(0, 0, -1) ); // second face normal is z -1 + if(dot < 0) + { + int Lines = LinesCross( start.z, start.y, end.z, end.y, BlockPos.z, BlockPos.y, BlockPos.z, BlockPos.y + 1 ); + if(Lines == 1) + { + Lines = LinesCross( start.z, start.x, end.z, end.x, BlockPos.z, BlockPos.x, BlockPos.z, BlockPos.x + 1 ); + if(Lines == 1) + { + intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(0, 0, -1) ); + return 2; + } + } + } + dot = Look.Dot( Vector3f(1, 0, 0) ); // third face normal is x 1 + if(dot < 0) + { + int Lines = LinesCross( start.x, start.y, end.x, end.y, BlockPos.x + 1, BlockPos.y, BlockPos.x + 1, BlockPos.y + 1 ); + if(Lines == 1) + { + Lines = LinesCross( start.x, start.z, end.x, end.z, BlockPos.x + 1, BlockPos.z, BlockPos.x + 1, BlockPos.z + 1 ); + if(Lines == 1) + { + intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(1, 0, 0), Vector3f(1, 0, 0) ); + return 3; + } + } + } + dot = Look.Dot( Vector3f(0, 0, 1) ); // fourth face normal is z 1 + if(dot < 0) + { + int Lines = LinesCross( start.z, start.y, end.z, end.y, BlockPos.z + 1, BlockPos.y, BlockPos.z + 1, BlockPos.y + 1 ); + if(Lines == 1) + { + Lines = LinesCross( start.z, start.x, end.z, end.x, BlockPos.z + 1, BlockPos.x, BlockPos.z + 1, BlockPos.x + 1 ); + if(Lines == 1) + { + intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(0, 0, 1), Vector3f(0, 0, 1) ); + return 4; + } + } + } + dot = Look.Dot( Vector3f(0, 1, 0) ); // fifth face normal is y 1 + if(dot < 0) + { + int Lines = LinesCross( start.y, start.x, end.y, end.x, BlockPos.y + 1, BlockPos.x, BlockPos.y + 1, BlockPos.x + 1 ); + if(Lines == 1) + { + Lines = LinesCross( start.y, start.z, end.y, end.z, BlockPos.y + 1, BlockPos.z, BlockPos.y + 1, BlockPos.z + 1 ); + if(Lines == 1) + { + intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(0, 1, 0), Vector3f(0, 1, 0) ); + return 5; + } + } + } + dot = Look.Dot( Vector3f(0, -1, 0) ); // sixth face normal is y -1 + if(dot < 0) + { + int Lines = LinesCross( start.y, start.x, end.y, end.x, BlockPos.y, BlockPos.x, BlockPos.y, BlockPos.x + 1 ); + if(Lines == 1) + { + Lines = LinesCross( start.y, start.z, end.y, end.z, BlockPos.y, BlockPos.z, BlockPos.y, BlockPos.z + 1 ); + if(Lines == 1) + { + intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(0, -1, 0) ); + return 6; + } + } + } + return 0; +} diff --git a/source/cTracer.h b/source/cTracer.h index 08ebc72e5..fa9d3c673 100644 --- a/source/cTracer.h +++ b/source/cTracer.h @@ -1,34 +1,34 @@ -#pragma once - -#include "Vector3i.h" -#include "Vector3f.h" - - -class cWorld; -class cTracer //tolua_export -{ //tolua_export -public: //tolua_export - Vector3f DotPos; - Vector3f BoxOffset; - cTracer( cWorld* a_World); //tolua_export - ~cTracer(); //tolua_export - int Trace( const Vector3f & a_Start, const Vector3f & a_Direction, int a_Distance ); //tolua_export - void SetValues( const Vector3f & a_Start, const Vector3f & a_Direction ); //tolua_export - Vector3f BlockHitPosition; //tolua_export - Vector3f HitNormal; //tolua_export - Vector3f RealHit; //tolua_export -private: - int intersect3D_SegmentPlane( const Vector3f & a_Origin, const Vector3f & a_End, const Vector3f & a_PlanePos, const Vector3f & a_PlaneNormal ); - int GetHitNormal( const Vector3f & start, const Vector3f & end, const Vector3i & a_BlockPos); - float SigNum( float a_Num ); - cWorld* m_World; - - Vector3f m_NormalTable[6]; - - Vector3f dir; - Vector3f tDelta; - Vector3i pos; - Vector3i end1; - Vector3i step; - Vector3f tMax; +#pragma once + +#include "Vector3i.h" +#include "Vector3f.h" + + +class cWorld; +class cTracer //tolua_export +{ //tolua_export +public: //tolua_export + Vector3f DotPos; + Vector3f BoxOffset; + cTracer( cWorld* a_World); //tolua_export + ~cTracer(); //tolua_export + int Trace( const Vector3f & a_Start, const Vector3f & a_Direction, int a_Distance ); //tolua_export + void SetValues( const Vector3f & a_Start, const Vector3f & a_Direction ); //tolua_export + Vector3f BlockHitPosition; //tolua_export + Vector3f HitNormal; //tolua_export + Vector3f RealHit; //tolua_export +private: + int intersect3D_SegmentPlane( const Vector3f & a_Origin, const Vector3f & a_End, const Vector3f & a_PlanePos, const Vector3f & a_PlaneNormal ); + int GetHitNormal( const Vector3f & start, const Vector3f & end, const Vector3i & a_BlockPos); + float SigNum( float a_Num ); + cWorld* m_World; + + Vector3f m_NormalTable[6]; + + Vector3f dir; + Vector3f tDelta; + Vector3i pos; + Vector3i end1; + Vector3i step; + Vector3f tMax; }; //tolua_export \ No newline at end of file diff --git a/source/cWaterSimulator.cpp b/source/cWaterSimulator.cpp index 22f4ece00..642d54aac 100644 --- a/source/cWaterSimulator.cpp +++ b/source/cWaterSimulator.cpp @@ -1,22 +1,22 @@ -#include "Globals.h" -#include "cWaterSimulator.h" -#include "Defines.h" -#include "cWorld.h" - - - -cWaterSimulator::cWaterSimulator(cWorld *a_World) - : cFluidSimulator(a_World) -{ - m_FluidBlock = E_BLOCK_WATER; - m_StationaryFluidBlock = E_BLOCK_STATIONARY_WATER; - m_MaxHeight = 7; - m_FlowReduction = 1; -} - - -bool cWaterSimulator::IsAllowedBlock(char a_BlockID) -{ - return IsBlockWater(a_BlockID); -} - +#include "Globals.h" +#include "cWaterSimulator.h" +#include "Defines.h" +#include "cWorld.h" + + + +cWaterSimulator::cWaterSimulator(cWorld *a_World) + : cFluidSimulator(a_World) +{ + m_FluidBlock = E_BLOCK_WATER; + m_StationaryFluidBlock = E_BLOCK_STATIONARY_WATER; + m_MaxHeight = 7; + m_FlowReduction = 1; +} + + +bool cWaterSimulator::IsAllowedBlock(char a_BlockID) +{ + return IsBlockWater(a_BlockID); +} + diff --git a/source/cWaterSimulator.h b/source/cWaterSimulator.h index c00481482..7d4a4a19b 100644 --- a/source/cWaterSimulator.h +++ b/source/cWaterSimulator.h @@ -1,11 +1,11 @@ -#pragma once -#include "cFluidSimulator.h" - -class cWaterSimulator : public cFluidSimulator -{ -public: - cWaterSimulator( cWorld* a_World ); - - virtual bool IsAllowedBlock( char a_BlockID ); - +#pragma once +#include "cFluidSimulator.h" + +class cWaterSimulator : public cFluidSimulator +{ +public: + cWaterSimulator( cWorld* a_World ); + + virtual bool IsAllowedBlock( char a_BlockID ); + }; \ No newline at end of file diff --git a/source/cWebAdmin.cpp b/source/cWebAdmin.cpp index b05eedb16..33068ec38 100644 --- a/source/cWebAdmin.cpp +++ b/source/cWebAdmin.cpp @@ -1,383 +1,383 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cWebAdmin.h" -#include "cStringMap.h" - -#include "cWebPlugin.h" -#include "cWebPlugin_Lua.h" - -#include "cPluginManager.h" -#include "cPlugin.h" - -#include "cWorld.h" -#include "cPlayer.h" -#include "cServer.h" -#include "cRoot.h" - -#include "../iniFile/iniFile.h" - -#ifdef _WIN32 - #include -#else - #include -#endif - - - - - -/// Helper class - appends all player names together in a HTML list -class cPlayerAccum : - public cPlayerListCallback -{ - virtual bool Item(cPlayer * a_Player) override - { - m_Contents.append("
  • "); - m_Contents.append(a_Player->GetName()); - m_Contents.append("
  • "); - return false; - } - -public: - - AString m_Contents; -} ; - - - - - -cWebAdmin * WebAdmin = NULL; - - - - - -cWebAdmin::cWebAdmin( int a_Port /* = 8080 */ ) - : m_Port( a_Port ) - , m_bConnected( false ) -{ - WebAdmin = this; - m_Event = new cEvent(); - Init( m_Port ); -} - -cWebAdmin::~cWebAdmin() -{ - WebAdmin = 0; - m_WebServer->Stop(); - - while( m_Plugins.begin() != m_Plugins.end() ) - { - delete *m_Plugins.begin(); - //m_Plugins.remove( *m_Plugins.begin() ); - } - delete m_WebServer; - delete m_IniFile; - - m_Event->Wait(); - delete m_Event; -} - -void cWebAdmin::AddPlugin( cWebPlugin* a_Plugin ) -{ - m_Plugins.remove( a_Plugin ); - m_Plugins.push_back( a_Plugin ); -} - -void cWebAdmin::RemovePlugin( cWebPlugin* a_Plugin ) -{ - m_Plugins.remove( a_Plugin ); -} - - - - - -void cWebAdmin::Request_Handler(webserver::http_request* r) -{ - if( WebAdmin == 0 ) return; - LOG("Path: %s", r->path_.c_str() ); - - if (r->path_ == "/") - { - r->answer_ += "

    MCServer WebAdmin

    "; - r->answer_ += "
    "; - r->answer_ += "
    "; - r->answer_ += ""; - r->answer_ += "
    "; - r->answer_ += "
    "; - return; - } - - if (r->path_.empty() || r->path_[0] != '/') - { - r->answer_ += "

    Bad request

    "; - r->answer_ += "

    "; - r->answer_ = r->path_; // TODO: Shouldn't we sanitize this? Possible security issue. - r->answer_ += "

    "; - return; - } - - AStringVector Split = StringSplit(r->path_.substr(1), "/"); - - if (Split.empty() || (Split[0] != "webadmin")) - { - r->answer_ += "

    Bad request

    "; - return; - } - - if (!r->authentication_given_) - { - r->answer_ += "no auth"; - r->auth_realm_ = "MCServer WebAdmin"; - } - - std::string UserPassword = WebAdmin->m_IniFile->GetValue( "User:"+r->username_, "Password", ""); - if ((UserPassword != "") && (r->password_ == UserPassword)) - { - std::string BaseURL = "./"; - if (Split.size() > 1) - { - for (unsigned int i = 0; i < Split.size(); i++) - { - BaseURL += "../"; - } - BaseURL += "webadmin/"; - } - - std::string Menu; - std::string Content; - std::string Template = WebAdmin->GetTemplate(); - std::string FoundPlugin; - - for (PluginList::iterator itr = WebAdmin->m_Plugins.begin(); itr != WebAdmin->m_Plugins.end(); ++itr) - { - cWebPlugin* WebPlugin = *itr; - cWebPlugin_Lua* LuaPlugin = dynamic_cast< cWebPlugin_Lua* >( WebPlugin ); - if( LuaPlugin ) - { - std::list< std::pair > NameList = LuaPlugin->GetTabNames(); - for( std::list< std::pair >::iterator Names = NameList.begin(); Names != NameList.end(); ++Names ) - { - Menu += "
  • " + (*Names).first + "
  • "; - } - } - else - { - Menu += "
  • " + WebPlugin->GetName() + "
  • "; - } - } - - HTTPRequest Request; - Request.Username = r->username_; - Request.Method = r->method_; - Request.Params = r->params_; - Request.PostParams = r->params_post_; - Request.Path = r->path_.substr(1); - - for( unsigned int i = 0; i < r->multipart_formdata_.size(); ++i ) - { - webserver::formdata& fd = r->multipart_formdata_[i]; - - HTTPFormData HTTPfd;//( fd.value_ ); - HTTPfd.Value = fd.value_; - HTTPfd.Type = fd.content_type_; - HTTPfd.Name = fd.name_; - LOGINFO("Form data name: %s", fd.name_.c_str() ); - Request.FormData[ fd.name_ ] = HTTPfd; - } - - if( Split.size() > 1 ) - { - for( PluginList::iterator itr = WebAdmin->m_Plugins.begin(); itr != WebAdmin->m_Plugins.end(); ++itr ) - { - if( (*itr)->GetName() == Split[1] ) - { - Content = (*itr)->HandleRequest( &Request ); - cWebPlugin* WebPlugin = *itr; - FoundPlugin = WebPlugin->GetName(); - cWebPlugin_Lua* LuaPlugin = dynamic_cast< cWebPlugin_Lua* >( WebPlugin ); - if( LuaPlugin ) - { - FoundPlugin += " - " + LuaPlugin->GetTabNameForRequest( &Request ).first; - } - break; - } - } - } - - if( FoundPlugin.empty() ) // Default page - { - Content.clear(); - FoundPlugin = "Current Game"; - Content += "

    Server Name:

    "; - Content += "

    " + std::string( cRoot::Get()->GetServer()->GetServerID() ) + "

    "; - - Content += "

    Plugins:

      "; - cPluginManager* PM = cRoot::Get()->GetPluginManager(); - if( PM ) - { - const cPluginManager::PluginList & List = PM->GetAllPlugins(); - for( cPluginManager::PluginList::const_iterator itr = List.begin(); itr != List.end(); ++itr ) - { - AString VersionNum; - AppendPrintf(Content, "
    • %s V.%i
    • ", (*itr)->GetName(), (*itr)->GetVersion()); - } - } - Content += "
    "; - Content += "

    Players:

      "; - - cPlayerAccum PlayerAccum; - cWorld * World = cRoot::Get()->GetDefaultWorld(); // TODO - Create a list of worlds and players - World->ForEachPlayer(PlayerAccum); - Content.append(PlayerAccum.m_Contents); - Content += "

    "; - } - - - - if( Split.size() > 1 ) - { - Content += "\n

    Go back

    "; - } - - // mem usage -#ifndef _WIN32 - rusage resource_usage; - if (getrusage(RUSAGE_SELF, &resource_usage) != 0) - { - ReplaceString( Template, std::string("{MEM}"), "Error :(" ); - } - else - { - AString MemUsage; - Printf(MemUsage, "%0.2f", ((double)resource_usage.ru_maxrss / 1024 / 1024) ); - ReplaceString(Template, std::string("{MEM}"), MemUsage); - } -#else - HANDLE hProcess = GetCurrentProcess(); - PROCESS_MEMORY_COUNTERS pmc; - if( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc) ) ) - { - AString MemUsage; - Printf(MemUsage, "%0.2f", (pmc.WorkingSetSize / 1024.f / 1024.f) ); - ReplaceString( Template, "{MEM}", MemUsage ); - } -#endif - // end mem usage - - ReplaceString( Template, "{USERNAME}", r->username_ ); - ReplaceString( Template, "{MENU}", Menu ); - ReplaceString( Template, "{PLUGIN_NAME}", FoundPlugin ); - ReplaceString( Template, "{CONTENT}", Content ); - ReplaceString( Template, "{TITLE}", "MCServer" ); - - AString NumChunks; - Printf(NumChunks, "%d", cRoot::Get()->GetTotalChunkCount()); - ReplaceString(Template, "{NUMCHUNKS}", NumChunks); - - r->answer_ = Template; - } - else - { - r->answer_ += "Wrong username/password"; - r->auth_realm_ = "MCServer WebAdmin"; - } -} - - - - - -bool cWebAdmin::Init( int a_Port ) -{ - m_Port = a_Port; - - m_IniFile = new cIniFile("webadmin.ini"); - if( m_IniFile->ReadFile() ) - { - m_Port = m_IniFile->GetValueI("WebAdmin", "Port", 8080 ); - } - - LOG("Starting WebAdmin on port %i", m_Port); - -#ifdef _WIN32 - HANDLE hThread = CreateThread( - NULL, // default security - 0, // default stack size - ListenThread, // name of the thread function - this, // thread parameters - 0, // default startup flags - NULL); - CloseHandle( hThread ); // Just close the handle immediately -#else - pthread_t LstnThread; - pthread_create( &LstnThread, 0, ListenThread, this); -#endif - - return true; -} - - - - - -#ifdef _WIN32 -DWORD WINAPI cWebAdmin::ListenThread(LPVOID lpParam) -#else -void *cWebAdmin::ListenThread( void *lpParam ) -#endif -{ - cWebAdmin* self = (cWebAdmin*)lpParam; - - self->m_WebServer = new webserver(self->m_Port, Request_Handler ); - if (!self->m_WebServer->Begin()) - { - LOGWARN("WebServer failed to start! WebAdmin is disabled"); - } - - self->m_Event->Set(); - return 0; -} - - - - - -std::string cWebAdmin::GetTemplate() -{ - std::string retVal = ""; - - char SourceFile[] = "webadmin/template.html"; - - cFile f; - if (!f.Open(SourceFile, cFile::fmRead)) - { - return ""; - } - - // copy the file into the buffer: - f.ReadRestOfFile(retVal); - - return retVal; -} - - - - - -void cWebAdmin::RemovePlugin( lua_State* L ) -{ - for( PluginList::iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); ) - { - if( (*itr)->GetLuaState() == L ) - { - PluginList::iterator prev = itr++; - delete *prev; // deleting a dereferenced iterator also takes it out of the list, so no need for erase() - } - else - ++itr; - } -} + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cWebAdmin.h" +#include "cStringMap.h" + +#include "cWebPlugin.h" +#include "cWebPlugin_Lua.h" + +#include "cPluginManager.h" +#include "cPlugin.h" + +#include "cWorld.h" +#include "cPlayer.h" +#include "cServer.h" +#include "cRoot.h" + +#include "../iniFile/iniFile.h" + +#ifdef _WIN32 + #include +#else + #include +#endif + + + + + +/// Helper class - appends all player names together in a HTML list +class cPlayerAccum : + public cPlayerListCallback +{ + virtual bool Item(cPlayer * a_Player) override + { + m_Contents.append("
  • "); + m_Contents.append(a_Player->GetName()); + m_Contents.append("
  • "); + return false; + } + +public: + + AString m_Contents; +} ; + + + + + +cWebAdmin * WebAdmin = NULL; + + + + + +cWebAdmin::cWebAdmin( int a_Port /* = 8080 */ ) + : m_Port( a_Port ) + , m_bConnected( false ) +{ + WebAdmin = this; + m_Event = new cEvent(); + Init( m_Port ); +} + +cWebAdmin::~cWebAdmin() +{ + WebAdmin = 0; + m_WebServer->Stop(); + + while( m_Plugins.begin() != m_Plugins.end() ) + { + delete *m_Plugins.begin(); + //m_Plugins.remove( *m_Plugins.begin() ); + } + delete m_WebServer; + delete m_IniFile; + + m_Event->Wait(); + delete m_Event; +} + +void cWebAdmin::AddPlugin( cWebPlugin* a_Plugin ) +{ + m_Plugins.remove( a_Plugin ); + m_Plugins.push_back( a_Plugin ); +} + +void cWebAdmin::RemovePlugin( cWebPlugin* a_Plugin ) +{ + m_Plugins.remove( a_Plugin ); +} + + + + + +void cWebAdmin::Request_Handler(webserver::http_request* r) +{ + if( WebAdmin == 0 ) return; + LOG("Path: %s", r->path_.c_str() ); + + if (r->path_ == "/") + { + r->answer_ += "

    MCServer WebAdmin

    "; + r->answer_ += "
    "; + r->answer_ += "
    "; + r->answer_ += ""; + r->answer_ += "
    "; + r->answer_ += "
    "; + return; + } + + if (r->path_.empty() || r->path_[0] != '/') + { + r->answer_ += "

    Bad request

    "; + r->answer_ += "

    "; + r->answer_ = r->path_; // TODO: Shouldn't we sanitize this? Possible security issue. + r->answer_ += "

    "; + return; + } + + AStringVector Split = StringSplit(r->path_.substr(1), "/"); + + if (Split.empty() || (Split[0] != "webadmin")) + { + r->answer_ += "

    Bad request

    "; + return; + } + + if (!r->authentication_given_) + { + r->answer_ += "no auth"; + r->auth_realm_ = "MCServer WebAdmin"; + } + + std::string UserPassword = WebAdmin->m_IniFile->GetValue( "User:"+r->username_, "Password", ""); + if ((UserPassword != "") && (r->password_ == UserPassword)) + { + std::string BaseURL = "./"; + if (Split.size() > 1) + { + for (unsigned int i = 0; i < Split.size(); i++) + { + BaseURL += "../"; + } + BaseURL += "webadmin/"; + } + + std::string Menu; + std::string Content; + std::string Template = WebAdmin->GetTemplate(); + std::string FoundPlugin; + + for (PluginList::iterator itr = WebAdmin->m_Plugins.begin(); itr != WebAdmin->m_Plugins.end(); ++itr) + { + cWebPlugin* WebPlugin = *itr; + cWebPlugin_Lua* LuaPlugin = dynamic_cast< cWebPlugin_Lua* >( WebPlugin ); + if( LuaPlugin ) + { + std::list< std::pair > NameList = LuaPlugin->GetTabNames(); + for( std::list< std::pair >::iterator Names = NameList.begin(); Names != NameList.end(); ++Names ) + { + Menu += "
  • " + (*Names).first + "
  • "; + } + } + else + { + Menu += "
  • " + WebPlugin->GetName() + "
  • "; + } + } + + HTTPRequest Request; + Request.Username = r->username_; + Request.Method = r->method_; + Request.Params = r->params_; + Request.PostParams = r->params_post_; + Request.Path = r->path_.substr(1); + + for( unsigned int i = 0; i < r->multipart_formdata_.size(); ++i ) + { + webserver::formdata& fd = r->multipart_formdata_[i]; + + HTTPFormData HTTPfd;//( fd.value_ ); + HTTPfd.Value = fd.value_; + HTTPfd.Type = fd.content_type_; + HTTPfd.Name = fd.name_; + LOGINFO("Form data name: %s", fd.name_.c_str() ); + Request.FormData[ fd.name_ ] = HTTPfd; + } + + if( Split.size() > 1 ) + { + for( PluginList::iterator itr = WebAdmin->m_Plugins.begin(); itr != WebAdmin->m_Plugins.end(); ++itr ) + { + if( (*itr)->GetName() == Split[1] ) + { + Content = (*itr)->HandleRequest( &Request ); + cWebPlugin* WebPlugin = *itr; + FoundPlugin = WebPlugin->GetName(); + cWebPlugin_Lua* LuaPlugin = dynamic_cast< cWebPlugin_Lua* >( WebPlugin ); + if( LuaPlugin ) + { + FoundPlugin += " - " + LuaPlugin->GetTabNameForRequest( &Request ).first; + } + break; + } + } + } + + if( FoundPlugin.empty() ) // Default page + { + Content.clear(); + FoundPlugin = "Current Game"; + Content += "

    Server Name:

    "; + Content += "

    " + std::string( cRoot::Get()->GetServer()->GetServerID() ) + "

    "; + + Content += "

    Plugins:

      "; + cPluginManager* PM = cRoot::Get()->GetPluginManager(); + if( PM ) + { + const cPluginManager::PluginList & List = PM->GetAllPlugins(); + for( cPluginManager::PluginList::const_iterator itr = List.begin(); itr != List.end(); ++itr ) + { + AString VersionNum; + AppendPrintf(Content, "
    • %s V.%i
    • ", (*itr)->GetName(), (*itr)->GetVersion()); + } + } + Content += "
    "; + Content += "

    Players:

      "; + + cPlayerAccum PlayerAccum; + cWorld * World = cRoot::Get()->GetDefaultWorld(); // TODO - Create a list of worlds and players + World->ForEachPlayer(PlayerAccum); + Content.append(PlayerAccum.m_Contents); + Content += "

    "; + } + + + + if( Split.size() > 1 ) + { + Content += "\n

    Go back

    "; + } + + // mem usage +#ifndef _WIN32 + rusage resource_usage; + if (getrusage(RUSAGE_SELF, &resource_usage) != 0) + { + ReplaceString( Template, std::string("{MEM}"), "Error :(" ); + } + else + { + AString MemUsage; + Printf(MemUsage, "%0.2f", ((double)resource_usage.ru_maxrss / 1024 / 1024) ); + ReplaceString(Template, std::string("{MEM}"), MemUsage); + } +#else + HANDLE hProcess = GetCurrentProcess(); + PROCESS_MEMORY_COUNTERS pmc; + if( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc) ) ) + { + AString MemUsage; + Printf(MemUsage, "%0.2f", (pmc.WorkingSetSize / 1024.f / 1024.f) ); + ReplaceString( Template, "{MEM}", MemUsage ); + } +#endif + // end mem usage + + ReplaceString( Template, "{USERNAME}", r->username_ ); + ReplaceString( Template, "{MENU}", Menu ); + ReplaceString( Template, "{PLUGIN_NAME}", FoundPlugin ); + ReplaceString( Template, "{CONTENT}", Content ); + ReplaceString( Template, "{TITLE}", "MCServer" ); + + AString NumChunks; + Printf(NumChunks, "%d", cRoot::Get()->GetTotalChunkCount()); + ReplaceString(Template, "{NUMCHUNKS}", NumChunks); + + r->answer_ = Template; + } + else + { + r->answer_ += "Wrong username/password"; + r->auth_realm_ = "MCServer WebAdmin"; + } +} + + + + + +bool cWebAdmin::Init( int a_Port ) +{ + m_Port = a_Port; + + m_IniFile = new cIniFile("webadmin.ini"); + if( m_IniFile->ReadFile() ) + { + m_Port = m_IniFile->GetValueI("WebAdmin", "Port", 8080 ); + } + + LOG("Starting WebAdmin on port %i", m_Port); + +#ifdef _WIN32 + HANDLE hThread = CreateThread( + NULL, // default security + 0, // default stack size + ListenThread, // name of the thread function + this, // thread parameters + 0, // default startup flags + NULL); + CloseHandle( hThread ); // Just close the handle immediately +#else + pthread_t LstnThread; + pthread_create( &LstnThread, 0, ListenThread, this); +#endif + + return true; +} + + + + + +#ifdef _WIN32 +DWORD WINAPI cWebAdmin::ListenThread(LPVOID lpParam) +#else +void *cWebAdmin::ListenThread( void *lpParam ) +#endif +{ + cWebAdmin* self = (cWebAdmin*)lpParam; + + self->m_WebServer = new webserver(self->m_Port, Request_Handler ); + if (!self->m_WebServer->Begin()) + { + LOGWARN("WebServer failed to start! WebAdmin is disabled"); + } + + self->m_Event->Set(); + return 0; +} + + + + + +std::string cWebAdmin::GetTemplate() +{ + std::string retVal = ""; + + char SourceFile[] = "webadmin/template.html"; + + cFile f; + if (!f.Open(SourceFile, cFile::fmRead)) + { + return ""; + } + + // copy the file into the buffer: + f.ReadRestOfFile(retVal); + + return retVal; +} + + + + + +void cWebAdmin::RemovePlugin( lua_State* L ) +{ + for( PluginList::iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); ) + { + if( (*itr)->GetLuaState() == L ) + { + PluginList::iterator prev = itr++; + delete *prev; // deleting a dereferenced iterator also takes it out of the list, so no need for erase() + } + else + ++itr; + } +} diff --git a/source/cWebAdmin.h b/source/cWebAdmin.h index 3be9426ad..9eca47105 100644 --- a/source/cWebAdmin.h +++ b/source/cWebAdmin.h @@ -1,69 +1,69 @@ -#pragma once - -#include "../WebServer/WebServer.h" -#include "cSocket.h" - -class cStringMap; - -struct HTTPFormData //tolua_export -{ //tolua_export - std::string Name; //tolua_export - std::string Value; //tolua_export - std::string Type; //tolua_export -};//tolua_export - -struct HTTPRequest //tolua_export -{ //tolua_export - typedef std::map< std::string, std::string > StringStringMap; - typedef std::map< std::string, HTTPFormData > FormDataMap; - std::string Method; //tolua_export - std::string Path; //tolua_export - StringStringMap Params; // >> EXPORTED IN MANUALBINDINGS << - StringStringMap PostParams; // >> EXPORTED IN MANUALBINDINGS << - std::string Username; //tolua_export - FormDataMap FormData; // >> EXPORTED IN MANUALBINDINGS << -}; //tolua_export - -struct lua_State; -class cEvent; -class cIniFile; -class cWebPlugin; -class cWebAdmin -{ -public: - cWebAdmin( int a_Port = 8080 ); - ~cWebAdmin(); - - bool Init( int a_Port ); - - void AddPlugin( cWebPlugin* a_Plugin ); - void RemovePlugin( cWebPlugin* a_Plugin ); - - typedef std::list< cWebPlugin* > PluginList; - PluginList GetPlugins() { return m_Plugins; } - - static void Request_Handler(webserver::http_request* r); - - void RemovePlugin( lua_State* L ); -private: - -#ifdef _WIN32 - static DWORD WINAPI ListenThread(LPVOID lpParam); -#else - static void *ListenThread( void *lpParam ); -#endif - - std::string GetTemplate(); - - int m_Port; - - bool m_bConnected; - cSocket m_ListenSocket; - - cIniFile* m_IniFile; - PluginList m_Plugins; - - cEvent* m_Event; - - webserver* m_WebServer; +#pragma once + +#include "../WebServer/WebServer.h" +#include "cSocket.h" + +class cStringMap; + +struct HTTPFormData //tolua_export +{ //tolua_export + std::string Name; //tolua_export + std::string Value; //tolua_export + std::string Type; //tolua_export +};//tolua_export + +struct HTTPRequest //tolua_export +{ //tolua_export + typedef std::map< std::string, std::string > StringStringMap; + typedef std::map< std::string, HTTPFormData > FormDataMap; + std::string Method; //tolua_export + std::string Path; //tolua_export + StringStringMap Params; // >> EXPORTED IN MANUALBINDINGS << + StringStringMap PostParams; // >> EXPORTED IN MANUALBINDINGS << + std::string Username; //tolua_export + FormDataMap FormData; // >> EXPORTED IN MANUALBINDINGS << +}; //tolua_export + +struct lua_State; +class cEvent; +class cIniFile; +class cWebPlugin; +class cWebAdmin +{ +public: + cWebAdmin( int a_Port = 8080 ); + ~cWebAdmin(); + + bool Init( int a_Port ); + + void AddPlugin( cWebPlugin* a_Plugin ); + void RemovePlugin( cWebPlugin* a_Plugin ); + + typedef std::list< cWebPlugin* > PluginList; + PluginList GetPlugins() { return m_Plugins; } + + static void Request_Handler(webserver::http_request* r); + + void RemovePlugin( lua_State* L ); +private: + +#ifdef _WIN32 + static DWORD WINAPI ListenThread(LPVOID lpParam); +#else + static void *ListenThread( void *lpParam ); +#endif + + std::string GetTemplate(); + + int m_Port; + + bool m_bConnected; + cSocket m_ListenSocket; + + cIniFile* m_IniFile; + PluginList m_Plugins; + + cEvent* m_Event; + + webserver* m_WebServer; }; \ No newline at end of file diff --git a/source/cWebPlugin.cpp b/source/cWebPlugin.cpp index 923c48722..186662ba8 100644 --- a/source/cWebPlugin.cpp +++ b/source/cWebPlugin.cpp @@ -1,26 +1,26 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cWebPlugin.h" -#include "cWebAdmin.h" -#include "cServer.h" -#include "cRoot.h" - - - - - -cWebPlugin::cWebPlugin( lua_State* L ) -{ - LOG("cWebPlugin::cWebPlugin()"); - m_LuaState = L; - cWebAdmin* WebAdmin = cRoot::Get()->GetWebAdmin(); - if( WebAdmin ) WebAdmin->AddPlugin( this ); -} - -cWebPlugin::~cWebPlugin() -{ - LOG("~cWebPlugin::cWebPlugin()"); - cWebAdmin* WebAdmin = cRoot::Get()->GetWebAdmin(); - if( WebAdmin ) WebAdmin->RemovePlugin( this ); + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cWebPlugin.h" +#include "cWebAdmin.h" +#include "cServer.h" +#include "cRoot.h" + + + + + +cWebPlugin::cWebPlugin( lua_State* L ) +{ + LOG("cWebPlugin::cWebPlugin()"); + m_LuaState = L; + cWebAdmin* WebAdmin = cRoot::Get()->GetWebAdmin(); + if( WebAdmin ) WebAdmin->AddPlugin( this ); +} + +cWebPlugin::~cWebPlugin() +{ + LOG("~cWebPlugin::cWebPlugin()"); + cWebAdmin* WebAdmin = cRoot::Get()->GetWebAdmin(); + if( WebAdmin ) WebAdmin->RemovePlugin( this ); } \ No newline at end of file diff --git a/source/cWebPlugin.h b/source/cWebPlugin.h index 1faf4e9ae..e6eb00559 100644 --- a/source/cWebPlugin.h +++ b/source/cWebPlugin.h @@ -1,24 +1,24 @@ - -#pragma once - -struct lua_State; -struct HTTPRequest; -//tolua_begin -class cWebPlugin -{ -public: - cWebPlugin( lua_State* L ); - virtual ~cWebPlugin(); - - void SetName( std::string a_Name ) { m_Name = a_Name; } - std::string GetName() { return m_Name; } - - virtual std::string HandleRequest( HTTPRequest* a_Request ) = 0; - virtual void Initialize() = 0; - //tolua_end - - lua_State* GetLuaState() { return m_LuaState; } -private: - lua_State* m_LuaState; - std::string m_Name; + +#pragma once + +struct lua_State; +struct HTTPRequest; +//tolua_begin +class cWebPlugin +{ +public: + cWebPlugin( lua_State* L ); + virtual ~cWebPlugin(); + + void SetName( std::string a_Name ) { m_Name = a_Name; } + std::string GetName() { return m_Name; } + + virtual std::string HandleRequest( HTTPRequest* a_Request ) = 0; + virtual void Initialize() = 0; + //tolua_end + + lua_State* GetLuaState() { return m_LuaState; } +private: + lua_State* m_LuaState; + std::string m_Name; }; //tolua_export \ No newline at end of file diff --git a/source/cWebPlugin_Lua.cpp b/source/cWebPlugin_Lua.cpp index ab397173e..e22c59961 100644 --- a/source/cWebPlugin_Lua.cpp +++ b/source/cWebPlugin_Lua.cpp @@ -1,185 +1,185 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cWebPlugin_Lua.h" -#include "cPlugin_NewLua.h" - -#include "tolua++.h" -#include "cWebAdmin.h" - - - - - -extern bool report_errors(lua_State* lua, int status); - - - - - -static std::string SafeString( const std::string& a_String ) -{ - std::string RetVal; - for( unsigned int i = 0; i < a_String.size(); ++i ) - { - char c = a_String[i]; - if( c == ' ' ) - { - c = '_'; - } - RetVal.push_back( c ); - } - return RetVal; -} - - - - - -struct cWebPlugin_Lua::sWebPluginTab -{ - std::string Title; - std::string SafeTitle; - - int Reference; -}; - -cWebPlugin_Lua::cWebPlugin_Lua( cPlugin_NewLua* a_Plugin ) - : cWebPlugin( a_Plugin->GetLuaState() ) - , m_Plugin( a_Plugin ) -{ - -} - -cWebPlugin_Lua::~cWebPlugin_Lua() -{ - for( TabList::iterator itr = m_Tabs.begin(); itr != m_Tabs.end(); ++itr ) - { - delete *itr; - } - m_Tabs.clear(); -} - -bool cWebPlugin_Lua::AddTab( const char* a_Title, lua_State * a_LuaState, int a_FunctionReference ) -{ - if( a_LuaState != m_Plugin->GetLuaState() ) - { - LOGERROR("Only allowed to add a tab to a WebPlugin of your own Plugin!"); - return false; - } - sWebPluginTab* Tab = new sWebPluginTab(); - Tab->Title = a_Title; - Tab->SafeTitle = SafeString( a_Title ); - - Tab->Reference = a_FunctionReference; - - m_Tabs.push_back( Tab ); - return true; -} - -std::string cWebPlugin_Lua::HandleRequest( HTTPRequest* a_Request ) -{ - lua_State* LuaState = m_Plugin->GetLuaState(); - std::string RetVal = ""; - - std::pair< std::string, std::string > TabName = GetTabNameForRequest(a_Request); - std::string SafeTabName = TabName.second; - if( SafeTabName.empty() ) - return ""; - - sWebPluginTab* Tab = 0; - for( TabList::iterator itr = m_Tabs.begin(); itr != m_Tabs.end(); ++itr ) - { - if( (*itr)->SafeTitle.compare( SafeTabName ) == 0 ) // This is the one! Rawr - { - Tab = *itr; - break; - } - } - - if( Tab ) - { - //LOGINFO("1. Stack size: %i", lua_gettop(LuaState) ); - lua_rawgeti( LuaState, LUA_REGISTRYINDEX, Tab->Reference); // same as lua_getref() - - //LOGINFO("2. Stack size: %i", lua_gettop(LuaState) ); - // Push HTTPRequest - tolua_pushusertype( LuaState, a_Request, "HTTPRequest" ); - //LOGINFO("Calling bound function! :D"); - int s = lua_pcall( LuaState, 1, 1, 0); - - if ( s != 0 ) - { - std::string err = lua_tostring(LuaState, -1); - LOGERROR("-- %s", err.c_str() ); - lua_pop(LuaState, 1); - LOGINFO("error. Stack size: %i", lua_gettop(LuaState) ); - return err; // Show the error message in the web page, looks cool - } - - if( !lua_isstring( LuaState, -1 ) ) - { - LOGWARN("WARNING: WebPlugin tab '%s' did not return a string!", Tab->Title.c_str() ); - lua_pop(LuaState, 1); // Pop return value - return std::string("WARNING: WebPlugin tab '") + Tab->Title + std::string("' did not return a string!"); - } - - RetVal += tolua_tostring(LuaState, -1, 0); - lua_pop(LuaState, 1); // Pop return value - //LOGINFO("ok. Stack size: %i", lua_gettop(LuaState) ); - } - - return RetVal; -} - -void cWebPlugin_Lua::Initialize() -{ -} - -std::pair< std::string, std::string > cWebPlugin_Lua::GetTabNameForRequest( HTTPRequest* a_Request ) -{ - std::pair< std::string, std::string > Names; - AStringVector Split = StringSplit(a_Request->Path, "/"); - - if( Split.size() > 1 ) - { - sWebPluginTab* Tab = 0; - if( Split.size() > 2 ) // If we got the tab name, show that page - { - for( TabList::iterator itr = m_Tabs.begin(); itr != m_Tabs.end(); ++itr ) - { - if( (*itr)->SafeTitle.compare( Split[2] ) == 0 ) // This is the one! Rawr - { - Tab = *itr; - break; - } - } - } - else // Otherwise show the first tab - { - if( m_Tabs.size() > 0 ) - Tab = *m_Tabs.begin(); - } - - if( Tab ) - { - Names.first = Tab->Title; - Names.second = Tab->SafeTitle; - } - } - - return Names; -} - -std::list< std::pair > cWebPlugin_Lua::GetTabNames() -{ - std::list< std::pair< std::string, std::string > > NameList; - for( TabList::iterator itr = m_Tabs.begin(); itr != m_Tabs.end(); ++itr ) - { - std::pair< std::string, std::string > StringPair; - StringPair.first = (*itr)->Title; - StringPair.second = (*itr)->SafeTitle; - NameList.push_back( StringPair ); - } - return NameList; + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cWebPlugin_Lua.h" +#include "cPlugin_NewLua.h" + +#include "tolua++.h" +#include "cWebAdmin.h" + + + + + +extern bool report_errors(lua_State* lua, int status); + + + + + +static std::string SafeString( const std::string& a_String ) +{ + std::string RetVal; + for( unsigned int i = 0; i < a_String.size(); ++i ) + { + char c = a_String[i]; + if( c == ' ' ) + { + c = '_'; + } + RetVal.push_back( c ); + } + return RetVal; +} + + + + + +struct cWebPlugin_Lua::sWebPluginTab +{ + std::string Title; + std::string SafeTitle; + + int Reference; +}; + +cWebPlugin_Lua::cWebPlugin_Lua( cPlugin_NewLua* a_Plugin ) + : cWebPlugin( a_Plugin->GetLuaState() ) + , m_Plugin( a_Plugin ) +{ + +} + +cWebPlugin_Lua::~cWebPlugin_Lua() +{ + for( TabList::iterator itr = m_Tabs.begin(); itr != m_Tabs.end(); ++itr ) + { + delete *itr; + } + m_Tabs.clear(); +} + +bool cWebPlugin_Lua::AddTab( const char* a_Title, lua_State * a_LuaState, int a_FunctionReference ) +{ + if( a_LuaState != m_Plugin->GetLuaState() ) + { + LOGERROR("Only allowed to add a tab to a WebPlugin of your own Plugin!"); + return false; + } + sWebPluginTab* Tab = new sWebPluginTab(); + Tab->Title = a_Title; + Tab->SafeTitle = SafeString( a_Title ); + + Tab->Reference = a_FunctionReference; + + m_Tabs.push_back( Tab ); + return true; +} + +std::string cWebPlugin_Lua::HandleRequest( HTTPRequest* a_Request ) +{ + lua_State* LuaState = m_Plugin->GetLuaState(); + std::string RetVal = ""; + + std::pair< std::string, std::string > TabName = GetTabNameForRequest(a_Request); + std::string SafeTabName = TabName.second; + if( SafeTabName.empty() ) + return ""; + + sWebPluginTab* Tab = 0; + for( TabList::iterator itr = m_Tabs.begin(); itr != m_Tabs.end(); ++itr ) + { + if( (*itr)->SafeTitle.compare( SafeTabName ) == 0 ) // This is the one! Rawr + { + Tab = *itr; + break; + } + } + + if( Tab ) + { + //LOGINFO("1. Stack size: %i", lua_gettop(LuaState) ); + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, Tab->Reference); // same as lua_getref() + + //LOGINFO("2. Stack size: %i", lua_gettop(LuaState) ); + // Push HTTPRequest + tolua_pushusertype( LuaState, a_Request, "HTTPRequest" ); + //LOGINFO("Calling bound function! :D"); + int s = lua_pcall( LuaState, 1, 1, 0); + + if ( s != 0 ) + { + std::string err = lua_tostring(LuaState, -1); + LOGERROR("-- %s", err.c_str() ); + lua_pop(LuaState, 1); + LOGINFO("error. Stack size: %i", lua_gettop(LuaState) ); + return err; // Show the error message in the web page, looks cool + } + + if( !lua_isstring( LuaState, -1 ) ) + { + LOGWARN("WARNING: WebPlugin tab '%s' did not return a string!", Tab->Title.c_str() ); + lua_pop(LuaState, 1); // Pop return value + return std::string("WARNING: WebPlugin tab '") + Tab->Title + std::string("' did not return a string!"); + } + + RetVal += tolua_tostring(LuaState, -1, 0); + lua_pop(LuaState, 1); // Pop return value + //LOGINFO("ok. Stack size: %i", lua_gettop(LuaState) ); + } + + return RetVal; +} + +void cWebPlugin_Lua::Initialize() +{ +} + +std::pair< std::string, std::string > cWebPlugin_Lua::GetTabNameForRequest( HTTPRequest* a_Request ) +{ + std::pair< std::string, std::string > Names; + AStringVector Split = StringSplit(a_Request->Path, "/"); + + if( Split.size() > 1 ) + { + sWebPluginTab* Tab = 0; + if( Split.size() > 2 ) // If we got the tab name, show that page + { + for( TabList::iterator itr = m_Tabs.begin(); itr != m_Tabs.end(); ++itr ) + { + if( (*itr)->SafeTitle.compare( Split[2] ) == 0 ) // This is the one! Rawr + { + Tab = *itr; + break; + } + } + } + else // Otherwise show the first tab + { + if( m_Tabs.size() > 0 ) + Tab = *m_Tabs.begin(); + } + + if( Tab ) + { + Names.first = Tab->Title; + Names.second = Tab->SafeTitle; + } + } + + return Names; +} + +std::list< std::pair > cWebPlugin_Lua::GetTabNames() +{ + std::list< std::pair< std::string, std::string > > NameList; + for( TabList::iterator itr = m_Tabs.begin(); itr != m_Tabs.end(); ++itr ) + { + std::pair< std::string, std::string > StringPair; + StringPair.first = (*itr)->Title; + StringPair.second = (*itr)->SafeTitle; + NameList.push_back( StringPair ); + } + return NameList; } \ No newline at end of file diff --git a/source/cWebPlugin_Lua.h b/source/cWebPlugin_Lua.h index 0444fb44f..a63ddf323 100644 --- a/source/cWebPlugin_Lua.h +++ b/source/cWebPlugin_Lua.h @@ -1,29 +1,29 @@ -#pragma once - -#include "cWebPlugin.h" - -class cPlugin_NewLua; -typedef struct lua_State lua_State; - -// a WebPlugin class more specialized for Lua -class cWebPlugin_Lua : public cWebPlugin //tolua_export -{ //tolua_export -public: //tolua_export - cWebPlugin_Lua( cPlugin_NewLua* a_Plugin ); - virtual ~cWebPlugin_Lua(); - - bool AddTab( const char* a_Title, lua_State * a_LuaState, int a_FunctionReference ); // >> EXPORTED IN MANUALBINDINGS << - - virtual std::string HandleRequest( HTTPRequest* a_Request ); - virtual void Initialize(); - - std::pair< std::string, std::string > GetTabNameForRequest( HTTPRequest* a_Request ); - - std::list< std::pair > GetTabNames(); -private: - cPlugin_NewLua* m_Plugin; - - struct sWebPluginTab; - typedef std::list< sWebPluginTab* > TabList; - TabList m_Tabs; +#pragma once + +#include "cWebPlugin.h" + +class cPlugin_NewLua; +typedef struct lua_State lua_State; + +// a WebPlugin class more specialized for Lua +class cWebPlugin_Lua : public cWebPlugin //tolua_export +{ //tolua_export +public: //tolua_export + cWebPlugin_Lua( cPlugin_NewLua* a_Plugin ); + virtual ~cWebPlugin_Lua(); + + bool AddTab( const char* a_Title, lua_State * a_LuaState, int a_FunctionReference ); // >> EXPORTED IN MANUALBINDINGS << + + virtual std::string HandleRequest( HTTPRequest* a_Request ); + virtual void Initialize(); + + std::pair< std::string, std::string > GetTabNameForRequest( HTTPRequest* a_Request ); + + std::list< std::pair > GetTabNames(); +private: + cPlugin_NewLua* m_Plugin; + + struct sWebPluginTab; + typedef std::list< sWebPluginTab* > TabList; + TabList m_Tabs; }; //tolua_export \ No newline at end of file diff --git a/source/cWindow.cpp b/source/cWindow.cpp index 8c5d78495..fe029cfd9 100644 --- a/source/cWindow.cpp +++ b/source/cWindow.cpp @@ -1,332 +1,332 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cWindow.h" -#include "cItem.h" -#include "cClientHandle.h" -#include "cPlayer.h" -#include "cPickup.h" -#include "cInventory.h" -#include "cWindowOwner.h" - -#include "packets/cPacket_WindowClick.h" -#include "packets/cPacket_WholeInventory.h" -#include "packets/cPacket_WindowOpen.h" -#include "packets/cPacket_WindowClose.h" - - - - - -cWindow::cWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible ) - : m_WindowID( 0 ) - , m_WindowType( 0 ) - , m_Owner( a_Owner ) - , m_bInventoryVisible( a_bInventoryVisible ) - , m_NumSlots( 0 ) - , m_Slots( 0 ) - , m_DraggingItem( 0 ) - , m_IsDestroyed(false) -{ - LOGD("Created a window at %p", this); - if( !m_bInventoryVisible ) m_DraggingItem = new cItem(); -} - - - - - -cWindow::~cWindow() -{ - LOGD("Deleting a window at %p", this); - if( !m_bInventoryVisible && m_DraggingItem ) - { - delete m_DraggingItem; - m_DraggingItem = 0; - } - LOGD("Deleted a window at %p", this); -} - - - - - -cItem* cWindow::GetSlot( int a_Slot ) -{ - if(a_Slot > -1 && a_Slot < m_NumSlots) - { - return (m_Slots + a_Slot); - } - return 0; -} - - - - - -cItem* cWindow::GetDraggingItem( cPlayer * a_Player /* = 0 */ ) -{ - if( m_bInventoryVisible && a_Player ) - { - cWindow* Window = a_Player->GetInventory().GetWindow(); - if( Window ) - { - return Window->GetDraggingItem(); - } - } - return m_DraggingItem; -} - - - - - -void cWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ) -{ - if( a_ClickPacket->m_WindowID != m_WindowID ) - { - LOG("WRONG WINDOW ID! (exp %d, got %d)", m_WindowID, a_ClickPacket->m_WindowID); - return; - } - - if( m_bInventoryVisible ) - { - cWindow* Window = a_Player.GetInventory().GetWindow(); - if( Window ) - { - m_DraggingItem = Window->GetDraggingItem(); - } - } - bool bAsync = false; - if( a_ClickPacket->m_SlotNum == -999 ) // Outside window click - { - if( a_ClickPacket->m_RightMouse ) - a_Player.TossItem( true ); - else - a_Player.TossItem( true, m_DraggingItem->m_ItemCount ); - } - else if( GetSlot( a_ClickPacket->m_SlotNum ) != 0 ) - { - cItem* Item = GetSlot( a_ClickPacket->m_SlotNum ); - if( a_ClickPacket->m_ItemID != Item->m_ItemID - || a_ClickPacket->m_ItemCount != Item->m_ItemCount - || a_ClickPacket->m_ItemUses != Item->m_ItemHealth ) - { - if( !((a_ClickPacket->m_ItemID == -1 || a_ClickPacket->m_ItemID == 0) && (Item->m_ItemID == -1 || Item->m_ItemID == 0 )) ) - { - LOGD("My ID: %i Their ID: %i", Item->m_ItemID, a_ClickPacket->m_ItemID ); - LOGD("My Count: %i Their Count: %i", Item->m_ItemCount, a_ClickPacket->m_ItemCount ); - LOGD("My Uses: %i Their Uses: %i", Item->m_ItemHealth, a_ClickPacket->m_ItemUses ); - bAsync = true; - } - } - } - if( m_DraggingItem && a_ClickPacket->m_SlotNum > -1 && a_ClickPacket->m_SlotNum < m_NumSlots ) - { - if( a_ClickPacket->m_RightMouse == 0 ) - { - if( !m_DraggingItem->Equals( m_Slots[a_ClickPacket->m_SlotNum] ) ) - { - cItem tmp( *m_DraggingItem ); - *m_DraggingItem = m_Slots[a_ClickPacket->m_SlotNum]; - m_Slots[a_ClickPacket->m_SlotNum] = tmp; // Switch contents - } - else - { - int FreeSlots = 64 - m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount; - int Filling = (FreeSlots > m_DraggingItem->m_ItemCount) ? m_DraggingItem->m_ItemCount : FreeSlots; - m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount += (char)Filling; - m_DraggingItem->m_ItemCount -= (char)Filling; - if( m_DraggingItem->m_ItemCount <= 0 ) - m_DraggingItem->Empty(); - } - } - else // Right clicked - { - if( m_DraggingItem->m_ItemID <= 0 ) // Empty? - { - m_DraggingItem->m_ItemCount = (char)(((float)m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount)/2.f + 0.5f); - m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount -= m_DraggingItem->m_ItemCount; - m_DraggingItem->m_ItemID = m_Slots[a_ClickPacket->m_SlotNum].m_ItemID; - m_DraggingItem->m_ItemHealth = m_Slots[a_ClickPacket->m_SlotNum].m_ItemHealth; - - if( m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount <= 0 ) - { - m_Slots[a_ClickPacket->m_SlotNum].Empty(); - } - } - else if( m_Slots[a_ClickPacket->m_SlotNum].m_ItemID <= 0 || m_DraggingItem->Equals( m_Slots[a_ClickPacket->m_SlotNum] ) ) - { // Drop one item in slot - if( m_DraggingItem->m_ItemCount > 0 && m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount < 64 ) - { - m_Slots[a_ClickPacket->m_SlotNum].m_ItemID = m_DraggingItem->m_ItemID; - m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount++; - m_Slots[a_ClickPacket->m_SlotNum].m_ItemHealth = m_DraggingItem->m_ItemHealth; - m_DraggingItem->m_ItemCount--; - } - if( m_DraggingItem->m_ItemCount <= 0 ) - { - m_DraggingItem->Empty(); - } - } - else if( !m_DraggingItem->Equals( m_Slots[a_ClickPacket->m_SlotNum]) ) // Swap contents - { - cItem tmp( *m_DraggingItem ); - *m_DraggingItem = m_Slots[a_ClickPacket->m_SlotNum]; - m_Slots[a_ClickPacket->m_SlotNum] = tmp; // Switch contents - } - } - if( bAsync ) - { - LOG("Window is not synchonous with client. Sending whole window. ID: %i", m_WindowID); - for( std::list< cPlayer* >::iterator itr = m_OpenedBy.begin(); itr != m_OpenedBy.end(); ++itr ) - { - SendWholeWindow( (*itr)->GetClientHandle() ); - } - if( m_bInventoryVisible || m_OpenedBy.size() == 0 ) - { - a_Player.GetInventory().SendWholeInventory( a_Player.GetClientHandle() ); - } - } - } - else if( m_bInventoryVisible ) // Click in player inventory - { - a_ClickPacket->m_WindowID = 0; - a_ClickPacket->m_SlotNum -= (short)(m_NumSlots - 9); - cWindow* Window = a_Player.GetInventory().GetWindow(); - if( Window ) - { - Window->Clicked( a_ClickPacket, a_Player ); - } - } - if (m_DraggingItem != NULL) - { - LOGD("Dragging: %i", m_DraggingItem->m_ItemCount ); - } -} - - - - - -void cWindow::Open( cPlayer & a_Player ) -{ - { - cCSLock Lock(m_CS); - // If player is already in OpenedBy remove player first - m_OpenedBy.remove( &a_Player ); - // Then add player - m_OpenedBy.push_back( &a_Player ); - } - - cPacket_WindowOpen WindowOpen; - WindowOpen.m_WindowID = (char)m_WindowID; - WindowOpen.m_InventoryType = (char)m_WindowType; - WindowOpen.m_WindowTitle = m_WindowTitle; - WindowOpen.m_NumSlots = (char)m_NumSlots; - a_Player.GetClientHandle()->Send( WindowOpen ); -} - - - - - -void cWindow::Close( cPlayer & a_Player ) -{ - //Checks wheather the player is still holding an item - if(m_DraggingItem && m_DraggingItem->m_ItemCount > 0) - { - LOG("Player holds item! Dropping it..."); - a_Player.TossItem( true, m_DraggingItem->m_ItemCount ); - } - - cPacket_WindowClose WindowClose; - WindowClose.m_Close = (char)m_WindowID; - cClientHandle * ClientHandle = a_Player.GetClientHandle(); - if ( ClientHandle != NULL) - { - ClientHandle->Send( WindowClose ); - } - - { - cCSLock Lock(m_CS); - m_OpenedBy.remove( &a_Player ); - if( m_OpenedBy.size() == 0 ) - { - Destroy(); - } - } - if (m_IsDestroyed) - { - delete this; - } -} - - - - - -void cWindow::OwnerDestroyed() -{ - m_Owner = 0; - while( m_OpenedBy.size() > 1 ) - { - (*m_OpenedBy.begin() )->CloseWindow((char)GetWindowType()); - } - (*m_OpenedBy.begin() )->CloseWindow((char)GetWindowType()); -} - - - - - -void cWindow::Destroy() -{ - LOGD("Destroying window %p (type %d)", this, m_WindowType); - if (m_Owner != NULL) - { - m_Owner->CloseWindow(); - m_Owner = NULL; - } - m_IsDestroyed = true; -} - - - - - -void cWindow::SendWholeWindow( cClientHandle* a_Client ) -{ - cPacket_WholeInventory Inventory( this ); - a_Client->Send( Inventory ); -} - - - - - -void cWindow::BroadcastWholeWindow(void) -{ - cCSLock Lock(m_CS); - for (cPlayerList::iterator itr = m_OpenedBy.begin(); itr != m_OpenedBy.end(); ++itr) - { - SendWholeWindow((*itr)->GetClientHandle()); - } // for itr - m_OpenedBy[] -} - - - - - -void cWindow::Broadcast(const cPacket & a_Packet) -{ - cCSLock Lock(m_CS); - for (cPlayerList::iterator itr = m_OpenedBy.begin(); itr != m_OpenedBy.end(); ++itr) - { - (*itr)->GetClientHandle()->Send(a_Packet); - } // for itr - m_OpenedBy[] -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cWindow.h" +#include "cItem.h" +#include "cClientHandle.h" +#include "cPlayer.h" +#include "cPickup.h" +#include "cInventory.h" +#include "cWindowOwner.h" + +#include "packets/cPacket_WindowClick.h" +#include "packets/cPacket_WholeInventory.h" +#include "packets/cPacket_WindowOpen.h" +#include "packets/cPacket_WindowClose.h" + + + + + +cWindow::cWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible ) + : m_WindowID( 0 ) + , m_WindowType( 0 ) + , m_Owner( a_Owner ) + , m_bInventoryVisible( a_bInventoryVisible ) + , m_NumSlots( 0 ) + , m_Slots( 0 ) + , m_DraggingItem( 0 ) + , m_IsDestroyed(false) +{ + LOGD("Created a window at %p", this); + if( !m_bInventoryVisible ) m_DraggingItem = new cItem(); +} + + + + + +cWindow::~cWindow() +{ + LOGD("Deleting a window at %p", this); + if( !m_bInventoryVisible && m_DraggingItem ) + { + delete m_DraggingItem; + m_DraggingItem = 0; + } + LOGD("Deleted a window at %p", this); +} + + + + + +cItem* cWindow::GetSlot( int a_Slot ) +{ + if(a_Slot > -1 && a_Slot < m_NumSlots) + { + return (m_Slots + a_Slot); + } + return 0; +} + + + + + +cItem* cWindow::GetDraggingItem( cPlayer * a_Player /* = 0 */ ) +{ + if( m_bInventoryVisible && a_Player ) + { + cWindow* Window = a_Player->GetInventory().GetWindow(); + if( Window ) + { + return Window->GetDraggingItem(); + } + } + return m_DraggingItem; +} + + + + + +void cWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ) +{ + if( a_ClickPacket->m_WindowID != m_WindowID ) + { + LOG("WRONG WINDOW ID! (exp %d, got %d)", m_WindowID, a_ClickPacket->m_WindowID); + return; + } + + if( m_bInventoryVisible ) + { + cWindow* Window = a_Player.GetInventory().GetWindow(); + if( Window ) + { + m_DraggingItem = Window->GetDraggingItem(); + } + } + bool bAsync = false; + if( a_ClickPacket->m_SlotNum == -999 ) // Outside window click + { + if( a_ClickPacket->m_RightMouse ) + a_Player.TossItem( true ); + else + a_Player.TossItem( true, m_DraggingItem->m_ItemCount ); + } + else if( GetSlot( a_ClickPacket->m_SlotNum ) != 0 ) + { + cItem* Item = GetSlot( a_ClickPacket->m_SlotNum ); + if( a_ClickPacket->m_ItemID != Item->m_ItemID + || a_ClickPacket->m_ItemCount != Item->m_ItemCount + || a_ClickPacket->m_ItemUses != Item->m_ItemHealth ) + { + if( !((a_ClickPacket->m_ItemID == -1 || a_ClickPacket->m_ItemID == 0) && (Item->m_ItemID == -1 || Item->m_ItemID == 0 )) ) + { + LOGD("My ID: %i Their ID: %i", Item->m_ItemID, a_ClickPacket->m_ItemID ); + LOGD("My Count: %i Their Count: %i", Item->m_ItemCount, a_ClickPacket->m_ItemCount ); + LOGD("My Uses: %i Their Uses: %i", Item->m_ItemHealth, a_ClickPacket->m_ItemUses ); + bAsync = true; + } + } + } + if( m_DraggingItem && a_ClickPacket->m_SlotNum > -1 && a_ClickPacket->m_SlotNum < m_NumSlots ) + { + if( a_ClickPacket->m_RightMouse == 0 ) + { + if( !m_DraggingItem->Equals( m_Slots[a_ClickPacket->m_SlotNum] ) ) + { + cItem tmp( *m_DraggingItem ); + *m_DraggingItem = m_Slots[a_ClickPacket->m_SlotNum]; + m_Slots[a_ClickPacket->m_SlotNum] = tmp; // Switch contents + } + else + { + int FreeSlots = 64 - m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount; + int Filling = (FreeSlots > m_DraggingItem->m_ItemCount) ? m_DraggingItem->m_ItemCount : FreeSlots; + m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount += (char)Filling; + m_DraggingItem->m_ItemCount -= (char)Filling; + if( m_DraggingItem->m_ItemCount <= 0 ) + m_DraggingItem->Empty(); + } + } + else // Right clicked + { + if( m_DraggingItem->m_ItemID <= 0 ) // Empty? + { + m_DraggingItem->m_ItemCount = (char)(((float)m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount)/2.f + 0.5f); + m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount -= m_DraggingItem->m_ItemCount; + m_DraggingItem->m_ItemID = m_Slots[a_ClickPacket->m_SlotNum].m_ItemID; + m_DraggingItem->m_ItemHealth = m_Slots[a_ClickPacket->m_SlotNum].m_ItemHealth; + + if( m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount <= 0 ) + { + m_Slots[a_ClickPacket->m_SlotNum].Empty(); + } + } + else if( m_Slots[a_ClickPacket->m_SlotNum].m_ItemID <= 0 || m_DraggingItem->Equals( m_Slots[a_ClickPacket->m_SlotNum] ) ) + { // Drop one item in slot + if( m_DraggingItem->m_ItemCount > 0 && m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount < 64 ) + { + m_Slots[a_ClickPacket->m_SlotNum].m_ItemID = m_DraggingItem->m_ItemID; + m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount++; + m_Slots[a_ClickPacket->m_SlotNum].m_ItemHealth = m_DraggingItem->m_ItemHealth; + m_DraggingItem->m_ItemCount--; + } + if( m_DraggingItem->m_ItemCount <= 0 ) + { + m_DraggingItem->Empty(); + } + } + else if( !m_DraggingItem->Equals( m_Slots[a_ClickPacket->m_SlotNum]) ) // Swap contents + { + cItem tmp( *m_DraggingItem ); + *m_DraggingItem = m_Slots[a_ClickPacket->m_SlotNum]; + m_Slots[a_ClickPacket->m_SlotNum] = tmp; // Switch contents + } + } + if( bAsync ) + { + LOG("Window is not synchonous with client. Sending whole window. ID: %i", m_WindowID); + for( std::list< cPlayer* >::iterator itr = m_OpenedBy.begin(); itr != m_OpenedBy.end(); ++itr ) + { + SendWholeWindow( (*itr)->GetClientHandle() ); + } + if( m_bInventoryVisible || m_OpenedBy.size() == 0 ) + { + a_Player.GetInventory().SendWholeInventory( a_Player.GetClientHandle() ); + } + } + } + else if( m_bInventoryVisible ) // Click in player inventory + { + a_ClickPacket->m_WindowID = 0; + a_ClickPacket->m_SlotNum -= (short)(m_NumSlots - 9); + cWindow* Window = a_Player.GetInventory().GetWindow(); + if( Window ) + { + Window->Clicked( a_ClickPacket, a_Player ); + } + } + if (m_DraggingItem != NULL) + { + LOGD("Dragging: %i", m_DraggingItem->m_ItemCount ); + } +} + + + + + +void cWindow::Open( cPlayer & a_Player ) +{ + { + cCSLock Lock(m_CS); + // If player is already in OpenedBy remove player first + m_OpenedBy.remove( &a_Player ); + // Then add player + m_OpenedBy.push_back( &a_Player ); + } + + cPacket_WindowOpen WindowOpen; + WindowOpen.m_WindowID = (char)m_WindowID; + WindowOpen.m_InventoryType = (char)m_WindowType; + WindowOpen.m_WindowTitle = m_WindowTitle; + WindowOpen.m_NumSlots = (char)m_NumSlots; + a_Player.GetClientHandle()->Send( WindowOpen ); +} + + + + + +void cWindow::Close( cPlayer & a_Player ) +{ + //Checks wheather the player is still holding an item + if(m_DraggingItem && m_DraggingItem->m_ItemCount > 0) + { + LOG("Player holds item! Dropping it..."); + a_Player.TossItem( true, m_DraggingItem->m_ItemCount ); + } + + cPacket_WindowClose WindowClose; + WindowClose.m_Close = (char)m_WindowID; + cClientHandle * ClientHandle = a_Player.GetClientHandle(); + if ( ClientHandle != NULL) + { + ClientHandle->Send( WindowClose ); + } + + { + cCSLock Lock(m_CS); + m_OpenedBy.remove( &a_Player ); + if( m_OpenedBy.size() == 0 ) + { + Destroy(); + } + } + if (m_IsDestroyed) + { + delete this; + } +} + + + + + +void cWindow::OwnerDestroyed() +{ + m_Owner = 0; + while( m_OpenedBy.size() > 1 ) + { + (*m_OpenedBy.begin() )->CloseWindow((char)GetWindowType()); + } + (*m_OpenedBy.begin() )->CloseWindow((char)GetWindowType()); +} + + + + + +void cWindow::Destroy() +{ + LOGD("Destroying window %p (type %d)", this, m_WindowType); + if (m_Owner != NULL) + { + m_Owner->CloseWindow(); + m_Owner = NULL; + } + m_IsDestroyed = true; +} + + + + + +void cWindow::SendWholeWindow( cClientHandle* a_Client ) +{ + cPacket_WholeInventory Inventory( this ); + a_Client->Send( Inventory ); +} + + + + + +void cWindow::BroadcastWholeWindow(void) +{ + cCSLock Lock(m_CS); + for (cPlayerList::iterator itr = m_OpenedBy.begin(); itr != m_OpenedBy.end(); ++itr) + { + SendWholeWindow((*itr)->GetClientHandle()); + } // for itr - m_OpenedBy[] +} + + + + + +void cWindow::Broadcast(const cPacket & a_Packet) +{ + cCSLock Lock(m_CS); + for (cPlayerList::iterator itr = m_OpenedBy.begin(); itr != m_OpenedBy.end(); ++itr) + { + (*itr)->GetClientHandle()->Send(a_Packet); + } // for itr - m_OpenedBy[] +} + + + + diff --git a/source/cWindow.h b/source/cWindow.h index d9f4226a6..7d31d71e3 100644 --- a/source/cWindow.h +++ b/source/cWindow.h @@ -1,86 +1,86 @@ -#pragma once - - -class cPacket_WindowClick; -class cPlayer; -class cItem; -class cWindowOwner; -class cClientHandle; -class cPacket; - -typedef std::list cPlayerList; - - - - - -class cWindow -{ -public: - cWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible ); - ~cWindow(); - - int GetWindowID() { return m_WindowID; } - void SetWindowID( int a_WindowID ) { m_WindowID = a_WindowID; } - - enum WindowType { - Chest, - Workbench, - Furnace, - Dispenser, - Enchantment, - Brewery - }; - - int GetWindowType() { return m_WindowType; } - void SetWindowType( int a_WindowType ) { m_WindowType = a_WindowType; } - - cItem* GetSlots() { return m_Slots; } - int GetNumSlots() { return m_NumSlots; } - - cItem* GetSlot( int a_Slot ); - - cItem* GetDraggingItem( cPlayer * a_Player = 0 ); - - // a_Slots is an array of slots of size a_NumSlots - void SetSlots(cItem* a_Slots, int a_NumSlots) { m_Slots = a_Slots; m_NumSlots = a_NumSlots; } - - bool IsInventoryVisible() { return m_bInventoryVisible; } - void SetInventoryVisible( bool a_bVisible ) { m_bInventoryVisible = a_bVisible; } - - virtual void Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ); - - virtual void Open( cPlayer & a_Player ); - virtual void Close( cPlayer & a_Player ); - - cWindowOwner* GetOwner() { return m_Owner; } - void SetOwner( cWindowOwner* a_Owner ) { m_Owner = a_Owner; } - - void SendWholeWindow( cClientHandle* a_Client ); - void BroadcastWholeWindow(void); - void Broadcast(const cPacket & a_Packet); - - const AString & GetWindowTitle() const { return m_WindowTitle; } - void SetWindowTitle( const std::string & a_WindowTitle ) { m_WindowTitle = a_WindowTitle; } - - void OwnerDestroyed(); - -private: - - void Destroy(); - - int m_WindowID; - int m_WindowType; - AString m_WindowTitle; - - cWindowOwner * m_Owner; - - cCriticalSection m_CS; - cPlayerList m_OpenedBy; - - bool m_bInventoryVisible; - int m_NumSlots; - cItem * m_Slots; - cItem * m_DraggingItem; - bool m_IsDestroyed; +#pragma once + + +class cPacket_WindowClick; +class cPlayer; +class cItem; +class cWindowOwner; +class cClientHandle; +class cPacket; + +typedef std::list cPlayerList; + + + + + +class cWindow +{ +public: + cWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible ); + ~cWindow(); + + int GetWindowID() { return m_WindowID; } + void SetWindowID( int a_WindowID ) { m_WindowID = a_WindowID; } + + enum WindowType { + Chest, + Workbench, + Furnace, + Dispenser, + Enchantment, + Brewery + }; + + int GetWindowType() { return m_WindowType; } + void SetWindowType( int a_WindowType ) { m_WindowType = a_WindowType; } + + cItem* GetSlots() { return m_Slots; } + int GetNumSlots() { return m_NumSlots; } + + cItem* GetSlot( int a_Slot ); + + cItem* GetDraggingItem( cPlayer * a_Player = 0 ); + + // a_Slots is an array of slots of size a_NumSlots + void SetSlots(cItem* a_Slots, int a_NumSlots) { m_Slots = a_Slots; m_NumSlots = a_NumSlots; } + + bool IsInventoryVisible() { return m_bInventoryVisible; } + void SetInventoryVisible( bool a_bVisible ) { m_bInventoryVisible = a_bVisible; } + + virtual void Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ); + + virtual void Open( cPlayer & a_Player ); + virtual void Close( cPlayer & a_Player ); + + cWindowOwner* GetOwner() { return m_Owner; } + void SetOwner( cWindowOwner* a_Owner ) { m_Owner = a_Owner; } + + void SendWholeWindow( cClientHandle* a_Client ); + void BroadcastWholeWindow(void); + void Broadcast(const cPacket & a_Packet); + + const AString & GetWindowTitle() const { return m_WindowTitle; } + void SetWindowTitle( const std::string & a_WindowTitle ) { m_WindowTitle = a_WindowTitle; } + + void OwnerDestroyed(); + +private: + + void Destroy(); + + int m_WindowID; + int m_WindowType; + AString m_WindowTitle; + + cWindowOwner * m_Owner; + + cCriticalSection m_CS; + cPlayerList m_OpenedBy; + + bool m_bInventoryVisible; + int m_NumSlots; + cItem * m_Slots; + cItem * m_DraggingItem; + bool m_IsDestroyed; }; \ No newline at end of file diff --git a/source/cWindowOwner.h b/source/cWindowOwner.h index 71691aaed..3a1797f74 100644 --- a/source/cWindowOwner.h +++ b/source/cWindowOwner.h @@ -1,29 +1,29 @@ -#pragma once - - -class cWindow; -class cBlockEntity; - - - - - -class cWindowOwner -{ -public: - cWindowOwner() : m_Window( NULL ) {} - void CloseWindow() { m_Window = NULL; } - void OpenWindow( cWindow* a_Window ) { m_Window = a_Window; } - - cWindow* GetWindow() { return m_Window; } - - void SetEntity(cBlockEntity *a_Entity) { m_Entity = a_Entity; } - cBlockEntity *GetEntity() { return m_Entity; } -private: - cWindow* m_Window; - cBlockEntity *m_Entity; -}; - - - - +#pragma once + + +class cWindow; +class cBlockEntity; + + + + + +class cWindowOwner +{ +public: + cWindowOwner() : m_Window( NULL ) {} + void CloseWindow() { m_Window = NULL; } + void OpenWindow( cWindow* a_Window ) { m_Window = a_Window; } + + cWindow* GetWindow() { return m_Window; } + + void SetEntity(cBlockEntity *a_Entity) { m_Entity = a_Entity; } + cBlockEntity *GetEntity() { return m_Entity; } +private: + cWindow* m_Window; + cBlockEntity *m_Entity; +}; + + + + diff --git a/source/cWolf.cpp b/source/cWolf.cpp index 8226b06ac..fa693bcbd 100644 --- a/source/cWolf.cpp +++ b/source/cWolf.cpp @@ -1,20 +1,20 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cWolf.h" - -cWolf::cWolf() -{ - m_MobType = 95; - GetMonsterConfig("Wolf"); -} - -cWolf::~cWolf() -{ -} - -bool cWolf::IsA( const char* a_EntityType ) -{ - if( strcmp( a_EntityType, "cWolf" ) == 0 ) return true; - return cMonster::IsA( a_EntityType ); -} + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cWolf.h" + +cWolf::cWolf() +{ + m_MobType = 95; + GetMonsterConfig("Wolf"); +} + +cWolf::~cWolf() +{ +} + +bool cWolf::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cWolf" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} diff --git a/source/cWolf.h b/source/cWolf.h index b3bca1e47..174968cdb 100644 --- a/source/cWolf.h +++ b/source/cWolf.h @@ -1,12 +1,12 @@ -#pragma once - -#include "cPassiveAggressiveMonster.h" - -class cWolf : public cPassiveAggressiveMonster -{ -public: - cWolf(); - ~cWolf(); - - virtual bool IsA( const char* a_EntityType ); -}; +#pragma once + +#include "cPassiveAggressiveMonster.h" + +class cWolf : public cPassiveAggressiveMonster +{ +public: + cWolf(); + ~cWolf(); + + virtual bool IsA( const char* a_EntityType ); +}; diff --git a/source/cWorld.cpp b/source/cWorld.cpp index 27f85bf90..b5ed59ccb 100644 --- a/source/cWorld.cpp +++ b/source/cWorld.cpp @@ -1,1845 +1,1845 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "BlockID.h" -#include "cWorld.h" -#include "cRedstone.h" -#include "ChunkDef.h" -#include "cClientHandle.h" -#include "cPickup.h" -#include "cBlockToPickup.h" -#include "cPlayer.h" -#include "cServer.h" -#include "cItem.h" -#include "cRoot.h" -#include "../iniFile/iniFile.h" -#include "cChunkMap.h" -#include "cSimulatorManager.h" -#include "cWaterSimulator.h" -#include "cLavaSimulator.h" -#include "cFireSimulator.h" -#include "cSandSimulator.h" -#include "cRedstoneSimulator.h" -#include "cChicken.h" -#include "cSpider.h" -#include "cCow.h" //cow -#include "cSquid.h" //Squid -#include "cWolf.h" //wolf -#include "cSlime.h" //slime -#include "cSkeleton.h" //Skeleton -#include "cSilverfish.h" //Silverfish -#include "cPig.h" //pig -#include "cSheep.h" //sheep -#include "cZombie.h" //zombie -#include "cEnderman.h" //enderman -#include "cCreeper.h" //creeper -#include "cCavespider.h" //cavespider -#include "cGhast.h" //Ghast -#include "cZombiepigman.h" //Zombiepigman -#include "cMakeDir.h" -#include "cChunkGenerator.h" -#include "MersenneTwister.h" -#include "cTracer.h" -#include "Trees.h" -#include "cPluginManager.h" - - -#include "packets/cPacket_TimeUpdate.h" -#include "packets/cPacket_NewInvalidState.h" -#include "packets/cPacket_Thunderbolt.h" - -#include "Vector3d.h" - -#include - -#include "tolua++.h" - -#ifndef _WIN32 - #include -#endif - - - - - -/// Up to this many m_SpreadQueue elements are handled each world tick -const int MAX_LIGHTING_SPREAD_PER_TICK = 10; - - - - - -float cWorld::m_Time = 0.f; - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cWorldLoadProgress: - -/// A simple thread that displays the progress of world loading / saving in cWorld::InitializeSpawn() -class cWorldLoadProgress : - public cIsThread -{ -public: - cWorldLoadProgress(cWorld * a_World) : - cIsThread("cWorldLoadProgress"), - m_World(a_World) - { - Start(); - } - - void Stop(void) - { - m_ShouldTerminate = true; - Wait(); - } - -protected: - - cWorld * m_World; - - virtual void Execute(void) override - { - for (;;) - { - LOG("%d chunks to load, %d chunks to generate", - m_World->GetStorage().GetLoadQueueLength(), - m_World->GetGenerator().GetQueueLength() - ); - - // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish - for (int i = 0; i < 20; i++) - { - cSleep::MilliSleep(100); - if (m_ShouldTerminate) - { - return; - } - } - } // for (-ever) - } - -} ; - - - - - -/// A simple thread that displays the progress of world lighting in cWorld::InitializeSpawn() -class cWorldLightingProgress : - public cIsThread -{ -public: - cWorldLightingProgress(cLightingThread * a_Lighting) : - cIsThread("cWorldLightingProgress"), - m_Lighting(a_Lighting) - { - Start(); - } - - void Stop(void) - { - m_ShouldTerminate = true; - Wait(); - } - -protected: - - cLightingThread * m_Lighting; - - virtual void Execute(void) override - { - for (;;) - { - LOG("%d chunks remaining to light", m_Lighting->GetQueueLength() - ); - - // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish - for (int i = 0; i < 20; i++) - { - cSleep::MilliSleep(100); - if (m_ShouldTerminate) - { - return; - } - } - } // for (-ever) - } - -} ; - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cWorld: - -cWorld* cWorld::GetWorld() -{ - LOGWARN("WARNING: Using deprecated function cWorld::GetWorld() use cRoot::Get()->GetDefaultWorld() instead!"); - return cRoot::Get()->GetDefaultWorld(); -} - - - - - -cWorld::~cWorld() -{ - { - cCSLock Lock(m_CSEntities); - while( m_AllEntities.begin() != m_AllEntities.end() ) - { - cEntity* Entity = *m_AllEntities.begin(); - m_AllEntities.remove( Entity ); - if ( !Entity->IsDestroyed() ) - { - Entity->Destroy(); - } - delete Entity; - } - } - - delete m_SimulatorManager; - delete m_SandSimulator; - delete m_WaterSimulator; - delete m_LavaSimulator; - delete m_FireSimulator; - delete m_RedstoneSimulator; - - m_Generator.Stop(); - m_ChunkSender.Stop(); - - UnloadUnusedChunks(); - - m_Storage.WaitForFinish(); - - delete m_ChunkMap; -} - - - - - -cWorld::cWorld( const AString & a_WorldName ) - : m_SpawnMonsterTime( 0.f ) - , m_RSList ( 0 ) - , m_Weather ( eWeather_Sunny ) -{ - LOG("cWorld::cWorld(%s)", a_WorldName.c_str()); - m_WorldName = a_WorldName; - m_IniFileName = m_WorldName + "/world.ini"; - - cMakeDir::MakeDir(m_WorldName.c_str()); - - MTRand r1; - m_SpawnX = (double)((r1.randInt() % 1000) - 500); - m_SpawnY = cChunkDef::Height; - m_SpawnZ = (double)((r1.randInt() % 1000) - 500); - m_GameMode = eGameMode_Creative; - - AString StorageSchema("Default"); - - cIniFile IniFile(m_IniFileName); - IniFile.ReadFile(); - m_SpawnX = IniFile.GetValueSetF("SpawnPosition", "X", m_SpawnX); - m_SpawnY = IniFile.GetValueSetF("SpawnPosition", "Y", m_SpawnY); - m_SpawnZ = IniFile.GetValueSetF("SpawnPosition", "Z", m_SpawnZ); - StorageSchema = IniFile.GetValueSet ("Storage", "Schema", StorageSchema); - m_MaxCactusHeight = IniFile.GetValueSetI("Plants", "MaxCactusHeight", 3); - m_MaxSugarcaneHeight = IniFile.GetValueSetI("Plants", "MaxSugarcaneHeight", 3); - m_IsCropsBonemealable = IniFile.GetValueSetB("Plants", "IsCropsBonemealable", true); - m_IsGrassBonemealable = IniFile.GetValueSetB("Plants", "IsGrassBonemealable", true); - m_IsSaplingBonemealable = IniFile.GetValueSetB("Plants", "IsSaplingBonemealable", true); - m_IsMelonStemBonemealable = IniFile.GetValueSetB("Plants", "IsMelonStemBonemealable", true); - m_IsMelonBonemealable = IniFile.GetValueSetB("Plants", "IsMelonBonemealable", false); - m_IsPumpkinStemBonemealable = IniFile.GetValueSetB("Plants", "IsPumpkinStemBonemealable", true); - m_IsPumpkinBonemealable = IniFile.GetValueSetB("Plants", "IsPumpkinBonemealable", false); - m_IsSugarcaneBonemealable = IniFile.GetValueSetB("Plants", "IsSugarcaneBonemealable", false); - m_IsCactusBonemealable = IniFile.GetValueSetB("Plants", "IsCactusBonemealable", false); - - m_GameMode = (eGameMode)IniFile.GetValueSetI("GameMode", "GameMode", m_GameMode ); - - if (!IniFile.WriteFile()) - { - LOG("WARNING: Could not write to %s", m_IniFileName.c_str()); - } - - m_Lighting.Start(this); - m_Storage.Start(this, StorageSchema); - m_Generator.Start(this, IniFile); - - m_bAnimals = true; - m_SpawnMonsterRate = 10; - cIniFile IniFile2("settings.ini"); - if( IniFile2.ReadFile() ) - { - m_bAnimals = IniFile2.GetValueB("Monsters", "AnimalsOn", true ); - m_SpawnMonsterRate = (float)IniFile2.GetValueF("Monsters", "AnimalSpawnInterval", 10); - SetMaxPlayers(IniFile2.GetValueI("Server", "MaxPlayers", 9001)); - m_Description = IniFile2.GetValue("Server", "Description", "MCServer! - It's OVER 9000!").c_str(); - } - - m_ChunkMap = new cChunkMap(this ); - - m_ChunkSender.Start(this); - - m_Time = 0; - m_WorldTimeFraction = 0.f; - m_WorldTime = 0; - m_LastSave = 0; - m_LastUnload = 0; - - //Simulators: - m_WaterSimulator = new cWaterSimulator( this ); - m_LavaSimulator = new cLavaSimulator( this ); - m_SandSimulator = new cSandSimulator(this); - m_FireSimulator = new cFireSimulator(this); - m_RedstoneSimulator = new cRedstoneSimulator(this); - - m_SimulatorManager = new cSimulatorManager(); - m_SimulatorManager->RegisterSimulator(m_WaterSimulator, 6); - m_SimulatorManager->RegisterSimulator(m_LavaSimulator, 12); - m_SimulatorManager->RegisterSimulator(m_SandSimulator, 1); - m_SimulatorManager->RegisterSimulator(m_FireSimulator, 10); - m_SimulatorManager->RegisterSimulator(m_RedstoneSimulator, 1); -} - - - - - -void cWorld::SetWeather( eWeather a_Weather ) -{ - switch( a_Weather ) - { - case eWeather_Sunny: - { - m_Weather = a_Weather; - cPacket_NewInvalidState WeatherPacket; - WeatherPacket.m_Reason = 2; //stop rain - Broadcast ( WeatherPacket ); - } - break; - case eWeather_Rain: - { - m_Weather = a_Weather; - cPacket_NewInvalidState WeatherPacket; - WeatherPacket.m_Reason = 1; //begin rain - Broadcast ( WeatherPacket ); - } - break; - case eWeather_ThunderStorm: - { - m_Weather = a_Weather; - cPacket_NewInvalidState WeatherPacket; - WeatherPacket.m_Reason = 1; //begin rain - Broadcast ( WeatherPacket ); - CastThunderbolt ( 0, 0, 0 ); //start thunderstorm with a lightning strike at 0, 0, 0. >:D - } - break; - default: - LOGWARN("Trying to set unknown weather %d", a_Weather ); - break; - } -} - - - - - -void cWorld::CastThunderbolt ( int a_X, int a_Y, int a_Z ) -{ - cPacket_Thunderbolt ThunderboltPacket; - ThunderboltPacket.m_xLBPos = a_X; - ThunderboltPacket.m_yLBPos = a_Y; - ThunderboltPacket.m_zLBPos = a_Z; - BroadcastToChunkOfBlock(a_X, a_Y, a_Z, &ThunderboltPacket); -} - - - - - -bool cWorld::IsPlacingItemLegal(Int16 a_ItemType, int a_BlockX, int a_BlockY, int a_BlockZ) -{ - BLOCKTYPE SurfaceBlock = GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ); - switch (a_ItemType) - { - case E_BLOCK_YELLOW_FLOWER: // Can ONLY be placed on dirt/grass - case E_BLOCK_RED_ROSE: - case E_BLOCK_SAPLING: - { - switch (SurfaceBlock) - { - case E_BLOCK_DIRT: - case E_BLOCK_GRASS: - case E_BLOCK_FARMLAND: - { - return true; - } - } - return false; - } - - case E_BLOCK_BROWN_MUSHROOM: // Can be placed on pretty much anything, with exceptions - case E_BLOCK_RED_MUSHROOM: - { - switch (SurfaceBlock) - { - case E_BLOCK_GLASS: - case E_BLOCK_YELLOW_FLOWER: - case E_BLOCK_RED_ROSE: - case E_BLOCK_BROWN_MUSHROOM: - case E_BLOCK_RED_MUSHROOM: - case E_BLOCK_CACTUS: - { - return false; - } - } - return true; - } - - case E_BLOCK_CACTUS: - { - if ((SurfaceBlock != E_BLOCK_SAND) && (SurfaceBlock != E_BLOCK_CACTUS)) - { - // Cactus can only be placed on sand and itself - return false; - } - - // Check surroundings. Cacti may ONLY be surrounded by air - if ( - (GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ) != E_BLOCK_AIR) || - (GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ) != E_BLOCK_AIR) || - (GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1) != E_BLOCK_AIR) || - (GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1) != E_BLOCK_AIR) - ) - { - return false; - } - return true; - } - - case E_ITEM_SEEDS: - case E_ITEM_MELON_SEEDS: - case E_ITEM_PUMPKIN_SEEDS: - { - // Seeds can go only on the farmland block: - return (SurfaceBlock == E_BLOCK_FARMLAND); - } - } // switch (a_Packet->m_ItemType) - return true; -} - - - - - -void cWorld::SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ) -{ - return m_ChunkMap->SetNextBlockTick(a_BlockX, a_BlockY, a_BlockZ); -} - - - - - -void cWorld::InitializeSpawn(void) -{ - int ChunkX = 0, ChunkY = 0, ChunkZ = 0; - BlockToChunk( (int)m_SpawnX, (int)m_SpawnY, (int)m_SpawnZ, ChunkX, ChunkY, ChunkZ ); - - // For the debugging builds, don't make the server build too much world upon start: - #ifdef _DEBUG - int ViewDist = 9; - #else - int ViewDist = 20; // Always prepare an area 20 chunks across, no matter what the actual cClientHandle::VIEWDISTANCE is - #endif // _DEBUG - - LOG("Preparing spawn area in world \"%s\"...", m_WorldName.c_str()); - for (int x = 0; x < ViewDist; x++) - { - for (int z = 0; z < ViewDist; z++) - { - m_ChunkMap->TouchChunk( x + ChunkX-(ViewDist - 1) / 2, ZERO_CHUNK_Y, z + ChunkZ-(ViewDist - 1) / 2 ); // Queue the chunk in the generator / loader - } - } - - { - // Display progress during this process: - cWorldLoadProgress Progress(this); - - // Wait for the loader to finish loading - m_Storage.WaitForQueuesEmpty(); - - // Wait for the generator to finish generating - m_Generator.WaitForQueueEmpty(); - - Progress.Stop(); - } - - // Light all chunks that have been newly generated: - LOG("Lighting spawn area in world \"%s\"...", m_WorldName.c_str()); - - for (int x = 0; x < ViewDist; x++) - { - int ChX = x + ChunkX-(ViewDist - 1) / 2; - for (int z = 0; z < ViewDist; z++) - { - int ChZ = z + ChunkZ-(ViewDist - 1) / 2; - if (!m_ChunkMap->IsChunkLighted(ChX, ChZ)) - { - m_Lighting.QueueChunk(ChX, ChZ); // Queue the chunk in the lighting thread - } - } // for z - } // for x - - { - cWorldLightingProgress Progress(&m_Lighting); - m_Lighting.WaitForQueueEmpty(); - Progress.Stop(); - } - - // TODO: Better spawn detection - move spawn out of the water if it isn't set in the INI already - m_SpawnY = (double)GetHeight( (int)m_SpawnX, (int)m_SpawnZ ) + 1.6f; // +1.6f eye height -} - - - - - -void cWorld::Tick(float a_Dt) -{ - m_Time += a_Dt / 1000.f; - - CurrentTick++; - - bool bSendTime = false; - m_WorldTimeFraction += a_Dt / 1000.f; - while ( m_WorldTimeFraction > 1.f ) - { - m_WorldTimeFraction -= 1.f; - m_WorldTime += 20; - bSendTime = true; - } - m_WorldTime %= 24000; // 24000 units in a day - if ( bSendTime ) - { - Broadcast( cPacket_TimeUpdate( (m_WorldTime) ) ); - } - - { - cCSLock Lock(m_CSEntities); - for (cEntityList::iterator itr = m_AllEntities.begin(); itr != m_AllEntities.end();) - { - if ((*itr)->IsDestroyed()) - { - LOG("Destroying entity #%i", (*itr)->GetUniqueID()); - cEntity * RemoveMe = *itr; - itr = m_AllEntities.erase( itr ); - m_RemoveEntityQueue.push_back( RemoveMe ); - continue; - } - (*itr)->Tick(a_Dt); - itr++; - } - } - - m_ChunkMap->Tick(a_Dt, m_TickRand); - - GetSimulatorManager()->Simulate(a_Dt); - - TickWeather(a_Dt); - - // Asynchronously set blocks: - sSetBlockList FastSetBlockQueueCopy; - { - cCSLock Lock(m_CSFastSetBlock); - std::swap(FastSetBlockQueueCopy, m_FastSetBlockQueue); - } - m_ChunkMap->FastSetBlocks(FastSetBlockQueueCopy); - if (!FastSetBlockQueueCopy.empty()) - { - // Some blocks failed, store them for next tick: - cCSLock Lock(m_CSFastSetBlock); - m_FastSetBlockQueue.splice(m_FastSetBlockQueue.end(), FastSetBlockQueueCopy); - } - - if( m_Time - m_LastSave > 60 * 5 ) // Save each 5 minutes - { - SaveAllChunks(); - } - - if( m_Time - m_LastUnload > 10 ) // Unload every 10 seconds - { - UnloadUnusedChunks(); - } - - // Delete entities queued for removal: - for (cEntityList::iterator itr = m_RemoveEntityQueue.begin(); itr != m_RemoveEntityQueue.end(); ++itr) - { - delete *itr; - } - m_RemoveEntityQueue.clear(); - - TickSpawnMobs(a_Dt); - - std::vector m_RSList_copy(m_RSList); - - m_RSList.clear(); - - std::vector::const_iterator cii; // FIXME - Please rename this variable, WTF is cii??? Use human readable variable names or common abbreviations (i, idx, itr, iter) - for(cii=m_RSList_copy.begin(); cii!=m_RSList_copy.end();) - { - int tempX = *cii;cii++; - int tempY = *cii;cii++; - int tempZ = *cii;cii++; - int state = *cii;cii++; - - if ( (state == 11111) && ( (int)GetBlock( tempX, tempY, tempZ ) == E_BLOCK_REDSTONE_TORCH_OFF ) ) - { - FastSetBlock( tempX, tempY, tempZ, E_BLOCK_REDSTONE_TORCH_ON, (int)GetBlockMeta( tempX, tempY, tempZ ) ); - cRedstone Redstone(this); - Redstone.ChangeRedstone( tempX, tempY, tempZ, true ); - } - else if ( (state == 00000) && ( (int)GetBlock( tempX, tempY, tempZ ) == E_BLOCK_REDSTONE_TORCH_ON ) ) - { - FastSetBlock( tempX, tempY, tempZ, E_BLOCK_REDSTONE_TORCH_OFF, (int)GetBlockMeta( tempX, tempY, tempZ ) ); - cRedstone Redstone(this); - Redstone.ChangeRedstone( tempX, tempY, tempZ, false ); - } - } - m_RSList_copy.erase(m_RSList_copy.begin(),m_RSList_copy.end()); -} - - - - - -void cWorld::ChangeWeather() -{ - unsigned randWeather = (m_TickRand.randInt() % 99); - - if (GetWeather() == eWeather_Sunny) - { - if (randWeather < 20) - { - LOG("Starting rainstorm!"); - SetWeather( eWeather_Rain ); - } - } - - else if (GetWeather() == eWeather_Rain) - { - if (randWeather < 5) - { - LOG("Thunderstorm!"); - SetWeather( eWeather_ThunderStorm ); - } - - else if (randWeather < 60) - { - LOG("Back to sunshine"); - SetWeather( eWeather_Sunny ); - } - } - - else if (GetWeather() == eWeather_ThunderStorm) - { - if (randWeather < 70) - { - SetWeather(eWeather_Sunny); - LOG("Thunder ended abruptly, returning to lovely sunshine"); - } - else if (randWeather < 85) - { - SetWeather(eWeather_Rain); - LOG("Thunder ended, but rain persists."); - } - else - { - return; - } - } -} - - - - - -void cWorld::TickWeather(float a_Dt) -{ - if(m_WeatherInterval == 0) - { - ChangeWeather(); - - cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::HOOK_WEATHER_CHANGE, 0 ); - - switch(GetWeather()) - { - case eWeather_Sunny: - m_WeatherInterval = 14400 + (m_TickRand.randInt() % 4800); // 12 - 16 minutes - break; - case eWeather_Rain: - m_WeatherInterval = 9600 + (m_TickRand.randInt() % 7200); // 8 - 14 minutes - break; - case eWeather_ThunderStorm: - m_WeatherInterval = 2400 + (m_TickRand.randInt() % 4800); // 2 - 6 minutes - break; - default: - LOG("Unknown weather occurred"); - break; - } - } - - else - { - m_WeatherInterval--; - } - - if ( GetWeather() == 2 ) // if thunderstorm - { - if (m_TickRand.randInt() % 199 == 0) // 0.5% chance per tick of thunderbolt - { - CastThunderbolt ( 0, 0, 0 ); // TODO: find random possitions near players to cast thunderbolts. - } - } -} - - - - - -void cWorld::TickSpawnMobs(float a_Dt) -{ - if (!m_bAnimals || (m_Time - m_SpawnMonsterTime <= m_SpawnMonsterRate)) - { - return; - } - - m_SpawnMonsterTime = m_Time; - Vector3d SpawnPos; - { - cCSLock Lock(m_CSPlayers); - if ( m_Players.size() <= 0) - { - return; - } - int RandomPlayerIdx = m_TickRand.randInt() & m_Players.size(); - cPlayerList::iterator itr = m_Players.begin(); - for( int i = 1; i < RandomPlayerIdx; i++ ) - { - itr++; - } - SpawnPos = (*itr)->GetPosition(); - } - - cMonster * Monster = NULL; - int dayRand = m_TickRand.randInt() % 6; - int nightRand = m_TickRand.randInt() % 10; - - SpawnPos += Vector3d( (double)(m_TickRand.randInt() % 64) - 32, (double)(m_TickRand.randInt() % 64) - 32, (double)(m_TickRand.randInt() % 64) - 32 ); - int Height = GetHeight( (int)SpawnPos.x, (int)SpawnPos.z ); - - if (m_WorldTime >= 12000 + 1000) - { - if (nightRand == 0) //random percent to spawn for night - Monster = new cSpider(); - else if (nightRand == 1) - Monster = new cZombie(); - else if (nightRand == 2) - Monster = new cEnderman(); - else if (nightRand == 3) - Monster = new cCreeper(); - else if (nightRand == 4) - Monster = new cCavespider(); - else if (nightRand == 5) - Monster = new cGhast(); - else if (nightRand == 6) - Monster = new cZombiepigman(); - else if (nightRand == 7) - Monster = new cSlime(); - else if (nightRand == 8) - Monster = new cSilverfish(); - else if (nightRand == 9) - Monster = new cSkeleton(); - //end random percent to spawn for night - } - else - { - if (dayRand == 0) //random percent to spawn for day - Monster = new cChicken(); - else if (dayRand == 1) - Monster = new cCow(); - else if (dayRand == 2) - Monster = new cPig(); - else if (dayRand == 3) - Monster = new cSheep(); - else if (dayRand == 4) - Monster = new cSquid(); - else if (dayRand == 5) - Monster = new cWolf(); - //end random percent to spawn for day - } - - if( Monster ) - { - Monster->Initialize( this ); - Monster->TeleportTo( SpawnPos.x, (double)(Height) + 2, SpawnPos.z ); - Monster->SpawnOn(0); - } -} - - - - - -void cWorld::GrowTree( int a_X, int a_Y, int a_Z ) -{ - if (GetBlock(a_X, a_Y, a_Z) == E_BLOCK_SAPLING) - { - // There is a sapling here, grow a tree according to its type: - GrowTreeFromSapling(a_X, a_Y, a_Z, GetBlockMeta(a_X, a_Y, a_Z)); - } - else - { - // There is nothing here, grow a tree based on the current biome here: - GrowTreeByBiome(a_X, a_Y, a_Z); - } -} - - - - - -void cWorld::GrowTreeFromSapling(int a_X, int a_Y, int a_Z, char a_SaplingMeta) -{ - cNoise Noise(m_Generator.GetSeed()); - sSetBlockVector Blocks; - switch (a_SaplingMeta & 0x07) - { - case E_META_SAPLING_APPLE: GetAppleTreeImage (a_X, a_Y, a_Z, Noise, (int)(m_WorldTime & 0xffffffff), Blocks); break; - case E_META_SAPLING_BIRCH: GetBirchTreeImage (a_X, a_Y, a_Z, Noise, (int)(m_WorldTime & 0xffffffff), Blocks); break; - case E_META_SAPLING_CONIFER: GetConiferTreeImage(a_X, a_Y, a_Z, Noise, (int)(m_WorldTime & 0xffffffff), Blocks); break; - case E_META_SAPLING_JUNGLE: GetJungleTreeImage (a_X, a_Y, a_Z, Noise, (int)(m_WorldTime & 0xffffffff), Blocks); break; - } - - GrowTreeImage(Blocks); -} - - - - - -void cWorld::GrowTreeByBiome(int a_X, int a_Y, int a_Z) -{ - cNoise Noise(m_Generator.GetSeed()); - sSetBlockVector Blocks; - GetTreeImageByBiome(a_X, a_Y, a_Z, Noise, (int)(m_WorldTime & 0xffffffff), (EMCSBiome)GetBiomeAt(a_X, a_Z), Blocks); - GrowTreeImage(Blocks); -} - - - - - -void cWorld::GrowTreeImage(const sSetBlockVector & a_Blocks) -{ - // Check that the tree has place to grow - - // Make a copy of the log blocks: - sSetBlockVector b2; - for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) - { - if (itr->BlockType == E_BLOCK_LOG) - { - b2.push_back(*itr); - } - } // for itr - a_Blocks[] - - // Query blocktypes and metas at those log blocks: - if (!GetBlocks(b2, false)) - { - return; - } - - // Check that at each log's coord there's an block allowed to be overwritten: - for (sSetBlockVector::const_iterator itr = b2.begin(); itr != b2.end(); ++itr) - { - switch (itr->BlockType) - { - CASE_TREE_ALLOWED_BLOCKS: - { - break; - } - default: - { - return; - } - } - } // for itr - b2[] - - // All ok, replace blocks with the tree image: - m_ChunkMap->ReplaceTreeBlocks(a_Blocks); -} - - - - - -bool cWorld::GrowPlant(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_IsByBonemeal) -{ - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta); - switch (BlockType) - { - case E_BLOCK_CROPS: - { - if (a_IsByBonemeal && !m_IsGrassBonemealable) - { - return false; - } - if (BlockMeta < 7) - { - FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, 7); - } - return true; - } - - case E_BLOCK_MELON_STEM: - { - if (BlockMeta < 7) - { - if (a_IsByBonemeal && !m_IsMelonStemBonemealable) - { - return false; - } - FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, 7); - } - else - { - if (a_IsByBonemeal && !m_IsMelonBonemealable) - { - return false; - } - GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, BlockType); - } - return true; - } - - case E_BLOCK_PUMPKIN_STEM: - { - if (BlockMeta < 7) - { - if (a_IsByBonemeal && !m_IsPumpkinStemBonemealable) - { - return false; - } - FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, 7); - } - else - { - if (a_IsByBonemeal && !m_IsPumpkinBonemealable) - { - return false; - } - GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, BlockType); - } - return true; - } - - case E_BLOCK_SAPLING: - { - if (a_IsByBonemeal && !m_IsSaplingBonemealable) - { - return false; - } - GrowTreeFromSapling(a_BlockX, a_BlockY, a_BlockZ, BlockMeta); - return true; - } - - case E_BLOCK_GRASS: - { - if (a_IsByBonemeal && !m_IsGrassBonemealable) - { - return false; - } - MTRand r1; - for (int i = 0; i < 60; i++) - { - int OfsX = (r1.randInt(3) + r1.randInt(3) + r1.randInt(3) + r1.randInt(3)) / 2 - 3; - int OfsY = r1.randInt(3) + r1.randInt(3) - 3; - int OfsZ = (r1.randInt(3) + r1.randInt(3) + r1.randInt(3) + r1.randInt(3)) / 2 - 3; - BLOCKTYPE Ground = GetBlock(a_BlockX + OfsX, a_BlockY + OfsY, a_BlockZ + OfsZ); - if (Ground != E_BLOCK_GRASS) - { - continue; - } - BLOCKTYPE Above = GetBlock(a_BlockX + OfsX, a_BlockY + OfsY + 1, a_BlockZ + OfsZ); - if (Above != E_BLOCK_AIR) - { - continue; - } - BLOCKTYPE SpawnType; - NIBBLETYPE SpawnMeta = 0; - switch (r1.randInt(10)) - { - case 0: SpawnType = E_BLOCK_YELLOW_FLOWER; break; - case 1: SpawnType = E_BLOCK_RED_ROSE; break; - default: - { - SpawnType = E_BLOCK_TALL_GRASS; - SpawnMeta = E_META_TALL_GRASS_GRASS; - break; - } - } // switch (random spawn block) - FastSetBlock(a_BlockX + OfsX, a_BlockY + OfsY + 1, a_BlockZ + OfsZ, SpawnType, SpawnMeta); - } // for i - 50 times - return true; - } - - case E_BLOCK_SUGARCANE: - { - if (a_IsByBonemeal && !m_IsSugarcaneBonemealable) - { - return false; - } - m_ChunkMap->GrowSugarcane(a_BlockX, a_BlockY, a_BlockZ, m_MaxSugarcaneHeight); - return true; - } - - case E_BLOCK_CACTUS: - { - if (a_IsByBonemeal && !m_IsCactusBonemealable) - { - return false; - } - m_ChunkMap->GrowCactus(a_BlockX, a_BlockY, a_BlockZ, m_MaxCactusHeight); - return true; - } - } // switch (BlockType) - return false; -} - - - - - -void cWorld::GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockType) -{ - MTRand Rand; - m_ChunkMap->GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, Rand); -} - - - - - -int cWorld::GetBiomeAt (int a_BlockX, int a_BlockZ) -{ - return m_ChunkMap->GetBiomeAt(a_BlockX, a_BlockZ); -} - - - - - -void cWorld::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ) -{ - m_ChunkMap->SetBlock(a_X, a_Y, a_Z, a_BlockType, a_BlockMeta); - - GetSimulatorManager()->WakeUp(a_X, a_Y, a_Z); -} - - - - - -void cWorld::FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ) -{ - cCSLock Lock(m_CSFastSetBlock); - m_FastSetBlockQueue.push_back(sSetBlock(a_X, a_Y, a_Z, a_BlockType, a_BlockMeta)); -} - - - - - -char cWorld::GetBlock(int a_X, int a_Y, int a_Z) -{ - // First check if it isn't queued in the m_FastSetBlockQueue: - { - int X = a_X, Y = a_Y, Z = a_Z; - int ChunkX, ChunkY, ChunkZ; - AbsoluteToRelative(X, Y, Z, ChunkX, ChunkY, ChunkZ); - - cCSLock Lock(m_CSFastSetBlock); - for (sSetBlockList::iterator itr = m_FastSetBlockQueue.begin(); itr != m_FastSetBlockQueue.end(); ++itr) - { - if ((itr->x == X) && (itr->y == Y) && (itr->z == Z) && (itr->ChunkX == ChunkX) && (itr->ChunkZ == ChunkZ)) - { - return itr->BlockType; - } - } // for itr - m_FastSetBlockQueue[] - } - - return m_ChunkMap->GetBlock(a_X, a_Y, a_Z); -} - - - - - -char cWorld::GetBlockMeta( int a_X, int a_Y, int a_Z ) -{ - // First check if it isn't queued in the m_FastSetBlockQueue: - { - cCSLock Lock(m_CSFastSetBlock); - for (sSetBlockList::iterator itr = m_FastSetBlockQueue.begin(); itr != m_FastSetBlockQueue.end(); ++itr) - { - if ((itr->x == a_X) && (itr->y == a_Y) && (itr->y == a_Y)) - { - return itr->BlockMeta; - } - } // for itr - m_FastSetBlockQueue[] - } - - return m_ChunkMap->GetBlockMeta(a_X, a_Y, a_Z); -} - - - - - -void cWorld::SetBlockMeta( int a_X, int a_Y, int a_Z, char a_MetaData ) -{ - m_ChunkMap->SetBlockMeta(a_X, a_Y, a_Z, a_MetaData); -} - - - - - -char cWorld::GetBlockSkyLight( int a_X, int a_Y, int a_Z ) -{ - return m_ChunkMap->GetBlockSkyLight(a_X, a_Y, a_Z); -} - - - - - -void cWorld::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, char & a_BlockType, unsigned char & a_BlockMeta) -{ - m_ChunkMap->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, (BLOCKTYPE &)a_BlockType, (NIBBLETYPE &)a_BlockMeta); -} - - - - - -void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_FlyAwaySpeed) -{ - MTRand r1; - a_FlyAwaySpeed /= 1000; // Pre-divide, so that we can don't have to divide each time inside the loop - for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr) - { - float SpeedX = (float)(a_FlyAwaySpeed * (r1.randInt(1000) - 500)); - float SpeedY = (float)(a_FlyAwaySpeed * r1.randInt(1000)); - float SpeedZ = (float)(a_FlyAwaySpeed * (r1.randInt(1000) - 500)); - cPickup * Pickup = new cPickup( - (int)(a_BlockX * 32) + r1.randInt(16) + r1.randInt(16), - (int)(a_BlockY * 32) + r1.randInt(16) + r1.randInt(16), - (int)(a_BlockZ * 32) + r1.randInt(16) + r1.randInt(16), - *itr, SpeedX, SpeedY, SpeedZ - ); - Pickup->Initialize(this); - } -} - - - - - -void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ) -{ - MTRand r1; - for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr) - { - cPickup * Pickup = new cPickup( - (int)(a_BlockX * 32) + r1.randInt(16) + r1.randInt(16), - (int)(a_BlockY * 32) + r1.randInt(16) + r1.randInt(16), - (int)(a_BlockZ * 32) + r1.randInt(16) + r1.randInt(16), - *itr, (float)a_SpeedX, (float)a_SpeedY, (float)a_SpeedZ - ); - Pickup->Initialize(this); - } -} - - - - - -void cWorld::ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType) -{ - m_ChunkMap->ReplaceBlocks(a_Blocks, a_FilterBlockType); -} - - - - - -bool cWorld::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure) -{ - return m_ChunkMap->GetBlocks(a_Blocks, a_ContinueOnFailure); -} - - - - - -bool cWorld::DigBlock( int a_X, int a_Y, int a_Z) -{ - return m_ChunkMap->DigBlock(a_X, a_Y, a_Z); -} - - - - - -void cWorld::SendBlockTo( int a_X, int a_Y, int a_Z, cPlayer * a_Player ) -{ - m_ChunkMap->SendBlockTo(a_X, a_Y, a_Z, a_Player); -} - - - - - -// TODO: This interface is dangerous! -cBlockEntity * cWorld::GetBlockEntity( int a_X, int a_Y, int a_Z ) -{ - return NULL; -} - - - - - -int cWorld::GetHeight( int a_X, int a_Z ) -{ - return m_ChunkMap->GetHeight(a_X, a_Z); -} - - - - - -const double & cWorld::GetSpawnY(void) -{ - return m_SpawnY; -} - - - - -void cWorld::Broadcast( const cPacket & a_Packet, cClientHandle * a_Exclude) -{ - cCSLock Lock(m_CSPlayers); - for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) - { - cClientHandle * ch = (*itr)->GetClientHandle(); - if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) - { - continue; - } - (*itr)->GetClientHandle()->Send( a_Packet ); - } -} - - - - - -void cWorld::BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude) -{ - m_ChunkMap->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, a_Packet, a_Exclude); -} - - - - - -void cWorld::BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, cPacket * a_Packet, cClientHandle * a_Exclude) -{ - m_ChunkMap->BroadcastToChunkOfBlock(a_X, a_Y, a_Z, a_Packet, a_Exclude); -} - - - - - -void cWorld::MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - m_ChunkMap->MarkChunkDirty (a_ChunkX, a_ChunkY, a_ChunkZ); -} - - - - - -void cWorld::MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - m_ChunkMap->MarkChunkSaving(a_ChunkX, a_ChunkY, a_ChunkZ); -} - - - - - -void cWorld::MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - m_ChunkMap->MarkChunkSaved (a_ChunkX, a_ChunkY, a_ChunkZ); -} - - - - - -void cWorld::SetChunkData( - int a_ChunkX, int a_ChunkY, int a_ChunkZ, - const BLOCKTYPE * a_BlockTypes, - const NIBBLETYPE * a_BlockMeta, - const NIBBLETYPE * a_BlockLight, - const NIBBLETYPE * a_BlockSkyLight, - const cChunkDef::HeightMap * a_HeightMap, - const cChunkDef::BiomeMap * a_BiomeMap, - cEntityList & a_Entities, - cBlockEntityList & a_BlockEntities, - bool a_MarkDirty -) -{ - // Validate biomes, if needed: - cChunkDef::BiomeMap BiomeMap; - const cChunkDef::BiomeMap * Biomes = a_BiomeMap; - if (a_BiomeMap == NULL) - { - // The biomes are not assigned, get them from the generator: - Biomes = &BiomeMap; - m_Generator.GenerateBiomes(a_ChunkX, a_ChunkZ, BiomeMap); - } - - m_ChunkMap->SetChunkData( - a_ChunkX, a_ChunkY, a_ChunkZ, - a_BlockTypes, a_BlockMeta, a_BlockLight, a_BlockSkyLight, - a_HeightMap, *Biomes, - a_Entities, a_BlockEntities, - a_MarkDirty - ); - - // If a client is requesting this chunk, send it to them: - if (m_ChunkMap->HasChunkAnyClients(a_ChunkX, a_ChunkY, a_ChunkZ)) - { - m_ChunkSender.ChunkReady(a_ChunkX, a_ChunkY, a_ChunkZ); - } - - // Notify the lighting thread that the chunk has become valid (in case it is a neighbor of a postponed chunk): - m_Lighting.ChunkReady(a_ChunkX, a_ChunkZ); -} - - - - - -void cWorld::ChunkLighted( - int a_ChunkX, int a_ChunkZ, - const cChunkDef::BlockNibbles & a_BlockLight, - const cChunkDef::BlockNibbles & a_SkyLight -) -{ - m_ChunkMap->ChunkLighted(a_ChunkX, a_ChunkZ, a_BlockLight, a_SkyLight); -} - - - - - -bool cWorld::GetChunkData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback) -{ - return m_ChunkMap->GetChunkData(a_ChunkX, a_ChunkY, a_ChunkZ, a_Callback); -} - - - - - -bool cWorld::GetChunkBlockTypes(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockTypes) -{ - return m_ChunkMap->GetChunkBlockTypes(a_ChunkX, a_ChunkY, a_ChunkZ, a_BlockTypes); -} - - - - - -bool cWorld::GetChunkBlockData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData) -{ - return m_ChunkMap->GetChunkBlockData(a_ChunkX, a_ChunkY, a_ChunkZ, a_BlockData); -} - - - - - -bool cWorld::IsChunkValid(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const -{ - return m_ChunkMap->IsChunkValid(a_ChunkX, a_ChunkY, a_ChunkZ); -} - - - - - -bool cWorld::HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const -{ - return m_ChunkMap->HasChunkAnyClients(a_ChunkX, a_ChunkY, a_ChunkZ); -} - - - - - -void cWorld::UnloadUnusedChunks(void ) -{ - m_LastUnload = m_Time; - m_ChunkMap->UnloadUnusedChunks(); -} - - - - - -void cWorld::CollectPickupsByPlayer(cPlayer * a_Player) -{ - m_ChunkMap->CollectPickupsByPlayer(a_Player); -} - - - - - -void cWorld::SetMaxPlayers(int iMax) -{ - m_MaxPlayers = MAX_PLAYERS; - if (iMax > 0 && iMax < MAX_PLAYERS) - { - m_MaxPlayers = iMax; - } -} - - - - - -void cWorld::AddPlayer( cPlayer* a_Player ) -{ - cCSLock Lock(m_CSPlayers); - - ASSERT(std::find(m_Players.begin(), m_Players.end(), a_Player) == m_Players.end()); // Is it already in the list? HOW? - - m_Players.remove( a_Player ); // Make sure the player is registered only once - m_Players.push_back( a_Player ); -} - - - - - -void cWorld::RemovePlayer( cPlayer* a_Player ) -{ - cCSLock Lock(m_CSPlayers); - m_Players.remove( a_Player ); -} - - - - - -bool cWorld::ForEachPlayer(cPlayerListCallback & a_Callback) -{ - // Calls the callback for each player in the list - cCSLock Lock(m_CSPlayers); - for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) - { - if (a_Callback.Item(*itr)) - { - return false; - } - } // for itr - m_Players[] - return true; -} - - - - -// TODO: This interface is dangerous! -cPlayer* cWorld::GetPlayer( const char* a_PlayerName ) -{ - cPlayer* BestMatch = 0; - unsigned int MatchedLetters = 0; - unsigned int NumMatches = 0; - bool bPerfectMatch = false; - - unsigned int NameLength = strlen( a_PlayerName ); - cCSLock Lock(m_CSPlayers); - for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); itr++ ) - { - std::string Name = (*itr)->GetName(); - if( NameLength > Name.length() ) continue; // Definitely not a match - - for (unsigned int i = 0; i < NameLength; i++) - { - char c1 = (char)toupper( a_PlayerName[i] ); - char c2 = (char)toupper( Name[i] ); - if( c1 == c2 ) - { - if( i+1 > MatchedLetters ) - { - MatchedLetters = i+1; - BestMatch = *itr; - } - if( i+1 == NameLength ) - { - NumMatches++; - if( NameLength == Name.length() ) - { - bPerfectMatch = true; - break; - } - } - } - else - { - if( BestMatch == *itr ) BestMatch = 0; - break; - } - if( bPerfectMatch ) - break; - } - } - if ( NumMatches == 1 ) - { - return BestMatch; - } - - // More than one matches, so it's undefined. Return NULL instead - return NULL; -} - - - - - -cPlayer * cWorld::FindClosestPlayer(const Vector3f & a_Pos, float a_SightLimit) -{ - cTracer LineOfSight(this); - - float ClosestDistance = a_SightLimit; - cPlayer* ClosestPlayer = NULL; - - cCSLock Lock(m_CSPlayers); - for (cPlayerList::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) - { - Vector3f Pos = (*itr)->GetPosition(); - float Distance = (Pos - a_Pos).Length(); - - if (Distance <= a_SightLimit) - { - if (!LineOfSight.Trace(a_Pos,(Pos - a_Pos),(int)(Pos - a_Pos).Length())) - { - if (Distance < ClosestDistance) - { - ClosestDistance = Distance; - ClosestPlayer = *itr; - } - } - } - } - return ClosestPlayer; -} - - - - - -void cWorld::SendPlayerList(cPlayer * a_DestPlayer) -{ - // Sends the playerlist to a_DestPlayer - cCSLock Lock(m_CSPlayers); - for ( cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) - { - cClientHandle * ch = (*itr)->GetClientHandle(); - if ((ch != NULL) && !ch->IsDestroyed()) - { - cPacket_PlayerListItem PlayerListItem((*itr)->GetColor() + (*itr)->GetName(), true, (*itr)->GetClientHandle()->GetPing()); - a_DestPlayer->GetClientHandle()->Send( PlayerListItem ); - } - } -} - - - - - -bool cWorld::DoWithEntity( int a_UniqueID, cEntityCallback & a_Callback ) -{ - cCSLock Lock(m_CSEntities); - for (cEntityList::iterator itr = m_AllEntities.begin(); itr != m_AllEntities.end(); ++itr ) - { - if( (*itr)->GetUniqueID() == a_UniqueID ) - { - return a_Callback.Item(*itr); - } - } // for itr - m_AllEntities[] - return false; -} - - - - - -void cWorld::RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - m_ChunkMap->RemoveEntityFromChunk(a_Entity, a_ChunkX, a_ChunkY, a_ChunkZ); -} - - - - - -void cWorld::MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - m_ChunkMap->MoveEntityToChunk(a_Entity, a_ChunkX, a_ChunkY, a_ChunkZ); -} - - - - - -void cWorld::CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback) -{ - m_ChunkMap->CompareChunkClients(a_ChunkX1, a_ChunkY1, a_ChunkZ1, a_ChunkX2, a_ChunkY2, a_ChunkZ2, a_Callback); -} - - - - - -bool cWorld::AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) -{ - return m_ChunkMap->AddChunkClient(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client); -} - - - - - -void cWorld::RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) -{ - m_ChunkMap->RemoveChunkClient(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client); -} - - - - - -void cWorld::RemoveClientFromChunks(cClientHandle * a_Client) -{ - m_ChunkMap->RemoveClientFromChunks(a_Client); -} - - - - - -void cWorld::SendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) -{ - m_ChunkSender.QueueSendChunkTo(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client); -} - - - - - -void cWorld::RemoveClientFromChunkSender(cClientHandle * a_Client) -{ - m_ChunkSender.RemoveClient(a_Client); -} - - - - - -void cWorld::TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - m_ChunkMap->TouchChunk(a_ChunkX, a_ChunkY, a_ChunkZ); -} - - - - - -bool cWorld::LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - return m_ChunkMap->LoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ); -} - - - - - -void cWorld::LoadChunks(const cChunkCoordsList & a_Chunks) -{ - m_ChunkMap->LoadChunks(a_Chunks); -} - - - - - -void cWorld::ChunkLoadFailed(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -{ - m_ChunkMap->ChunkLoadFailed(a_ChunkX, a_ChunkY, a_ChunkZ); -} - - - - - -void cWorld::UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) -{ - m_ChunkMap->UpdateSign(a_X, a_Y, a_Z, a_Line1, a_Line2, a_Line3, a_Line4); -} - - - - - -void cWorld::ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay) -{ - m_ChunkMap->ChunksStay(a_Chunks, a_Stay); -} - - - - - -void cWorld::RegenerateChunk(int a_ChunkX, int a_ChunkZ) -{ - m_ChunkMap->MarkChunkRegenerating(a_ChunkX, a_ChunkZ); - - // Trick: use Y=1 to force the chunk generation even though the chunk data is already present - m_Generator.QueueGenerateChunk(a_ChunkX, 1, a_ChunkZ); -} - - - - - -void cWorld::GenerateChunk(int a_ChunkX, int a_ChunkZ) -{ - m_Generator.QueueGenerateChunk(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); -} - - - - - -void cWorld::QueueLightChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback) -{ - m_Lighting.QueueChunk(a_ChunkX, a_ChunkZ, a_Callback); -} - - - - - -bool cWorld::IsChunkLighted(int a_ChunkX, int a_ChunkZ) -{ - return m_ChunkMap->IsChunkLighted(a_ChunkX, a_ChunkZ); -} - - - - - -void cWorld::SaveAllChunks(void) -{ - LOG("Saving all chunks..."); - m_LastSave = m_Time; - m_ChunkMap->SaveAllChunks(); -} - - - - - -/************************************************************************/ -/* Get and set */ -/************************************************************************/ -// void cWorld::AddClient( cClientHandle* a_Client ) -// { -// m_m_Clients.push_back( a_Client ); -// } -// cWorld::ClientList & cWorld::GetClients() -// { -// return m_m_Clients; -// } - - - - - -void cWorld::AddEntity( cEntity* a_Entity ) -{ - cCSLock Lock(m_CSEntities); - m_AllEntities.push_back( a_Entity ); -} - - - - - -unsigned int cWorld::GetNumPlayers() -{ - cCSLock Lock(m_CSPlayers); - return m_Players.size(); -} - - - - - -int cWorld::GetNumChunks(void) const -{ - return m_ChunkMap->GetNumChunks(); -} - - - - - -void cWorld::GetChunkStats(int & a_NumValid, int & a_NumDirty, int & a_NumInLightingQueue) -{ - m_ChunkMap->GetChunkStats(a_NumValid, a_NumDirty); - a_NumInLightingQueue = (int) m_Lighting.GetQueueLength(); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "BlockID.h" +#include "cWorld.h" +#include "cRedstone.h" +#include "ChunkDef.h" +#include "cClientHandle.h" +#include "cPickup.h" +#include "cBlockToPickup.h" +#include "cPlayer.h" +#include "cServer.h" +#include "cItem.h" +#include "cRoot.h" +#include "../iniFile/iniFile.h" +#include "cChunkMap.h" +#include "cSimulatorManager.h" +#include "cWaterSimulator.h" +#include "cLavaSimulator.h" +#include "cFireSimulator.h" +#include "cSandSimulator.h" +#include "cRedstoneSimulator.h" +#include "cChicken.h" +#include "cSpider.h" +#include "cCow.h" //cow +#include "cSquid.h" //Squid +#include "cWolf.h" //wolf +#include "cSlime.h" //slime +#include "cSkeleton.h" //Skeleton +#include "cSilverfish.h" //Silverfish +#include "cPig.h" //pig +#include "cSheep.h" //sheep +#include "cZombie.h" //zombie +#include "cEnderman.h" //enderman +#include "cCreeper.h" //creeper +#include "cCavespider.h" //cavespider +#include "cGhast.h" //Ghast +#include "cZombiepigman.h" //Zombiepigman +#include "cMakeDir.h" +#include "cChunkGenerator.h" +#include "MersenneTwister.h" +#include "cTracer.h" +#include "Trees.h" +#include "cPluginManager.h" + + +#include "packets/cPacket_TimeUpdate.h" +#include "packets/cPacket_NewInvalidState.h" +#include "packets/cPacket_Thunderbolt.h" + +#include "Vector3d.h" + +#include + +#include "tolua++.h" + +#ifndef _WIN32 + #include +#endif + + + + + +/// Up to this many m_SpreadQueue elements are handled each world tick +const int MAX_LIGHTING_SPREAD_PER_TICK = 10; + + + + + +float cWorld::m_Time = 0.f; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cWorldLoadProgress: + +/// A simple thread that displays the progress of world loading / saving in cWorld::InitializeSpawn() +class cWorldLoadProgress : + public cIsThread +{ +public: + cWorldLoadProgress(cWorld * a_World) : + cIsThread("cWorldLoadProgress"), + m_World(a_World) + { + Start(); + } + + void Stop(void) + { + m_ShouldTerminate = true; + Wait(); + } + +protected: + + cWorld * m_World; + + virtual void Execute(void) override + { + for (;;) + { + LOG("%d chunks to load, %d chunks to generate", + m_World->GetStorage().GetLoadQueueLength(), + m_World->GetGenerator().GetQueueLength() + ); + + // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish + for (int i = 0; i < 20; i++) + { + cSleep::MilliSleep(100); + if (m_ShouldTerminate) + { + return; + } + } + } // for (-ever) + } + +} ; + + + + + +/// A simple thread that displays the progress of world lighting in cWorld::InitializeSpawn() +class cWorldLightingProgress : + public cIsThread +{ +public: + cWorldLightingProgress(cLightingThread * a_Lighting) : + cIsThread("cWorldLightingProgress"), + m_Lighting(a_Lighting) + { + Start(); + } + + void Stop(void) + { + m_ShouldTerminate = true; + Wait(); + } + +protected: + + cLightingThread * m_Lighting; + + virtual void Execute(void) override + { + for (;;) + { + LOG("%d chunks remaining to light", m_Lighting->GetQueueLength() + ); + + // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish + for (int i = 0; i < 20; i++) + { + cSleep::MilliSleep(100); + if (m_ShouldTerminate) + { + return; + } + } + } // for (-ever) + } + +} ; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cWorld: + +cWorld* cWorld::GetWorld() +{ + LOGWARN("WARNING: Using deprecated function cWorld::GetWorld() use cRoot::Get()->GetDefaultWorld() instead!"); + return cRoot::Get()->GetDefaultWorld(); +} + + + + + +cWorld::~cWorld() +{ + { + cCSLock Lock(m_CSEntities); + while( m_AllEntities.begin() != m_AllEntities.end() ) + { + cEntity* Entity = *m_AllEntities.begin(); + m_AllEntities.remove( Entity ); + if ( !Entity->IsDestroyed() ) + { + Entity->Destroy(); + } + delete Entity; + } + } + + delete m_SimulatorManager; + delete m_SandSimulator; + delete m_WaterSimulator; + delete m_LavaSimulator; + delete m_FireSimulator; + delete m_RedstoneSimulator; + + m_Generator.Stop(); + m_ChunkSender.Stop(); + + UnloadUnusedChunks(); + + m_Storage.WaitForFinish(); + + delete m_ChunkMap; +} + + + + + +cWorld::cWorld( const AString & a_WorldName ) + : m_SpawnMonsterTime( 0.f ) + , m_RSList ( 0 ) + , m_Weather ( eWeather_Sunny ) +{ + LOG("cWorld::cWorld(%s)", a_WorldName.c_str()); + m_WorldName = a_WorldName; + m_IniFileName = m_WorldName + "/world.ini"; + + cMakeDir::MakeDir(m_WorldName.c_str()); + + MTRand r1; + m_SpawnX = (double)((r1.randInt() % 1000) - 500); + m_SpawnY = cChunkDef::Height; + m_SpawnZ = (double)((r1.randInt() % 1000) - 500); + m_GameMode = eGameMode_Creative; + + AString StorageSchema("Default"); + + cIniFile IniFile(m_IniFileName); + IniFile.ReadFile(); + m_SpawnX = IniFile.GetValueSetF("SpawnPosition", "X", m_SpawnX); + m_SpawnY = IniFile.GetValueSetF("SpawnPosition", "Y", m_SpawnY); + m_SpawnZ = IniFile.GetValueSetF("SpawnPosition", "Z", m_SpawnZ); + StorageSchema = IniFile.GetValueSet ("Storage", "Schema", StorageSchema); + m_MaxCactusHeight = IniFile.GetValueSetI("Plants", "MaxCactusHeight", 3); + m_MaxSugarcaneHeight = IniFile.GetValueSetI("Plants", "MaxSugarcaneHeight", 3); + m_IsCropsBonemealable = IniFile.GetValueSetB("Plants", "IsCropsBonemealable", true); + m_IsGrassBonemealable = IniFile.GetValueSetB("Plants", "IsGrassBonemealable", true); + m_IsSaplingBonemealable = IniFile.GetValueSetB("Plants", "IsSaplingBonemealable", true); + m_IsMelonStemBonemealable = IniFile.GetValueSetB("Plants", "IsMelonStemBonemealable", true); + m_IsMelonBonemealable = IniFile.GetValueSetB("Plants", "IsMelonBonemealable", false); + m_IsPumpkinStemBonemealable = IniFile.GetValueSetB("Plants", "IsPumpkinStemBonemealable", true); + m_IsPumpkinBonemealable = IniFile.GetValueSetB("Plants", "IsPumpkinBonemealable", false); + m_IsSugarcaneBonemealable = IniFile.GetValueSetB("Plants", "IsSugarcaneBonemealable", false); + m_IsCactusBonemealable = IniFile.GetValueSetB("Plants", "IsCactusBonemealable", false); + + m_GameMode = (eGameMode)IniFile.GetValueSetI("GameMode", "GameMode", m_GameMode ); + + if (!IniFile.WriteFile()) + { + LOG("WARNING: Could not write to %s", m_IniFileName.c_str()); + } + + m_Lighting.Start(this); + m_Storage.Start(this, StorageSchema); + m_Generator.Start(this, IniFile); + + m_bAnimals = true; + m_SpawnMonsterRate = 10; + cIniFile IniFile2("settings.ini"); + if( IniFile2.ReadFile() ) + { + m_bAnimals = IniFile2.GetValueB("Monsters", "AnimalsOn", true ); + m_SpawnMonsterRate = (float)IniFile2.GetValueF("Monsters", "AnimalSpawnInterval", 10); + SetMaxPlayers(IniFile2.GetValueI("Server", "MaxPlayers", 9001)); + m_Description = IniFile2.GetValue("Server", "Description", "MCServer! - It's OVER 9000!").c_str(); + } + + m_ChunkMap = new cChunkMap(this ); + + m_ChunkSender.Start(this); + + m_Time = 0; + m_WorldTimeFraction = 0.f; + m_WorldTime = 0; + m_LastSave = 0; + m_LastUnload = 0; + + //Simulators: + m_WaterSimulator = new cWaterSimulator( this ); + m_LavaSimulator = new cLavaSimulator( this ); + m_SandSimulator = new cSandSimulator(this); + m_FireSimulator = new cFireSimulator(this); + m_RedstoneSimulator = new cRedstoneSimulator(this); + + m_SimulatorManager = new cSimulatorManager(); + m_SimulatorManager->RegisterSimulator(m_WaterSimulator, 6); + m_SimulatorManager->RegisterSimulator(m_LavaSimulator, 12); + m_SimulatorManager->RegisterSimulator(m_SandSimulator, 1); + m_SimulatorManager->RegisterSimulator(m_FireSimulator, 10); + m_SimulatorManager->RegisterSimulator(m_RedstoneSimulator, 1); +} + + + + + +void cWorld::SetWeather( eWeather a_Weather ) +{ + switch( a_Weather ) + { + case eWeather_Sunny: + { + m_Weather = a_Weather; + cPacket_NewInvalidState WeatherPacket; + WeatherPacket.m_Reason = 2; //stop rain + Broadcast ( WeatherPacket ); + } + break; + case eWeather_Rain: + { + m_Weather = a_Weather; + cPacket_NewInvalidState WeatherPacket; + WeatherPacket.m_Reason = 1; //begin rain + Broadcast ( WeatherPacket ); + } + break; + case eWeather_ThunderStorm: + { + m_Weather = a_Weather; + cPacket_NewInvalidState WeatherPacket; + WeatherPacket.m_Reason = 1; //begin rain + Broadcast ( WeatherPacket ); + CastThunderbolt ( 0, 0, 0 ); //start thunderstorm with a lightning strike at 0, 0, 0. >:D + } + break; + default: + LOGWARN("Trying to set unknown weather %d", a_Weather ); + break; + } +} + + + + + +void cWorld::CastThunderbolt ( int a_X, int a_Y, int a_Z ) +{ + cPacket_Thunderbolt ThunderboltPacket; + ThunderboltPacket.m_xLBPos = a_X; + ThunderboltPacket.m_yLBPos = a_Y; + ThunderboltPacket.m_zLBPos = a_Z; + BroadcastToChunkOfBlock(a_X, a_Y, a_Z, &ThunderboltPacket); +} + + + + + +bool cWorld::IsPlacingItemLegal(Int16 a_ItemType, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + BLOCKTYPE SurfaceBlock = GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ); + switch (a_ItemType) + { + case E_BLOCK_YELLOW_FLOWER: // Can ONLY be placed on dirt/grass + case E_BLOCK_RED_ROSE: + case E_BLOCK_SAPLING: + { + switch (SurfaceBlock) + { + case E_BLOCK_DIRT: + case E_BLOCK_GRASS: + case E_BLOCK_FARMLAND: + { + return true; + } + } + return false; + } + + case E_BLOCK_BROWN_MUSHROOM: // Can be placed on pretty much anything, with exceptions + case E_BLOCK_RED_MUSHROOM: + { + switch (SurfaceBlock) + { + case E_BLOCK_GLASS: + case E_BLOCK_YELLOW_FLOWER: + case E_BLOCK_RED_ROSE: + case E_BLOCK_BROWN_MUSHROOM: + case E_BLOCK_RED_MUSHROOM: + case E_BLOCK_CACTUS: + { + return false; + } + } + return true; + } + + case E_BLOCK_CACTUS: + { + if ((SurfaceBlock != E_BLOCK_SAND) && (SurfaceBlock != E_BLOCK_CACTUS)) + { + // Cactus can only be placed on sand and itself + return false; + } + + // Check surroundings. Cacti may ONLY be surrounded by air + if ( + (GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ) != E_BLOCK_AIR) || + (GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ) != E_BLOCK_AIR) || + (GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1) != E_BLOCK_AIR) || + (GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1) != E_BLOCK_AIR) + ) + { + return false; + } + return true; + } + + case E_ITEM_SEEDS: + case E_ITEM_MELON_SEEDS: + case E_ITEM_PUMPKIN_SEEDS: + { + // Seeds can go only on the farmland block: + return (SurfaceBlock == E_BLOCK_FARMLAND); + } + } // switch (a_Packet->m_ItemType) + return true; +} + + + + + +void cWorld::SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + return m_ChunkMap->SetNextBlockTick(a_BlockX, a_BlockY, a_BlockZ); +} + + + + + +void cWorld::InitializeSpawn(void) +{ + int ChunkX = 0, ChunkY = 0, ChunkZ = 0; + BlockToChunk( (int)m_SpawnX, (int)m_SpawnY, (int)m_SpawnZ, ChunkX, ChunkY, ChunkZ ); + + // For the debugging builds, don't make the server build too much world upon start: + #ifdef _DEBUG + int ViewDist = 9; + #else + int ViewDist = 20; // Always prepare an area 20 chunks across, no matter what the actual cClientHandle::VIEWDISTANCE is + #endif // _DEBUG + + LOG("Preparing spawn area in world \"%s\"...", m_WorldName.c_str()); + for (int x = 0; x < ViewDist; x++) + { + for (int z = 0; z < ViewDist; z++) + { + m_ChunkMap->TouchChunk( x + ChunkX-(ViewDist - 1) / 2, ZERO_CHUNK_Y, z + ChunkZ-(ViewDist - 1) / 2 ); // Queue the chunk in the generator / loader + } + } + + { + // Display progress during this process: + cWorldLoadProgress Progress(this); + + // Wait for the loader to finish loading + m_Storage.WaitForQueuesEmpty(); + + // Wait for the generator to finish generating + m_Generator.WaitForQueueEmpty(); + + Progress.Stop(); + } + + // Light all chunks that have been newly generated: + LOG("Lighting spawn area in world \"%s\"...", m_WorldName.c_str()); + + for (int x = 0; x < ViewDist; x++) + { + int ChX = x + ChunkX-(ViewDist - 1) / 2; + for (int z = 0; z < ViewDist; z++) + { + int ChZ = z + ChunkZ-(ViewDist - 1) / 2; + if (!m_ChunkMap->IsChunkLighted(ChX, ChZ)) + { + m_Lighting.QueueChunk(ChX, ChZ); // Queue the chunk in the lighting thread + } + } // for z + } // for x + + { + cWorldLightingProgress Progress(&m_Lighting); + m_Lighting.WaitForQueueEmpty(); + Progress.Stop(); + } + + // TODO: Better spawn detection - move spawn out of the water if it isn't set in the INI already + m_SpawnY = (double)GetHeight( (int)m_SpawnX, (int)m_SpawnZ ) + 1.6f; // +1.6f eye height +} + + + + + +void cWorld::Tick(float a_Dt) +{ + m_Time += a_Dt / 1000.f; + + CurrentTick++; + + bool bSendTime = false; + m_WorldTimeFraction += a_Dt / 1000.f; + while ( m_WorldTimeFraction > 1.f ) + { + m_WorldTimeFraction -= 1.f; + m_WorldTime += 20; + bSendTime = true; + } + m_WorldTime %= 24000; // 24000 units in a day + if ( bSendTime ) + { + Broadcast( cPacket_TimeUpdate( (m_WorldTime) ) ); + } + + { + cCSLock Lock(m_CSEntities); + for (cEntityList::iterator itr = m_AllEntities.begin(); itr != m_AllEntities.end();) + { + if ((*itr)->IsDestroyed()) + { + LOG("Destroying entity #%i", (*itr)->GetUniqueID()); + cEntity * RemoveMe = *itr; + itr = m_AllEntities.erase( itr ); + m_RemoveEntityQueue.push_back( RemoveMe ); + continue; + } + (*itr)->Tick(a_Dt); + itr++; + } + } + + m_ChunkMap->Tick(a_Dt, m_TickRand); + + GetSimulatorManager()->Simulate(a_Dt); + + TickWeather(a_Dt); + + // Asynchronously set blocks: + sSetBlockList FastSetBlockQueueCopy; + { + cCSLock Lock(m_CSFastSetBlock); + std::swap(FastSetBlockQueueCopy, m_FastSetBlockQueue); + } + m_ChunkMap->FastSetBlocks(FastSetBlockQueueCopy); + if (!FastSetBlockQueueCopy.empty()) + { + // Some blocks failed, store them for next tick: + cCSLock Lock(m_CSFastSetBlock); + m_FastSetBlockQueue.splice(m_FastSetBlockQueue.end(), FastSetBlockQueueCopy); + } + + if( m_Time - m_LastSave > 60 * 5 ) // Save each 5 minutes + { + SaveAllChunks(); + } + + if( m_Time - m_LastUnload > 10 ) // Unload every 10 seconds + { + UnloadUnusedChunks(); + } + + // Delete entities queued for removal: + for (cEntityList::iterator itr = m_RemoveEntityQueue.begin(); itr != m_RemoveEntityQueue.end(); ++itr) + { + delete *itr; + } + m_RemoveEntityQueue.clear(); + + TickSpawnMobs(a_Dt); + + std::vector m_RSList_copy(m_RSList); + + m_RSList.clear(); + + std::vector::const_iterator cii; // FIXME - Please rename this variable, WTF is cii??? Use human readable variable names or common abbreviations (i, idx, itr, iter) + for(cii=m_RSList_copy.begin(); cii!=m_RSList_copy.end();) + { + int tempX = *cii;cii++; + int tempY = *cii;cii++; + int tempZ = *cii;cii++; + int state = *cii;cii++; + + if ( (state == 11111) && ( (int)GetBlock( tempX, tempY, tempZ ) == E_BLOCK_REDSTONE_TORCH_OFF ) ) + { + FastSetBlock( tempX, tempY, tempZ, E_BLOCK_REDSTONE_TORCH_ON, (int)GetBlockMeta( tempX, tempY, tempZ ) ); + cRedstone Redstone(this); + Redstone.ChangeRedstone( tempX, tempY, tempZ, true ); + } + else if ( (state == 00000) && ( (int)GetBlock( tempX, tempY, tempZ ) == E_BLOCK_REDSTONE_TORCH_ON ) ) + { + FastSetBlock( tempX, tempY, tempZ, E_BLOCK_REDSTONE_TORCH_OFF, (int)GetBlockMeta( tempX, tempY, tempZ ) ); + cRedstone Redstone(this); + Redstone.ChangeRedstone( tempX, tempY, tempZ, false ); + } + } + m_RSList_copy.erase(m_RSList_copy.begin(),m_RSList_copy.end()); +} + + + + + +void cWorld::ChangeWeather() +{ + unsigned randWeather = (m_TickRand.randInt() % 99); + + if (GetWeather() == eWeather_Sunny) + { + if (randWeather < 20) + { + LOG("Starting rainstorm!"); + SetWeather( eWeather_Rain ); + } + } + + else if (GetWeather() == eWeather_Rain) + { + if (randWeather < 5) + { + LOG("Thunderstorm!"); + SetWeather( eWeather_ThunderStorm ); + } + + else if (randWeather < 60) + { + LOG("Back to sunshine"); + SetWeather( eWeather_Sunny ); + } + } + + else if (GetWeather() == eWeather_ThunderStorm) + { + if (randWeather < 70) + { + SetWeather(eWeather_Sunny); + LOG("Thunder ended abruptly, returning to lovely sunshine"); + } + else if (randWeather < 85) + { + SetWeather(eWeather_Rain); + LOG("Thunder ended, but rain persists."); + } + else + { + return; + } + } +} + + + + + +void cWorld::TickWeather(float a_Dt) +{ + if(m_WeatherInterval == 0) + { + ChangeWeather(); + + cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::HOOK_WEATHER_CHANGE, 0 ); + + switch(GetWeather()) + { + case eWeather_Sunny: + m_WeatherInterval = 14400 + (m_TickRand.randInt() % 4800); // 12 - 16 minutes + break; + case eWeather_Rain: + m_WeatherInterval = 9600 + (m_TickRand.randInt() % 7200); // 8 - 14 minutes + break; + case eWeather_ThunderStorm: + m_WeatherInterval = 2400 + (m_TickRand.randInt() % 4800); // 2 - 6 minutes + break; + default: + LOG("Unknown weather occurred"); + break; + } + } + + else + { + m_WeatherInterval--; + } + + if ( GetWeather() == 2 ) // if thunderstorm + { + if (m_TickRand.randInt() % 199 == 0) // 0.5% chance per tick of thunderbolt + { + CastThunderbolt ( 0, 0, 0 ); // TODO: find random possitions near players to cast thunderbolts. + } + } +} + + + + + +void cWorld::TickSpawnMobs(float a_Dt) +{ + if (!m_bAnimals || (m_Time - m_SpawnMonsterTime <= m_SpawnMonsterRate)) + { + return; + } + + m_SpawnMonsterTime = m_Time; + Vector3d SpawnPos; + { + cCSLock Lock(m_CSPlayers); + if ( m_Players.size() <= 0) + { + return; + } + int RandomPlayerIdx = m_TickRand.randInt() & m_Players.size(); + cPlayerList::iterator itr = m_Players.begin(); + for( int i = 1; i < RandomPlayerIdx; i++ ) + { + itr++; + } + SpawnPos = (*itr)->GetPosition(); + } + + cMonster * Monster = NULL; + int dayRand = m_TickRand.randInt() % 6; + int nightRand = m_TickRand.randInt() % 10; + + SpawnPos += Vector3d( (double)(m_TickRand.randInt() % 64) - 32, (double)(m_TickRand.randInt() % 64) - 32, (double)(m_TickRand.randInt() % 64) - 32 ); + int Height = GetHeight( (int)SpawnPos.x, (int)SpawnPos.z ); + + if (m_WorldTime >= 12000 + 1000) + { + if (nightRand == 0) //random percent to spawn for night + Monster = new cSpider(); + else if (nightRand == 1) + Monster = new cZombie(); + else if (nightRand == 2) + Monster = new cEnderman(); + else if (nightRand == 3) + Monster = new cCreeper(); + else if (nightRand == 4) + Monster = new cCavespider(); + else if (nightRand == 5) + Monster = new cGhast(); + else if (nightRand == 6) + Monster = new cZombiepigman(); + else if (nightRand == 7) + Monster = new cSlime(); + else if (nightRand == 8) + Monster = new cSilverfish(); + else if (nightRand == 9) + Monster = new cSkeleton(); + //end random percent to spawn for night + } + else + { + if (dayRand == 0) //random percent to spawn for day + Monster = new cChicken(); + else if (dayRand == 1) + Monster = new cCow(); + else if (dayRand == 2) + Monster = new cPig(); + else if (dayRand == 3) + Monster = new cSheep(); + else if (dayRand == 4) + Monster = new cSquid(); + else if (dayRand == 5) + Monster = new cWolf(); + //end random percent to spawn for day + } + + if( Monster ) + { + Monster->Initialize( this ); + Monster->TeleportTo( SpawnPos.x, (double)(Height) + 2, SpawnPos.z ); + Monster->SpawnOn(0); + } +} + + + + + +void cWorld::GrowTree( int a_X, int a_Y, int a_Z ) +{ + if (GetBlock(a_X, a_Y, a_Z) == E_BLOCK_SAPLING) + { + // There is a sapling here, grow a tree according to its type: + GrowTreeFromSapling(a_X, a_Y, a_Z, GetBlockMeta(a_X, a_Y, a_Z)); + } + else + { + // There is nothing here, grow a tree based on the current biome here: + GrowTreeByBiome(a_X, a_Y, a_Z); + } +} + + + + + +void cWorld::GrowTreeFromSapling(int a_X, int a_Y, int a_Z, char a_SaplingMeta) +{ + cNoise Noise(m_Generator.GetSeed()); + sSetBlockVector Blocks; + switch (a_SaplingMeta & 0x07) + { + case E_META_SAPLING_APPLE: GetAppleTreeImage (a_X, a_Y, a_Z, Noise, (int)(m_WorldTime & 0xffffffff), Blocks); break; + case E_META_SAPLING_BIRCH: GetBirchTreeImage (a_X, a_Y, a_Z, Noise, (int)(m_WorldTime & 0xffffffff), Blocks); break; + case E_META_SAPLING_CONIFER: GetConiferTreeImage(a_X, a_Y, a_Z, Noise, (int)(m_WorldTime & 0xffffffff), Blocks); break; + case E_META_SAPLING_JUNGLE: GetJungleTreeImage (a_X, a_Y, a_Z, Noise, (int)(m_WorldTime & 0xffffffff), Blocks); break; + } + + GrowTreeImage(Blocks); +} + + + + + +void cWorld::GrowTreeByBiome(int a_X, int a_Y, int a_Z) +{ + cNoise Noise(m_Generator.GetSeed()); + sSetBlockVector Blocks; + GetTreeImageByBiome(a_X, a_Y, a_Z, Noise, (int)(m_WorldTime & 0xffffffff), (EMCSBiome)GetBiomeAt(a_X, a_Z), Blocks); + GrowTreeImage(Blocks); +} + + + + + +void cWorld::GrowTreeImage(const sSetBlockVector & a_Blocks) +{ + // Check that the tree has place to grow + + // Make a copy of the log blocks: + sSetBlockVector b2; + for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) + { + if (itr->BlockType == E_BLOCK_LOG) + { + b2.push_back(*itr); + } + } // for itr - a_Blocks[] + + // Query blocktypes and metas at those log blocks: + if (!GetBlocks(b2, false)) + { + return; + } + + // Check that at each log's coord there's an block allowed to be overwritten: + for (sSetBlockVector::const_iterator itr = b2.begin(); itr != b2.end(); ++itr) + { + switch (itr->BlockType) + { + CASE_TREE_ALLOWED_BLOCKS: + { + break; + } + default: + { + return; + } + } + } // for itr - b2[] + + // All ok, replace blocks with the tree image: + m_ChunkMap->ReplaceTreeBlocks(a_Blocks); +} + + + + + +bool cWorld::GrowPlant(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_IsByBonemeal) +{ + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta); + switch (BlockType) + { + case E_BLOCK_CROPS: + { + if (a_IsByBonemeal && !m_IsGrassBonemealable) + { + return false; + } + if (BlockMeta < 7) + { + FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, 7); + } + return true; + } + + case E_BLOCK_MELON_STEM: + { + if (BlockMeta < 7) + { + if (a_IsByBonemeal && !m_IsMelonStemBonemealable) + { + return false; + } + FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, 7); + } + else + { + if (a_IsByBonemeal && !m_IsMelonBonemealable) + { + return false; + } + GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, BlockType); + } + return true; + } + + case E_BLOCK_PUMPKIN_STEM: + { + if (BlockMeta < 7) + { + if (a_IsByBonemeal && !m_IsPumpkinStemBonemealable) + { + return false; + } + FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, 7); + } + else + { + if (a_IsByBonemeal && !m_IsPumpkinBonemealable) + { + return false; + } + GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, BlockType); + } + return true; + } + + case E_BLOCK_SAPLING: + { + if (a_IsByBonemeal && !m_IsSaplingBonemealable) + { + return false; + } + GrowTreeFromSapling(a_BlockX, a_BlockY, a_BlockZ, BlockMeta); + return true; + } + + case E_BLOCK_GRASS: + { + if (a_IsByBonemeal && !m_IsGrassBonemealable) + { + return false; + } + MTRand r1; + for (int i = 0; i < 60; i++) + { + int OfsX = (r1.randInt(3) + r1.randInt(3) + r1.randInt(3) + r1.randInt(3)) / 2 - 3; + int OfsY = r1.randInt(3) + r1.randInt(3) - 3; + int OfsZ = (r1.randInt(3) + r1.randInt(3) + r1.randInt(3) + r1.randInt(3)) / 2 - 3; + BLOCKTYPE Ground = GetBlock(a_BlockX + OfsX, a_BlockY + OfsY, a_BlockZ + OfsZ); + if (Ground != E_BLOCK_GRASS) + { + continue; + } + BLOCKTYPE Above = GetBlock(a_BlockX + OfsX, a_BlockY + OfsY + 1, a_BlockZ + OfsZ); + if (Above != E_BLOCK_AIR) + { + continue; + } + BLOCKTYPE SpawnType; + NIBBLETYPE SpawnMeta = 0; + switch (r1.randInt(10)) + { + case 0: SpawnType = E_BLOCK_YELLOW_FLOWER; break; + case 1: SpawnType = E_BLOCK_RED_ROSE; break; + default: + { + SpawnType = E_BLOCK_TALL_GRASS; + SpawnMeta = E_META_TALL_GRASS_GRASS; + break; + } + } // switch (random spawn block) + FastSetBlock(a_BlockX + OfsX, a_BlockY + OfsY + 1, a_BlockZ + OfsZ, SpawnType, SpawnMeta); + } // for i - 50 times + return true; + } + + case E_BLOCK_SUGARCANE: + { + if (a_IsByBonemeal && !m_IsSugarcaneBonemealable) + { + return false; + } + m_ChunkMap->GrowSugarcane(a_BlockX, a_BlockY, a_BlockZ, m_MaxSugarcaneHeight); + return true; + } + + case E_BLOCK_CACTUS: + { + if (a_IsByBonemeal && !m_IsCactusBonemealable) + { + return false; + } + m_ChunkMap->GrowCactus(a_BlockX, a_BlockY, a_BlockZ, m_MaxCactusHeight); + return true; + } + } // switch (BlockType) + return false; +} + + + + + +void cWorld::GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockType) +{ + MTRand Rand; + m_ChunkMap->GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, Rand); +} + + + + + +int cWorld::GetBiomeAt (int a_BlockX, int a_BlockZ) +{ + return m_ChunkMap->GetBiomeAt(a_BlockX, a_BlockZ); +} + + + + + +void cWorld::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ) +{ + m_ChunkMap->SetBlock(a_X, a_Y, a_Z, a_BlockType, a_BlockMeta); + + GetSimulatorManager()->WakeUp(a_X, a_Y, a_Z); +} + + + + + +void cWorld::FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ) +{ + cCSLock Lock(m_CSFastSetBlock); + m_FastSetBlockQueue.push_back(sSetBlock(a_X, a_Y, a_Z, a_BlockType, a_BlockMeta)); +} + + + + + +char cWorld::GetBlock(int a_X, int a_Y, int a_Z) +{ + // First check if it isn't queued in the m_FastSetBlockQueue: + { + int X = a_X, Y = a_Y, Z = a_Z; + int ChunkX, ChunkY, ChunkZ; + AbsoluteToRelative(X, Y, Z, ChunkX, ChunkY, ChunkZ); + + cCSLock Lock(m_CSFastSetBlock); + for (sSetBlockList::iterator itr = m_FastSetBlockQueue.begin(); itr != m_FastSetBlockQueue.end(); ++itr) + { + if ((itr->x == X) && (itr->y == Y) && (itr->z == Z) && (itr->ChunkX == ChunkX) && (itr->ChunkZ == ChunkZ)) + { + return itr->BlockType; + } + } // for itr - m_FastSetBlockQueue[] + } + + return m_ChunkMap->GetBlock(a_X, a_Y, a_Z); +} + + + + + +char cWorld::GetBlockMeta( int a_X, int a_Y, int a_Z ) +{ + // First check if it isn't queued in the m_FastSetBlockQueue: + { + cCSLock Lock(m_CSFastSetBlock); + for (sSetBlockList::iterator itr = m_FastSetBlockQueue.begin(); itr != m_FastSetBlockQueue.end(); ++itr) + { + if ((itr->x == a_X) && (itr->y == a_Y) && (itr->y == a_Y)) + { + return itr->BlockMeta; + } + } // for itr - m_FastSetBlockQueue[] + } + + return m_ChunkMap->GetBlockMeta(a_X, a_Y, a_Z); +} + + + + + +void cWorld::SetBlockMeta( int a_X, int a_Y, int a_Z, char a_MetaData ) +{ + m_ChunkMap->SetBlockMeta(a_X, a_Y, a_Z, a_MetaData); +} + + + + + +char cWorld::GetBlockSkyLight( int a_X, int a_Y, int a_Z ) +{ + return m_ChunkMap->GetBlockSkyLight(a_X, a_Y, a_Z); +} + + + + + +void cWorld::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, char & a_BlockType, unsigned char & a_BlockMeta) +{ + m_ChunkMap->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, (BLOCKTYPE &)a_BlockType, (NIBBLETYPE &)a_BlockMeta); +} + + + + + +void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_FlyAwaySpeed) +{ + MTRand r1; + a_FlyAwaySpeed /= 1000; // Pre-divide, so that we can don't have to divide each time inside the loop + for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr) + { + float SpeedX = (float)(a_FlyAwaySpeed * (r1.randInt(1000) - 500)); + float SpeedY = (float)(a_FlyAwaySpeed * r1.randInt(1000)); + float SpeedZ = (float)(a_FlyAwaySpeed * (r1.randInt(1000) - 500)); + cPickup * Pickup = new cPickup( + (int)(a_BlockX * 32) + r1.randInt(16) + r1.randInt(16), + (int)(a_BlockY * 32) + r1.randInt(16) + r1.randInt(16), + (int)(a_BlockZ * 32) + r1.randInt(16) + r1.randInt(16), + *itr, SpeedX, SpeedY, SpeedZ + ); + Pickup->Initialize(this); + } +} + + + + + +void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ) +{ + MTRand r1; + for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr) + { + cPickup * Pickup = new cPickup( + (int)(a_BlockX * 32) + r1.randInt(16) + r1.randInt(16), + (int)(a_BlockY * 32) + r1.randInt(16) + r1.randInt(16), + (int)(a_BlockZ * 32) + r1.randInt(16) + r1.randInt(16), + *itr, (float)a_SpeedX, (float)a_SpeedY, (float)a_SpeedZ + ); + Pickup->Initialize(this); + } +} + + + + + +void cWorld::ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType) +{ + m_ChunkMap->ReplaceBlocks(a_Blocks, a_FilterBlockType); +} + + + + + +bool cWorld::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure) +{ + return m_ChunkMap->GetBlocks(a_Blocks, a_ContinueOnFailure); +} + + + + + +bool cWorld::DigBlock( int a_X, int a_Y, int a_Z) +{ + return m_ChunkMap->DigBlock(a_X, a_Y, a_Z); +} + + + + + +void cWorld::SendBlockTo( int a_X, int a_Y, int a_Z, cPlayer * a_Player ) +{ + m_ChunkMap->SendBlockTo(a_X, a_Y, a_Z, a_Player); +} + + + + + +// TODO: This interface is dangerous! +cBlockEntity * cWorld::GetBlockEntity( int a_X, int a_Y, int a_Z ) +{ + return NULL; +} + + + + + +int cWorld::GetHeight( int a_X, int a_Z ) +{ + return m_ChunkMap->GetHeight(a_X, a_Z); +} + + + + + +const double & cWorld::GetSpawnY(void) +{ + return m_SpawnY; +} + + + + +void cWorld::Broadcast( const cPacket & a_Packet, cClientHandle * a_Exclude) +{ + cCSLock Lock(m_CSPlayers); + for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + cClientHandle * ch = (*itr)->GetClientHandle(); + if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + { + continue; + } + (*itr)->GetClientHandle()->Send( a_Packet ); + } +} + + + + + +void cWorld::BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude) +{ + m_ChunkMap->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, a_Packet, a_Exclude); +} + + + + + +void cWorld::BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, cPacket * a_Packet, cClientHandle * a_Exclude) +{ + m_ChunkMap->BroadcastToChunkOfBlock(a_X, a_Y, a_Z, a_Packet, a_Exclude); +} + + + + + +void cWorld::MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + m_ChunkMap->MarkChunkDirty (a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +void cWorld::MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + m_ChunkMap->MarkChunkSaving(a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +void cWorld::MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + m_ChunkMap->MarkChunkSaved (a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +void cWorld::SetChunkData( + int a_ChunkX, int a_ChunkY, int a_ChunkZ, + const BLOCKTYPE * a_BlockTypes, + const NIBBLETYPE * a_BlockMeta, + const NIBBLETYPE * a_BlockLight, + const NIBBLETYPE * a_BlockSkyLight, + const cChunkDef::HeightMap * a_HeightMap, + const cChunkDef::BiomeMap * a_BiomeMap, + cEntityList & a_Entities, + cBlockEntityList & a_BlockEntities, + bool a_MarkDirty +) +{ + // Validate biomes, if needed: + cChunkDef::BiomeMap BiomeMap; + const cChunkDef::BiomeMap * Biomes = a_BiomeMap; + if (a_BiomeMap == NULL) + { + // The biomes are not assigned, get them from the generator: + Biomes = &BiomeMap; + m_Generator.GenerateBiomes(a_ChunkX, a_ChunkZ, BiomeMap); + } + + m_ChunkMap->SetChunkData( + a_ChunkX, a_ChunkY, a_ChunkZ, + a_BlockTypes, a_BlockMeta, a_BlockLight, a_BlockSkyLight, + a_HeightMap, *Biomes, + a_Entities, a_BlockEntities, + a_MarkDirty + ); + + // If a client is requesting this chunk, send it to them: + if (m_ChunkMap->HasChunkAnyClients(a_ChunkX, a_ChunkY, a_ChunkZ)) + { + m_ChunkSender.ChunkReady(a_ChunkX, a_ChunkY, a_ChunkZ); + } + + // Notify the lighting thread that the chunk has become valid (in case it is a neighbor of a postponed chunk): + m_Lighting.ChunkReady(a_ChunkX, a_ChunkZ); +} + + + + + +void cWorld::ChunkLighted( + int a_ChunkX, int a_ChunkZ, + const cChunkDef::BlockNibbles & a_BlockLight, + const cChunkDef::BlockNibbles & a_SkyLight +) +{ + m_ChunkMap->ChunkLighted(a_ChunkX, a_ChunkZ, a_BlockLight, a_SkyLight); +} + + + + + +bool cWorld::GetChunkData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback) +{ + return m_ChunkMap->GetChunkData(a_ChunkX, a_ChunkY, a_ChunkZ, a_Callback); +} + + + + + +bool cWorld::GetChunkBlockTypes(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockTypes) +{ + return m_ChunkMap->GetChunkBlockTypes(a_ChunkX, a_ChunkY, a_ChunkZ, a_BlockTypes); +} + + + + + +bool cWorld::GetChunkBlockData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData) +{ + return m_ChunkMap->GetChunkBlockData(a_ChunkX, a_ChunkY, a_ChunkZ, a_BlockData); +} + + + + + +bool cWorld::IsChunkValid(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const +{ + return m_ChunkMap->IsChunkValid(a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +bool cWorld::HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const +{ + return m_ChunkMap->HasChunkAnyClients(a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +void cWorld::UnloadUnusedChunks(void ) +{ + m_LastUnload = m_Time; + m_ChunkMap->UnloadUnusedChunks(); +} + + + + + +void cWorld::CollectPickupsByPlayer(cPlayer * a_Player) +{ + m_ChunkMap->CollectPickupsByPlayer(a_Player); +} + + + + + +void cWorld::SetMaxPlayers(int iMax) +{ + m_MaxPlayers = MAX_PLAYERS; + if (iMax > 0 && iMax < MAX_PLAYERS) + { + m_MaxPlayers = iMax; + } +} + + + + + +void cWorld::AddPlayer( cPlayer* a_Player ) +{ + cCSLock Lock(m_CSPlayers); + + ASSERT(std::find(m_Players.begin(), m_Players.end(), a_Player) == m_Players.end()); // Is it already in the list? HOW? + + m_Players.remove( a_Player ); // Make sure the player is registered only once + m_Players.push_back( a_Player ); +} + + + + + +void cWorld::RemovePlayer( cPlayer* a_Player ) +{ + cCSLock Lock(m_CSPlayers); + m_Players.remove( a_Player ); +} + + + + + +bool cWorld::ForEachPlayer(cPlayerListCallback & a_Callback) +{ + // Calls the callback for each player in the list + cCSLock Lock(m_CSPlayers); + for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + if (a_Callback.Item(*itr)) + { + return false; + } + } // for itr - m_Players[] + return true; +} + + + + +// TODO: This interface is dangerous! +cPlayer* cWorld::GetPlayer( const char* a_PlayerName ) +{ + cPlayer* BestMatch = 0; + unsigned int MatchedLetters = 0; + unsigned int NumMatches = 0; + bool bPerfectMatch = false; + + unsigned int NameLength = strlen( a_PlayerName ); + cCSLock Lock(m_CSPlayers); + for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); itr++ ) + { + std::string Name = (*itr)->GetName(); + if( NameLength > Name.length() ) continue; // Definitely not a match + + for (unsigned int i = 0; i < NameLength; i++) + { + char c1 = (char)toupper( a_PlayerName[i] ); + char c2 = (char)toupper( Name[i] ); + if( c1 == c2 ) + { + if( i+1 > MatchedLetters ) + { + MatchedLetters = i+1; + BestMatch = *itr; + } + if( i+1 == NameLength ) + { + NumMatches++; + if( NameLength == Name.length() ) + { + bPerfectMatch = true; + break; + } + } + } + else + { + if( BestMatch == *itr ) BestMatch = 0; + break; + } + if( bPerfectMatch ) + break; + } + } + if ( NumMatches == 1 ) + { + return BestMatch; + } + + // More than one matches, so it's undefined. Return NULL instead + return NULL; +} + + + + + +cPlayer * cWorld::FindClosestPlayer(const Vector3f & a_Pos, float a_SightLimit) +{ + cTracer LineOfSight(this); + + float ClosestDistance = a_SightLimit; + cPlayer* ClosestPlayer = NULL; + + cCSLock Lock(m_CSPlayers); + for (cPlayerList::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + Vector3f Pos = (*itr)->GetPosition(); + float Distance = (Pos - a_Pos).Length(); + + if (Distance <= a_SightLimit) + { + if (!LineOfSight.Trace(a_Pos,(Pos - a_Pos),(int)(Pos - a_Pos).Length())) + { + if (Distance < ClosestDistance) + { + ClosestDistance = Distance; + ClosestPlayer = *itr; + } + } + } + } + return ClosestPlayer; +} + + + + + +void cWorld::SendPlayerList(cPlayer * a_DestPlayer) +{ + // Sends the playerlist to a_DestPlayer + cCSLock Lock(m_CSPlayers); + for ( cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + cClientHandle * ch = (*itr)->GetClientHandle(); + if ((ch != NULL) && !ch->IsDestroyed()) + { + cPacket_PlayerListItem PlayerListItem((*itr)->GetColor() + (*itr)->GetName(), true, (*itr)->GetClientHandle()->GetPing()); + a_DestPlayer->GetClientHandle()->Send( PlayerListItem ); + } + } +} + + + + + +bool cWorld::DoWithEntity( int a_UniqueID, cEntityCallback & a_Callback ) +{ + cCSLock Lock(m_CSEntities); + for (cEntityList::iterator itr = m_AllEntities.begin(); itr != m_AllEntities.end(); ++itr ) + { + if( (*itr)->GetUniqueID() == a_UniqueID ) + { + return a_Callback.Item(*itr); + } + } // for itr - m_AllEntities[] + return false; +} + + + + + +void cWorld::RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + m_ChunkMap->RemoveEntityFromChunk(a_Entity, a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +void cWorld::MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + m_ChunkMap->MoveEntityToChunk(a_Entity, a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +void cWorld::CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback) +{ + m_ChunkMap->CompareChunkClients(a_ChunkX1, a_ChunkY1, a_ChunkZ1, a_ChunkX2, a_ChunkY2, a_ChunkZ2, a_Callback); +} + + + + + +bool cWorld::AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) +{ + return m_ChunkMap->AddChunkClient(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client); +} + + + + + +void cWorld::RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) +{ + m_ChunkMap->RemoveChunkClient(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client); +} + + + + + +void cWorld::RemoveClientFromChunks(cClientHandle * a_Client) +{ + m_ChunkMap->RemoveClientFromChunks(a_Client); +} + + + + + +void cWorld::SendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) +{ + m_ChunkSender.QueueSendChunkTo(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client); +} + + + + + +void cWorld::RemoveClientFromChunkSender(cClientHandle * a_Client) +{ + m_ChunkSender.RemoveClient(a_Client); +} + + + + + +void cWorld::TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + m_ChunkMap->TouchChunk(a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +bool cWorld::LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + return m_ChunkMap->LoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +void cWorld::LoadChunks(const cChunkCoordsList & a_Chunks) +{ + m_ChunkMap->LoadChunks(a_Chunks); +} + + + + + +void cWorld::ChunkLoadFailed(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + m_ChunkMap->ChunkLoadFailed(a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +void cWorld::UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) +{ + m_ChunkMap->UpdateSign(a_X, a_Y, a_Z, a_Line1, a_Line2, a_Line3, a_Line4); +} + + + + + +void cWorld::ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay) +{ + m_ChunkMap->ChunksStay(a_Chunks, a_Stay); +} + + + + + +void cWorld::RegenerateChunk(int a_ChunkX, int a_ChunkZ) +{ + m_ChunkMap->MarkChunkRegenerating(a_ChunkX, a_ChunkZ); + + // Trick: use Y=1 to force the chunk generation even though the chunk data is already present + m_Generator.QueueGenerateChunk(a_ChunkX, 1, a_ChunkZ); +} + + + + + +void cWorld::GenerateChunk(int a_ChunkX, int a_ChunkZ) +{ + m_Generator.QueueGenerateChunk(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); +} + + + + + +void cWorld::QueueLightChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback) +{ + m_Lighting.QueueChunk(a_ChunkX, a_ChunkZ, a_Callback); +} + + + + + +bool cWorld::IsChunkLighted(int a_ChunkX, int a_ChunkZ) +{ + return m_ChunkMap->IsChunkLighted(a_ChunkX, a_ChunkZ); +} + + + + + +void cWorld::SaveAllChunks(void) +{ + LOG("Saving all chunks..."); + m_LastSave = m_Time; + m_ChunkMap->SaveAllChunks(); +} + + + + + +/************************************************************************/ +/* Get and set */ +/************************************************************************/ +// void cWorld::AddClient( cClientHandle* a_Client ) +// { +// m_m_Clients.push_back( a_Client ); +// } +// cWorld::ClientList & cWorld::GetClients() +// { +// return m_m_Clients; +// } + + + + + +void cWorld::AddEntity( cEntity* a_Entity ) +{ + cCSLock Lock(m_CSEntities); + m_AllEntities.push_back( a_Entity ); +} + + + + + +unsigned int cWorld::GetNumPlayers() +{ + cCSLock Lock(m_CSPlayers); + return m_Players.size(); +} + + + + + +int cWorld::GetNumChunks(void) const +{ + return m_ChunkMap->GetNumChunks(); +} + + + + + +void cWorld::GetChunkStats(int & a_NumValid, int & a_NumDirty, int & a_NumInLightingQueue) +{ + m_ChunkMap->GetChunkStats(a_NumValid, a_NumDirty); + a_NumInLightingQueue = (int) m_Lighting.GetQueueLength(); +} + + + + diff --git a/source/cWorld.h b/source/cWorld.h index 7c4e8b654..e557a56ed 100644 --- a/source/cWorld.h +++ b/source/cWorld.h @@ -1,408 +1,408 @@ - -#pragma once - -#ifndef _WIN32 - #include "BlockID.h" -#else - enum ENUM_ITEM_ID; -#endif - -#define MAX_PLAYERS 65535 - -#include "cSimulatorManager.h" -#include "MersenneTwister.h" -#include "cChunkMap.h" -#include "WorldStorage.h" -#include "cChunkGenerator.h" -#include "Vector3i.h" -#include "Vector3f.h" -#include "ChunkSender.h" -#include "Defines.h" -#include "LightingThread.h" -#include "cItem.h" - - - - - -class cPacket; -class cRedstone; -class cFireSimulator; -class cWaterSimulator; -class cLavaSimulator; -class cSandSimulator; -class cRedstoneSimulator; -class cItem; -class cPlayer; -class cClientHandle; -class cEntity; -class cBlockEntity; -class cWorldGenerator; // The generator that actually generates the chunks for a single world -class cChunkGenerator; // The thread responsible for generating chunks -typedef std::list< cPlayer * > cPlayerList; -typedef cItemCallback cPlayerListCallback; -typedef cItemCallback cEntityCallback; - - - - - -class cWorld //tolua_export -{ //tolua_export -public: - - OBSOLETE static cWorld* GetWorld(); - - // Return time in seconds - inline static float GetTime() //tolua_export - { - return m_Time; - } - long long GetWorldTime(void) const { return m_WorldTime; } //tolua_export - - eGameMode GetGameMode(void) const { return m_GameMode; } //tolua_export - - void SetWorldTime(long long a_WorldTime) { m_WorldTime = a_WorldTime; } //tolua_export - - int GetHeight( int a_X, int a_Z ); //tolua_export - - void Broadcast( const cPacket & a_Packet, cClientHandle* a_Exclude = 0 ); - void BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude = NULL); - void BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, cPacket * a_Packet, cClientHandle * a_Exclude = NULL); - - void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ); - void MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ); - void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ); - - /** Sets the chunk data as either loaded from the storage or generated. - a_BlockLight and a_BlockSkyLight are optional, if not present, chunk will be marked as unlighted. - a_BiomeMap is optional, if not present, biomes will be calculated by the generator - a_HeightMap is optional, if not present, will be calculated. - If a_MarkDirty is set, the chunk is set as dirty (used after generating) - */ - void SetChunkData( - int a_ChunkX, int a_ChunkY, int a_ChunkZ, - const BLOCKTYPE * a_BlockTypes, - const NIBBLETYPE * a_BlockMeta, - const NIBBLETYPE * a_BlockLight, - const NIBBLETYPE * a_BlockSkyLight, - const cChunkDef::HeightMap * a_HeightMap, - const cChunkDef::BiomeMap * a_BiomeMap, - cEntityList & a_Entities, - cBlockEntityList & a_BlockEntities, - bool a_MarkDirty - ); - - void ChunkLighted( - int a_ChunkX, int a_ChunkZ, - const cChunkDef::BlockNibbles & a_BlockLight, - const cChunkDef::BlockNibbles & a_SkyLight - ); - - bool GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback); - - /// Gets the chunk's blocks, only the block types - bool GetChunkBlockTypes(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockTypes); - - /// Gets the chunk's blockdata, the entire 4 arrays (Types, Meta, Light, SkyLight) - bool GetChunkBlockData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData); - - bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ) const; - bool HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const; - - void UnloadUnusedChunks(void); // tolua_export - - void CollectPickupsByPlayer(cPlayer * a_Player); - - // MOTD - const AString & GetDescription(void) const {return m_Description; } // FIXME: This should not be in cWorld - - // Max Players - unsigned int GetMaxPlayers(void) const {return m_MaxPlayers; } //tolua_export - void SetMaxPlayers(int iMax); //tolua_export - - void AddPlayer( cPlayer* a_Player ); - void RemovePlayer( cPlayer* a_Player ); - - bool ForEachPlayer(cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << - - unsigned int GetNumPlayers(); //tolua_export - - // TODO: This interface is dangerous - rewrite to DoWithPlayer(playername, action) - cPlayer * GetPlayer( const char * a_PlayerName ); //tolua_export - - // TODO: This interface is dangerous - rewrite to DoWithClosestPlayer(pos, sight, action) - cPlayer * FindClosestPlayer(const Vector3f & a_Pos, float a_SightLimit); - - void SendPlayerList(cPlayer * a_DestPlayer); // Sends playerlist to the player - - void AddEntity( cEntity* a_Entity ); - - /// Add an entity to the chunk specified; broadcasts the a_SpawnPacket to all clients of that chunk - void AddEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ, cPacket * a_SpawnPacket); - - /// Removes the entity from the chunk specified - void RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ); - - /// Moves the entity from its current chunk to the new chunk specified - void MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ); - - /// Compares clients of two chunks, calls the callback accordingly - void CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback); - - /// Adds client to a chunk, if not already present; returns true if added, false if present - bool AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); - - /// Removes client from the chunk specified - void RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); - - /// Removes the client from all chunks it is present in - void RemoveClientFromChunks(cClientHandle * a_Client); - - /// Sends the chunk to the client specified, if the chunk is valid. If not valid, the request is postponed (ChunkSender will send that chunk when it becomes valid+lighted) - void SendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); - - /// Removes client from ChunkSender's queue of chunks to be sent - void RemoveClientFromChunkSender(cClientHandle * a_Client); - - /// Touches the chunk, causing it to be loaded or generated - void TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); - - /// Loads the chunk, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before) - bool LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); - - /// Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid() - void LoadChunks(const cChunkCoordsList & a_Chunks); - - /// Marks the chunk as failed-to-load: - void ChunkLoadFailed(int a_ChunkX, int a_ChunkY, int a_ChunkZ); - - void UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); //tolua_export - - /// Marks (a_Stay == true) or unmarks (a_Stay == false) chunks as non-unloadable. To be used only by cChunkStay! - void ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay = true); - - /// Regenerate the given chunk: - void RegenerateChunk(int a_ChunkX, int a_ChunkZ); //tolua_export - - /// Generates the given chunk, if not already generated - void GenerateChunk(int a_ChunkX, int a_ChunkZ); //tolua_export - - /// Queues a chunk for lighting; a_Callback is called after the chunk is lighted - void QueueLightChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback = NULL); - - bool IsChunkLighted(int a_ChunkX, int a_ChunkZ); - - // TODO: Export to Lua - bool DoWithEntity( int a_UniqueID, cEntityCallback & a_Callback ); - - void SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ); //tolua_export - void FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ); //tolua_export - char GetBlock( int a_X, int a_Y, int a_Z ); //tolua_export - char GetBlock( const Vector3i & a_Pos ) { return GetBlock( a_Pos.x, a_Pos.y, a_Pos.z ); } //tolua_export - char GetBlockMeta( int a_X, int a_Y, int a_Z ); //tolua_export - char GetBlockMeta( const Vector3i & a_Pos ) { return GetBlockMeta( a_Pos.x, a_Pos.y, a_Pos.z ); } //tolua_export - void SetBlockMeta( int a_X, int a_Y, int a_Z, char a_MetaData ); //tolua_export - void SetBlockMeta( const Vector3i & a_Pos, char a_MetaData ) { SetBlockMeta( a_Pos.x, a_Pos.y, a_Pos.z, a_MetaData ); } //tolua_export - char GetBlockSkyLight( int a_X, int a_Y, int a_Z ); //tolua_export - // TODO: char GetBlockActualLight(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export - void GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, char & a_BlockType, unsigned char & a_BlockMeta); // tolua_export - - /// Spawns item pickups for each item in the list. May compress pickups if too many entities: - void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_FlyAwaySpeed = 1.0); - - /// Spawns item pickups for each item in the list. May compress pickups if too many entities. All pickups get the speed specified: - void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ); - - /// Replaces world blocks with a_Blocks, if they are of type a_FilterBlockType - void ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType); - - /// Retrieves block types of the specified blocks. If a chunk is not loaded, doesn't modify the block. Returns true if all blocks were read. - bool GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure); - - bool DigBlock (int a_X, int a_Y, int a_Z); //tolua_export - void SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player ); //tolua_export - - const double & GetSpawnX() { return m_SpawnX; } //tolua_export - const double & GetSpawnY(); //tolua_export - const double & GetSpawnZ() { return m_SpawnZ; } //tolua_export - - inline cSimulatorManager *GetSimulatorManager() { return m_SimulatorManager; } - inline cWaterSimulator *GetWaterSimulator() { return m_WaterSimulator; } - inline cLavaSimulator *GetLavaSimulator() { return m_LavaSimulator; } - - // TODO: This interface is dangerous! Export as a set of specific action functions for Lua: GetChestItem, GetFurnaceItem, SetFurnaceItem, SetSignLines etc. - // _X 2012_02_21: This function always returns NULL - OBSOLETE cBlockEntity * GetBlockEntity( int a_X, int a_Y, int a_Z ); //tolua_export - - /// a_Player is using block entity at [x, y, z], handle that: - void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z) {m_ChunkMap->UseBlockEntity(a_Player, a_X, a_Y, a_Z); } - - void GrowTree (int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export - void GrowTreeFromSapling(int a_BlockX, int a_BlockY, int a_BlockZ, char a_SaplingMeta); // tolua_export - void GrowTreeByBiome (int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export - - void GrowTreeImage(const sSetBlockVector & a_Blocks); - - /// Grows the plant at the specified block to its ripe stage (bonemeal used); returns false if the block is not growable. If a_IsBonemeal is true, block is not grown if not allowed in world.ini - bool GrowPlant(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_IsByBonemeal = false); // tolua_export - - /// Grows a melon or a pumpkin next to the block specified (assumed to be the stem) - void GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockType); // tolua_export - - int GetBiomeAt (int a_BlockX, int a_BlockZ); // tolua_export - - const AString & GetName(void) const { return m_WorldName; } //tolua_export - const AString & GetIniFileName(void) const {return m_IniFileName; } - - inline static void AbsoluteToRelative( int & a_X, int & a_Y, int & a_Z, int & a_ChunkX, int & a_ChunkY, int & a_ChunkZ ) - { - // TODO: Use floor() instead of weird if statements - // Also fix Y - a_ChunkX = a_X/cChunkDef::Width; - if(a_X < 0 && a_X % cChunkDef::Width != 0) a_ChunkX--; - a_ChunkY = 0; - a_ChunkZ = a_Z/cChunkDef::Width; - if(a_Z < 0 && a_Z % cChunkDef::Width != 0) a_ChunkZ--; - - a_X = a_X - a_ChunkX*cChunkDef::Width; - a_Y = a_Y - a_ChunkY*cChunkDef::Height; - a_Z = a_Z - a_ChunkZ*cChunkDef::Width; - } - - inline static void BlockToChunk( int a_X, int a_Y, int a_Z, int & a_ChunkX, int & a_ChunkY, int & a_ChunkZ ) - { - // TODO: Use floor() instead of weird if statements - // Also fix Y - (void)a_Y; // not unused anymore - a_ChunkX = a_X/cChunkDef::Width; - if(a_X < 0 && a_X % cChunkDef::Width != 0) a_ChunkX--; - a_ChunkY = 0; - a_ChunkZ = a_Z/cChunkDef::Width; - if(a_Z < 0 && a_Z % cChunkDef::Width != 0) a_ChunkZ--; - } - - void SaveAllChunks(void); //tolua_export - - /// Returns the number of chunks loaded - int GetNumChunks() const; //tolua_export - - /// Returns the number of chunks loaded and dirty, and in the lighting queue - void GetChunkStats(int & a_NumValid, int & a_NumDirty, int & a_NumInLightingQueue); - - // Various queues length queries (cannot be const, they lock their CS): - inline int GetGeneratorQueueLength (void) { return m_Generator.GetQueueLength(); } // tolua_export - inline int GetLightingQueueLength (void) { return m_Lighting.GetQueueLength(); } // tolua_export - inline int GetStorageLoadQueueLength(void) { return m_Storage.GetLoadQueueLength(); } // tolua_export - inline int GetStorageSaveQueueLength(void) { return m_Storage.GetSaveQueueLength(); } // tolua_export - - void Tick(float a_Dt); - - void InitializeSpawn(); - - void CastThunderbolt (int a_X, int a_Y, int a_Z); //tolua_export - void SetWeather ( eWeather a_Weather ); //tolua_export - void ChangeWeather(); //tolua_export - eWeather GetWeather() { return m_Weather; }; //tolua_export - - cChunkGenerator & GetGenerator(void) { return m_Generator; } - cWorldStorage & GetStorage (void) { return m_Storage; } - cChunkMap * GetChunkMap (void) { return m_ChunkMap; } - - bool IsPlacingItemLegal(Int16 a_ItemType, int a_BlockX, int a_BlockY, int a_BlockZ); - - /// Sets the blockticking to start at the specified block. Only one blocktick per chunk may be set, second call overwrites the first call - void SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export - - int GetMaxSugarcaneHeight(void) const { return m_MaxSugarcaneHeight; } // tolua_export - int GetMaxCactusHeight (void) const { return m_MaxCactusHeight; } // tolua_export - -private: - - friend class cRoot; - - // This random generator is to be used only in the Tick() method, and thus only in the World-Tick-thread (MTRand is not exactly thread-safe) - MTRand m_TickRand; - - double m_SpawnX; - double m_SpawnY; - double m_SpawnZ; - - float m_LastUnload; - float m_LastSave; - static float m_Time; // Time in seconds - long long m_WorldTime; // Time in seconds*20, this is sent to clients (is wrapped) - unsigned long long CurrentTick; - eGameMode m_GameMode; - float m_WorldTimeFraction; // When this > 1.f m_WorldTime is incremented by 20 - - // The cRedstone class simulates redstone and needs access to m_RSList - friend class cRedstone; - std::vector m_RSList; - - cSimulatorManager * m_SimulatorManager; - cSandSimulator * m_SandSimulator; - cWaterSimulator * m_WaterSimulator; - cLavaSimulator * m_LavaSimulator; - cFireSimulator * m_FireSimulator; - cRedstoneSimulator * m_RedstoneSimulator; - - cCriticalSection m_CSClients; - cCriticalSection m_CSEntities; - cCriticalSection m_CSPlayers; - - cWorldStorage m_Storage; - - AString m_Description; - - unsigned int m_MaxPlayers; - - cChunkMap * m_ChunkMap; - - bool m_bAnimals; - float m_SpawnMonsterTime; - float m_SpawnMonsterRate; - - eWeather m_Weather; - int m_WeatherInterval; - - int m_MaxCactusHeight; - int m_MaxSugarcaneHeight; - bool m_IsCropsBonemealable; - bool m_IsGrassBonemealable; - bool m_IsSaplingBonemealable; - bool m_IsMelonStemBonemealable; - bool m_IsMelonBonemealable; - bool m_IsPumpkinStemBonemealable; - bool m_IsPumpkinBonemealable; - bool m_IsSugarcaneBonemealable; - bool m_IsCactusBonemealable; - - cEntityList m_RemoveEntityQueue; - cEntityList m_AllEntities; - cClientHandleList m_Clients; - cPlayerList m_Players; - - cCriticalSection m_CSFastSetBlock; - sSetBlockList m_FastSetBlockQueue; - - cChunkGenerator m_Generator; - - cChunkSender m_ChunkSender; - cLightingThread m_Lighting; - - AString m_WorldName; - AString m_IniFileName; - - cWorld(const AString & a_WorldName); - ~cWorld(); - - void TickWeather(float a_Dt); // Handles weather each tick - void TickSpawnMobs(float a_Dt); // Handles mob spawning each tick - - void RemoveEntity( cEntity * a_Entity ); -}; //tolua_export - - - - + +#pragma once + +#ifndef _WIN32 + #include "BlockID.h" +#else + enum ENUM_ITEM_ID; +#endif + +#define MAX_PLAYERS 65535 + +#include "cSimulatorManager.h" +#include "MersenneTwister.h" +#include "cChunkMap.h" +#include "WorldStorage.h" +#include "cChunkGenerator.h" +#include "Vector3i.h" +#include "Vector3f.h" +#include "ChunkSender.h" +#include "Defines.h" +#include "LightingThread.h" +#include "cItem.h" + + + + + +class cPacket; +class cRedstone; +class cFireSimulator; +class cWaterSimulator; +class cLavaSimulator; +class cSandSimulator; +class cRedstoneSimulator; +class cItem; +class cPlayer; +class cClientHandle; +class cEntity; +class cBlockEntity; +class cWorldGenerator; // The generator that actually generates the chunks for a single world +class cChunkGenerator; // The thread responsible for generating chunks +typedef std::list< cPlayer * > cPlayerList; +typedef cItemCallback cPlayerListCallback; +typedef cItemCallback cEntityCallback; + + + + + +class cWorld //tolua_export +{ //tolua_export +public: + + OBSOLETE static cWorld* GetWorld(); + + // Return time in seconds + inline static float GetTime() //tolua_export + { + return m_Time; + } + long long GetWorldTime(void) const { return m_WorldTime; } //tolua_export + + eGameMode GetGameMode(void) const { return m_GameMode; } //tolua_export + + void SetWorldTime(long long a_WorldTime) { m_WorldTime = a_WorldTime; } //tolua_export + + int GetHeight( int a_X, int a_Z ); //tolua_export + + void Broadcast( const cPacket & a_Packet, cClientHandle* a_Exclude = 0 ); + void BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude = NULL); + void BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, cPacket * a_Packet, cClientHandle * a_Exclude = NULL); + + void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ); + void MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /** Sets the chunk data as either loaded from the storage or generated. + a_BlockLight and a_BlockSkyLight are optional, if not present, chunk will be marked as unlighted. + a_BiomeMap is optional, if not present, biomes will be calculated by the generator + a_HeightMap is optional, if not present, will be calculated. + If a_MarkDirty is set, the chunk is set as dirty (used after generating) + */ + void SetChunkData( + int a_ChunkX, int a_ChunkY, int a_ChunkZ, + const BLOCKTYPE * a_BlockTypes, + const NIBBLETYPE * a_BlockMeta, + const NIBBLETYPE * a_BlockLight, + const NIBBLETYPE * a_BlockSkyLight, + const cChunkDef::HeightMap * a_HeightMap, + const cChunkDef::BiomeMap * a_BiomeMap, + cEntityList & a_Entities, + cBlockEntityList & a_BlockEntities, + bool a_MarkDirty + ); + + void ChunkLighted( + int a_ChunkX, int a_ChunkZ, + const cChunkDef::BlockNibbles & a_BlockLight, + const cChunkDef::BlockNibbles & a_SkyLight + ); + + bool GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback); + + /// Gets the chunk's blocks, only the block types + bool GetChunkBlockTypes(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockTypes); + + /// Gets the chunk's blockdata, the entire 4 arrays (Types, Meta, Light, SkyLight) + bool GetChunkBlockData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData); + + bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ) const; + bool HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const; + + void UnloadUnusedChunks(void); // tolua_export + + void CollectPickupsByPlayer(cPlayer * a_Player); + + // MOTD + const AString & GetDescription(void) const {return m_Description; } // FIXME: This should not be in cWorld + + // Max Players + unsigned int GetMaxPlayers(void) const {return m_MaxPlayers; } //tolua_export + void SetMaxPlayers(int iMax); //tolua_export + + void AddPlayer( cPlayer* a_Player ); + void RemovePlayer( cPlayer* a_Player ); + + bool ForEachPlayer(cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << + + unsigned int GetNumPlayers(); //tolua_export + + // TODO: This interface is dangerous - rewrite to DoWithPlayer(playername, action) + cPlayer * GetPlayer( const char * a_PlayerName ); //tolua_export + + // TODO: This interface is dangerous - rewrite to DoWithClosestPlayer(pos, sight, action) + cPlayer * FindClosestPlayer(const Vector3f & a_Pos, float a_SightLimit); + + void SendPlayerList(cPlayer * a_DestPlayer); // Sends playerlist to the player + + void AddEntity( cEntity* a_Entity ); + + /// Add an entity to the chunk specified; broadcasts the a_SpawnPacket to all clients of that chunk + void AddEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ, cPacket * a_SpawnPacket); + + /// Removes the entity from the chunk specified + void RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Moves the entity from its current chunk to the new chunk specified + void MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Compares clients of two chunks, calls the callback accordingly + void CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback); + + /// Adds client to a chunk, if not already present; returns true if added, false if present + bool AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); + + /// Removes client from the chunk specified + void RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); + + /// Removes the client from all chunks it is present in + void RemoveClientFromChunks(cClientHandle * a_Client); + + /// Sends the chunk to the client specified, if the chunk is valid. If not valid, the request is postponed (ChunkSender will send that chunk when it becomes valid+lighted) + void SendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); + + /// Removes client from ChunkSender's queue of chunks to be sent + void RemoveClientFromChunkSender(cClientHandle * a_Client); + + /// Touches the chunk, causing it to be loaded or generated + void TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Loads the chunk, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before) + bool LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid() + void LoadChunks(const cChunkCoordsList & a_Chunks); + + /// Marks the chunk as failed-to-load: + void ChunkLoadFailed(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + void UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); //tolua_export + + /// Marks (a_Stay == true) or unmarks (a_Stay == false) chunks as non-unloadable. To be used only by cChunkStay! + void ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay = true); + + /// Regenerate the given chunk: + void RegenerateChunk(int a_ChunkX, int a_ChunkZ); //tolua_export + + /// Generates the given chunk, if not already generated + void GenerateChunk(int a_ChunkX, int a_ChunkZ); //tolua_export + + /// Queues a chunk for lighting; a_Callback is called after the chunk is lighted + void QueueLightChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback = NULL); + + bool IsChunkLighted(int a_ChunkX, int a_ChunkZ); + + // TODO: Export to Lua + bool DoWithEntity( int a_UniqueID, cEntityCallback & a_Callback ); + + void SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ); //tolua_export + void FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ); //tolua_export + char GetBlock( int a_X, int a_Y, int a_Z ); //tolua_export + char GetBlock( const Vector3i & a_Pos ) { return GetBlock( a_Pos.x, a_Pos.y, a_Pos.z ); } //tolua_export + char GetBlockMeta( int a_X, int a_Y, int a_Z ); //tolua_export + char GetBlockMeta( const Vector3i & a_Pos ) { return GetBlockMeta( a_Pos.x, a_Pos.y, a_Pos.z ); } //tolua_export + void SetBlockMeta( int a_X, int a_Y, int a_Z, char a_MetaData ); //tolua_export + void SetBlockMeta( const Vector3i & a_Pos, char a_MetaData ) { SetBlockMeta( a_Pos.x, a_Pos.y, a_Pos.z, a_MetaData ); } //tolua_export + char GetBlockSkyLight( int a_X, int a_Y, int a_Z ); //tolua_export + // TODO: char GetBlockActualLight(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export + void GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, char & a_BlockType, unsigned char & a_BlockMeta); // tolua_export + + /// Spawns item pickups for each item in the list. May compress pickups if too many entities: + void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_FlyAwaySpeed = 1.0); + + /// Spawns item pickups for each item in the list. May compress pickups if too many entities. All pickups get the speed specified: + void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ); + + /// Replaces world blocks with a_Blocks, if they are of type a_FilterBlockType + void ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType); + + /// Retrieves block types of the specified blocks. If a chunk is not loaded, doesn't modify the block. Returns true if all blocks were read. + bool GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure); + + bool DigBlock (int a_X, int a_Y, int a_Z); //tolua_export + void SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player ); //tolua_export + + const double & GetSpawnX() { return m_SpawnX; } //tolua_export + const double & GetSpawnY(); //tolua_export + const double & GetSpawnZ() { return m_SpawnZ; } //tolua_export + + inline cSimulatorManager *GetSimulatorManager() { return m_SimulatorManager; } + inline cWaterSimulator *GetWaterSimulator() { return m_WaterSimulator; } + inline cLavaSimulator *GetLavaSimulator() { return m_LavaSimulator; } + + // TODO: This interface is dangerous! Export as a set of specific action functions for Lua: GetChestItem, GetFurnaceItem, SetFurnaceItem, SetSignLines etc. + // _X 2012_02_21: This function always returns NULL + OBSOLETE cBlockEntity * GetBlockEntity( int a_X, int a_Y, int a_Z ); //tolua_export + + /// a_Player is using block entity at [x, y, z], handle that: + void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z) {m_ChunkMap->UseBlockEntity(a_Player, a_X, a_Y, a_Z); } + + void GrowTree (int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export + void GrowTreeFromSapling(int a_BlockX, int a_BlockY, int a_BlockZ, char a_SaplingMeta); // tolua_export + void GrowTreeByBiome (int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export + + void GrowTreeImage(const sSetBlockVector & a_Blocks); + + /// Grows the plant at the specified block to its ripe stage (bonemeal used); returns false if the block is not growable. If a_IsBonemeal is true, block is not grown if not allowed in world.ini + bool GrowPlant(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_IsByBonemeal = false); // tolua_export + + /// Grows a melon or a pumpkin next to the block specified (assumed to be the stem) + void GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockType); // tolua_export + + int GetBiomeAt (int a_BlockX, int a_BlockZ); // tolua_export + + const AString & GetName(void) const { return m_WorldName; } //tolua_export + const AString & GetIniFileName(void) const {return m_IniFileName; } + + inline static void AbsoluteToRelative( int & a_X, int & a_Y, int & a_Z, int & a_ChunkX, int & a_ChunkY, int & a_ChunkZ ) + { + // TODO: Use floor() instead of weird if statements + // Also fix Y + a_ChunkX = a_X/cChunkDef::Width; + if(a_X < 0 && a_X % cChunkDef::Width != 0) a_ChunkX--; + a_ChunkY = 0; + a_ChunkZ = a_Z/cChunkDef::Width; + if(a_Z < 0 && a_Z % cChunkDef::Width != 0) a_ChunkZ--; + + a_X = a_X - a_ChunkX*cChunkDef::Width; + a_Y = a_Y - a_ChunkY*cChunkDef::Height; + a_Z = a_Z - a_ChunkZ*cChunkDef::Width; + } + + inline static void BlockToChunk( int a_X, int a_Y, int a_Z, int & a_ChunkX, int & a_ChunkY, int & a_ChunkZ ) + { + // TODO: Use floor() instead of weird if statements + // Also fix Y + (void)a_Y; // not unused anymore + a_ChunkX = a_X/cChunkDef::Width; + if(a_X < 0 && a_X % cChunkDef::Width != 0) a_ChunkX--; + a_ChunkY = 0; + a_ChunkZ = a_Z/cChunkDef::Width; + if(a_Z < 0 && a_Z % cChunkDef::Width != 0) a_ChunkZ--; + } + + void SaveAllChunks(void); //tolua_export + + /// Returns the number of chunks loaded + int GetNumChunks() const; //tolua_export + + /// Returns the number of chunks loaded and dirty, and in the lighting queue + void GetChunkStats(int & a_NumValid, int & a_NumDirty, int & a_NumInLightingQueue); + + // Various queues length queries (cannot be const, they lock their CS): + inline int GetGeneratorQueueLength (void) { return m_Generator.GetQueueLength(); } // tolua_export + inline int GetLightingQueueLength (void) { return m_Lighting.GetQueueLength(); } // tolua_export + inline int GetStorageLoadQueueLength(void) { return m_Storage.GetLoadQueueLength(); } // tolua_export + inline int GetStorageSaveQueueLength(void) { return m_Storage.GetSaveQueueLength(); } // tolua_export + + void Tick(float a_Dt); + + void InitializeSpawn(); + + void CastThunderbolt (int a_X, int a_Y, int a_Z); //tolua_export + void SetWeather ( eWeather a_Weather ); //tolua_export + void ChangeWeather(); //tolua_export + eWeather GetWeather() { return m_Weather; }; //tolua_export + + cChunkGenerator & GetGenerator(void) { return m_Generator; } + cWorldStorage & GetStorage (void) { return m_Storage; } + cChunkMap * GetChunkMap (void) { return m_ChunkMap; } + + bool IsPlacingItemLegal(Int16 a_ItemType, int a_BlockX, int a_BlockY, int a_BlockZ); + + /// Sets the blockticking to start at the specified block. Only one blocktick per chunk may be set, second call overwrites the first call + void SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export + + int GetMaxSugarcaneHeight(void) const { return m_MaxSugarcaneHeight; } // tolua_export + int GetMaxCactusHeight (void) const { return m_MaxCactusHeight; } // tolua_export + +private: + + friend class cRoot; + + // This random generator is to be used only in the Tick() method, and thus only in the World-Tick-thread (MTRand is not exactly thread-safe) + MTRand m_TickRand; + + double m_SpawnX; + double m_SpawnY; + double m_SpawnZ; + + float m_LastUnload; + float m_LastSave; + static float m_Time; // Time in seconds + long long m_WorldTime; // Time in seconds*20, this is sent to clients (is wrapped) + unsigned long long CurrentTick; + eGameMode m_GameMode; + float m_WorldTimeFraction; // When this > 1.f m_WorldTime is incremented by 20 + + // The cRedstone class simulates redstone and needs access to m_RSList + friend class cRedstone; + std::vector m_RSList; + + cSimulatorManager * m_SimulatorManager; + cSandSimulator * m_SandSimulator; + cWaterSimulator * m_WaterSimulator; + cLavaSimulator * m_LavaSimulator; + cFireSimulator * m_FireSimulator; + cRedstoneSimulator * m_RedstoneSimulator; + + cCriticalSection m_CSClients; + cCriticalSection m_CSEntities; + cCriticalSection m_CSPlayers; + + cWorldStorage m_Storage; + + AString m_Description; + + unsigned int m_MaxPlayers; + + cChunkMap * m_ChunkMap; + + bool m_bAnimals; + float m_SpawnMonsterTime; + float m_SpawnMonsterRate; + + eWeather m_Weather; + int m_WeatherInterval; + + int m_MaxCactusHeight; + int m_MaxSugarcaneHeight; + bool m_IsCropsBonemealable; + bool m_IsGrassBonemealable; + bool m_IsSaplingBonemealable; + bool m_IsMelonStemBonemealable; + bool m_IsMelonBonemealable; + bool m_IsPumpkinStemBonemealable; + bool m_IsPumpkinBonemealable; + bool m_IsSugarcaneBonemealable; + bool m_IsCactusBonemealable; + + cEntityList m_RemoveEntityQueue; + cEntityList m_AllEntities; + cClientHandleList m_Clients; + cPlayerList m_Players; + + cCriticalSection m_CSFastSetBlock; + sSetBlockList m_FastSetBlockQueue; + + cChunkGenerator m_Generator; + + cChunkSender m_ChunkSender; + cLightingThread m_Lighting; + + AString m_WorldName; + AString m_IniFileName; + + cWorld(const AString & a_WorldName); + ~cWorld(); + + void TickWeather(float a_Dt); // Handles weather each tick + void TickSpawnMobs(float a_Dt); // Handles mob spawning each tick + + void RemoveEntity( cEntity * a_Entity ); +}; //tolua_export + + + + diff --git a/source/cZombie.cpp b/source/cZombie.cpp index b8f9553d2..94c1d669b 100644 --- a/source/cZombie.cpp +++ b/source/cZombie.cpp @@ -1,66 +1,66 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cZombie.h" - - - - - -cZombie::cZombie() -{ - m_MobType = 54; - GetMonsterConfig("Zombie"); -} - - - - - -cZombie::~cZombie() -{ -} - - - - - -bool cZombie::IsA( const char* a_EntityType ) -{ - if( strcmp( a_EntityType, "cZombie" ) == 0 ) return true; - return cMonster::IsA( a_EntityType ); -} - - - - - -void cZombie::Tick(float a_Dt) -{ - cMonster::Tick(a_Dt); - - //TODO Same as in cSkeleton :D - if (GetWorld()->GetWorldTime() < (12000 + 1000) && GetMetaData() != BURNING) { //if daylight - SetMetaData(BURNING); // BURN, BABY, BURN! >:D - } -} - - - - - -void cZombie::KilledBy( cEntity* a_Killer ) -{ - cItems Drops; - AddRandomDropItem(Drops, 0, 2, E_ITEM_ROTTEN_FLESH); - - // TODO: Rare drops - - m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); - - cMonster::KilledBy( a_Killer ); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cZombie.h" + + + + + +cZombie::cZombie() +{ + m_MobType = 54; + GetMonsterConfig("Zombie"); +} + + + + + +cZombie::~cZombie() +{ +} + + + + + +bool cZombie::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cZombie" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cZombie::Tick(float a_Dt) +{ + cMonster::Tick(a_Dt); + + //TODO Same as in cSkeleton :D + if (GetWorld()->GetWorldTime() < (12000 + 1000) && GetMetaData() != BURNING) { //if daylight + SetMetaData(BURNING); // BURN, BABY, BURN! >:D + } +} + + + + + +void cZombie::KilledBy( cEntity* a_Killer ) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_ROTTEN_FLESH); + + // TODO: Rare drops + + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cZombie.h b/source/cZombie.h index b35ff8933..4d6e39fb0 100644 --- a/source/cZombie.h +++ b/source/cZombie.h @@ -1,15 +1,15 @@ -#pragma once - -#include "cAggressiveMonster.h" - -class cZombie : public cAggressiveMonster -{ -public: - cZombie(); - ~cZombie(); - - virtual bool IsA( const char* a_EntityType ); - - virtual void Tick(float a_Dt); - virtual void KilledBy( cEntity* a_Killer ); -}; +#pragma once + +#include "cAggressiveMonster.h" + +class cZombie : public cAggressiveMonster +{ +public: + cZombie(); + ~cZombie(); + + virtual bool IsA( const char* a_EntityType ); + + virtual void Tick(float a_Dt); + virtual void KilledBy( cEntity* a_Killer ); +}; diff --git a/source/cZombiepigman.cpp b/source/cZombiepigman.cpp index 024c0bd62..5aefbae72 100644 --- a/source/cZombiepigman.cpp +++ b/source/cZombiepigman.cpp @@ -1,67 +1,67 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cZombiepigman.h" - - - - - -cZombiepigman::cZombiepigman() -{ - m_MobType = 57; - GetMonsterConfig("Zombiepigman"); -} - - - - - -cZombiepigman::~cZombiepigman() -{ -} - - - - - -bool cZombiepigman::IsA( const char* a_EntityType ) -{ - if( strcmp( a_EntityType, "cZombiepigman" ) == 0 ) return true; - return cMonster::IsA( a_EntityType ); -} - - - - - -void cZombiepigman::Tick(float a_Dt) -{ - cMonster::Tick(a_Dt); - - //TODO Same as noticed in cSkeleton AND Do they really burn by sun?? :D In the neather is no sun :D - if (GetWorld()->GetWorldTime() < (12000 + 1000) && GetMetaData() != BURNING ) { //if daylight - SetMetaData(BURNING); // BURN, BABY, BURN! >:D - } -} - - - - - -void cZombiepigman::KilledBy(cEntity * a_Killer) -{ - cItems Drops; - AddRandomDropItem(Drops, 0, 1, E_ITEM_ROTTEN_FLESH); - AddRandomDropItem(Drops, 0, 1, E_ITEM_GOLD_NUGGET); - - // TODO: Rare drops - - m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); - - cMonster::KilledBy( a_Killer ); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cZombiepigman.h" + + + + + +cZombiepigman::cZombiepigman() +{ + m_MobType = 57; + GetMonsterConfig("Zombiepigman"); +} + + + + + +cZombiepigman::~cZombiepigman() +{ +} + + + + + +bool cZombiepigman::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cZombiepigman" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cZombiepigman::Tick(float a_Dt) +{ + cMonster::Tick(a_Dt); + + //TODO Same as noticed in cSkeleton AND Do they really burn by sun?? :D In the neather is no sun :D + if (GetWorld()->GetWorldTime() < (12000 + 1000) && GetMetaData() != BURNING ) { //if daylight + SetMetaData(BURNING); // BURN, BABY, BURN! >:D + } +} + + + + + +void cZombiepigman::KilledBy(cEntity * a_Killer) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 1, E_ITEM_ROTTEN_FLESH); + AddRandomDropItem(Drops, 0, 1, E_ITEM_GOLD_NUGGET); + + // TODO: Rare drops + + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cZombiepigman.h b/source/cZombiepigman.h index 1a102572b..76fb34e4b 100644 --- a/source/cZombiepigman.h +++ b/source/cZombiepigman.h @@ -1,15 +1,15 @@ -#pragma once - -#include "cPassiveAggressiveMonster.h" - -class cZombiepigman : public cPassiveAggressiveMonster -{ -public: - cZombiepigman(); - ~cZombiepigman(); - - virtual bool IsA( const char* a_EntityType ); - - virtual void Tick(float a_Dt); - virtual void KilledBy( cEntity* a_Killer ); -}; +#pragma once + +#include "cPassiveAggressiveMonster.h" + +class cZombiepigman : public cPassiveAggressiveMonster +{ +public: + cZombiepigman(); + ~cZombiepigman(); + + virtual bool IsA( const char* a_EntityType ); + + virtual void Tick(float a_Dt); + virtual void KilledBy( cEntity* a_Killer ); +}; diff --git a/source/main.cpp b/source/main.cpp index 1d245ae0b..d379fdd17 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,204 +1,204 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cRoot.h" - -#include //std::exception -#include //std::signal -#include //exit() - -#ifdef _WIN32 - #include -#endif // _WIN32 - -#include "SquirrelBindings.h" -#if USE_SQUIRREL - #pragma warning(push) - #pragma warning(disable:4100;disable:4127;disable:4510;disable:4610;disable:4244;disable:4512) // Getting A LOT of these warnings from SqPlus - #include - #pragma warning(pop) -#endif - - - - -/// If defined, a thorough leak finder will be used (debug MSVC only); leaks will be output to the Output window -#define ENABLE_LEAK_FINDER - - - - - -#if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) - #define XML_LEAK_FINDER - #pragma warning(push) - #pragma warning(disable:4100) - #include "LeakFinder.h" - #pragma warning(pop) -#endif - - - - - - -void ShowCrashReport(int) -{ - std::signal(SIGSEGV, SIG_DFL); - - printf("\n\nMCServer has crashed!\n"); - - exit(-1); -} - - - - - -#if defined(_WIN32) && !defined(_WIN64) -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Windows 32-bit stuff: when the server crashes, create a "dump file" containing the callstack of each thread and some variables; let the user send us that crash file for analysis - -typedef BOOL (WINAPI *pMiniDumpWriteDump)( - HANDLE hProcess, - DWORD ProcessId, - HANDLE hFile, - MINIDUMP_TYPE DumpType, - PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, - PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, - PMINIDUMP_CALLBACK_INFORMATION CallbackParam -); - -pMiniDumpWriteDump g_WriteMiniDump; // The function in dbghlp DLL that creates dump files - -char g_DumpFileName[MAX_PATH]; // Filename of the dump file; hes to be created before the dump handler kicks in -char g_ExceptionStack[128 * 1024]; // Substitute stack, just in case the handler kicks in because of "insufficient stack space" -MINIDUMP_TYPE g_DumpFlags = MiniDumpNormal; // By default dump only the stack and some helpers - - - - - -/** This function gets called just before the "program executed an illegal instruction and will be terminated" or similar. -Its purpose is to create the crashdump using the dbghlp DLLs -*/ -LONG WINAPI LastChanceExceptionFilter(__in struct _EXCEPTION_POINTERS * a_ExceptionInfo) -{ - char * newStack = &g_ExceptionStack[sizeof(g_ExceptionStack)]; - char * oldStack; - - // Use the substitute stack: - // This code is the reason why we don't support 64-bit (yet) - _asm - { - mov oldStack, esp - mov esp, newStack - } - - MINIDUMP_EXCEPTION_INFORMATION ExcInformation; - ExcInformation.ThreadId = GetCurrentThreadId(); - ExcInformation.ExceptionPointers = a_ExceptionInfo; - ExcInformation.ClientPointers = 0; - - // Write the dump file: - HANDLE dumpFile = CreateFile(g_DumpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - g_WriteMiniDump(GetCurrentProcess(), GetCurrentProcessId(), dumpFile, g_DumpFlags, (a_ExceptionInfo) ? &ExcInformation : NULL, NULL, NULL); - CloseHandle(dumpFile); - - // Revert to old stack: - _asm - { - mov esp, oldStack - } - - return 0; -} - -#endif // _WIN32 && !_WIN64 - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// main: - -int main( int argc, char **argv ) -{ - (void)argc; - (void)argv; - - #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) - InitLeakFinder(); - #endif - - // Magic code to produce dump-files on Windows if the server crashes: - #if defined(_WIN32) && !defined(_WIN64) - HINSTANCE hDbgHelp = LoadLibrary("DBGHELP.DLL"); - g_WriteMiniDump = (pMiniDumpWriteDump)GetProcAddress(hDbgHelp, "MiniDumpWriteDump"); - if (g_WriteMiniDump != NULL) - { - _snprintf_s(g_DumpFileName, ARRAYCOUNT(g_DumpFileName), _TRUNCATE, "crash_mcs_%x.dmp", GetCurrentProcessId()); - SetUnhandledExceptionFilter(LastChanceExceptionFilter); - - // Parse arguments for minidump flags: - for (int i = 0; i < argc; i++) - { - if (stricmp(argv[i], "/cdg") == 0) - { - // Add globals to the dump - g_DumpFlags = (MINIDUMP_TYPE)(g_DumpFlags | MiniDumpWithDataSegs); - } - else if (stricmp(argv[i], "/cdf") == 0) - { - // Add full memory to the dump (HUUUGE file) - g_DumpFlags = (MINIDUMP_TYPE)(g_DumpFlags | MiniDumpWithFullMemory); - } - } // for i - argv[] - } - #endif // _WIN32 && !_WIN64 - // End of dump-file magic - - #if defined(_DEBUG) && defined(_MSC_VER) - _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); - - // _X: The simple built-in CRT leak finder - simply break when allocating the Nth block ({N} is listed in the leak output) - // Only useful when the leak is in the same sequence all the time - // _CrtSetBreakAlloc(85950); - - #endif // _DEBUG && _MSC_VER - - #ifndef _DEBUG - std::signal(SIGSEGV, ShowCrashReport); - #endif - - // DEBUG: test the dumpfile creation: - // *((int *)0) = 0; - - try - { - cRoot Root; - Root.Start(); - } - catch( std::exception& e ) - { - LOGERROR("Standard exception: %s", e.what() ); - } - catch( ... ) - { - LOGERROR("Unknown exception!"); - } - - #if USE_SQUIRREL - SquirrelVM::Shutdown(); - #endif - - #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) - DeinitLeakFinder(); - #endif - - return 0; -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cRoot.h" + +#include //std::exception +#include //std::signal +#include //exit() + +#ifdef _WIN32 + #include +#endif // _WIN32 + +#include "SquirrelBindings.h" +#if USE_SQUIRREL + #pragma warning(push) + #pragma warning(disable:4100;disable:4127;disable:4510;disable:4610;disable:4244;disable:4512) // Getting A LOT of these warnings from SqPlus + #include + #pragma warning(pop) +#endif + + + + +/// If defined, a thorough leak finder will be used (debug MSVC only); leaks will be output to the Output window +#define ENABLE_LEAK_FINDER + + + + + +#if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) + #define XML_LEAK_FINDER + #pragma warning(push) + #pragma warning(disable:4100) + #include "LeakFinder.h" + #pragma warning(pop) +#endif + + + + + + +void ShowCrashReport(int) +{ + std::signal(SIGSEGV, SIG_DFL); + + printf("\n\nMCServer has crashed!\n"); + + exit(-1); +} + + + + + +#if defined(_WIN32) && !defined(_WIN64) +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Windows 32-bit stuff: when the server crashes, create a "dump file" containing the callstack of each thread and some variables; let the user send us that crash file for analysis + +typedef BOOL (WINAPI *pMiniDumpWriteDump)( + HANDLE hProcess, + DWORD ProcessId, + HANDLE hFile, + MINIDUMP_TYPE DumpType, + PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, + PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, + PMINIDUMP_CALLBACK_INFORMATION CallbackParam +); + +pMiniDumpWriteDump g_WriteMiniDump; // The function in dbghlp DLL that creates dump files + +char g_DumpFileName[MAX_PATH]; // Filename of the dump file; hes to be created before the dump handler kicks in +char g_ExceptionStack[128 * 1024]; // Substitute stack, just in case the handler kicks in because of "insufficient stack space" +MINIDUMP_TYPE g_DumpFlags = MiniDumpNormal; // By default dump only the stack and some helpers + + + + + +/** This function gets called just before the "program executed an illegal instruction and will be terminated" or similar. +Its purpose is to create the crashdump using the dbghlp DLLs +*/ +LONG WINAPI LastChanceExceptionFilter(__in struct _EXCEPTION_POINTERS * a_ExceptionInfo) +{ + char * newStack = &g_ExceptionStack[sizeof(g_ExceptionStack)]; + char * oldStack; + + // Use the substitute stack: + // This code is the reason why we don't support 64-bit (yet) + _asm + { + mov oldStack, esp + mov esp, newStack + } + + MINIDUMP_EXCEPTION_INFORMATION ExcInformation; + ExcInformation.ThreadId = GetCurrentThreadId(); + ExcInformation.ExceptionPointers = a_ExceptionInfo; + ExcInformation.ClientPointers = 0; + + // Write the dump file: + HANDLE dumpFile = CreateFile(g_DumpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + g_WriteMiniDump(GetCurrentProcess(), GetCurrentProcessId(), dumpFile, g_DumpFlags, (a_ExceptionInfo) ? &ExcInformation : NULL, NULL, NULL); + CloseHandle(dumpFile); + + // Revert to old stack: + _asm + { + mov esp, oldStack + } + + return 0; +} + +#endif // _WIN32 && !_WIN64 + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// main: + +int main( int argc, char **argv ) +{ + (void)argc; + (void)argv; + + #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) + InitLeakFinder(); + #endif + + // Magic code to produce dump-files on Windows if the server crashes: + #if defined(_WIN32) && !defined(_WIN64) + HINSTANCE hDbgHelp = LoadLibrary("DBGHELP.DLL"); + g_WriteMiniDump = (pMiniDumpWriteDump)GetProcAddress(hDbgHelp, "MiniDumpWriteDump"); + if (g_WriteMiniDump != NULL) + { + _snprintf_s(g_DumpFileName, ARRAYCOUNT(g_DumpFileName), _TRUNCATE, "crash_mcs_%x.dmp", GetCurrentProcessId()); + SetUnhandledExceptionFilter(LastChanceExceptionFilter); + + // Parse arguments for minidump flags: + for (int i = 0; i < argc; i++) + { + if (stricmp(argv[i], "/cdg") == 0) + { + // Add globals to the dump + g_DumpFlags = (MINIDUMP_TYPE)(g_DumpFlags | MiniDumpWithDataSegs); + } + else if (stricmp(argv[i], "/cdf") == 0) + { + // Add full memory to the dump (HUUUGE file) + g_DumpFlags = (MINIDUMP_TYPE)(g_DumpFlags | MiniDumpWithFullMemory); + } + } // for i - argv[] + } + #endif // _WIN32 && !_WIN64 + // End of dump-file magic + + #if defined(_DEBUG) && defined(_MSC_VER) + _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); + + // _X: The simple built-in CRT leak finder - simply break when allocating the Nth block ({N} is listed in the leak output) + // Only useful when the leak is in the same sequence all the time + // _CrtSetBreakAlloc(85950); + + #endif // _DEBUG && _MSC_VER + + #ifndef _DEBUG + std::signal(SIGSEGV, ShowCrashReport); + #endif + + // DEBUG: test the dumpfile creation: + // *((int *)0) = 0; + + try + { + cRoot Root; + Root.Start(); + } + catch( std::exception& e ) + { + LOGERROR("Standard exception: %s", e.what() ); + } + catch( ... ) + { + LOGERROR("Unknown exception!"); + } + + #if USE_SQUIRREL + SquirrelVM::Shutdown(); + #endif + + #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) + DeinitLeakFinder(); + #endif + + return 0; +} + + + + diff --git a/source/md5/md5.cpp b/source/md5/md5.cpp index 2b9e10c9f..39337da5d 100644 --- a/source/md5/md5.cpp +++ b/source/md5/md5.cpp @@ -1,364 +1,364 @@ -/* 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. - -*/ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -/* interface header */ -#include "md5.h" - - - - - -// 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(); -} +/* 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. + +*/ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +/* interface header */ +#include "md5.h" + + + + + +// 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(); +} diff --git a/source/md5/md5.h b/source/md5/md5.h index 140ad1f14..ad5ad5384 100644 --- a/source/md5/md5.h +++ b/source/md5/md5.h @@ -1,93 +1,93 @@ -/* 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 -#include - - -// 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); - +/* 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 +#include + + +// 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 \ No newline at end of file diff --git a/source/packets/cPacket.cpp b/source/packets/cPacket.cpp index ec7181762..6fad331ed 100644 --- a/source/packets/cPacket.cpp +++ b/source/packets/cPacket.cpp @@ -1,307 +1,307 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket.h" -#include "../Endianness.h" - - - - - -/* -// These checks cannot be done in preprocessor, since sizeof() is evaluated while compiling, so in preprocessing it's unknown. -// Check some basic type assumptions: -#if (sizeof(int) != 4) - #error "Bad size for int, protocol won't work" -#endif - -#if (sizeof(float) != 4) - #error "Bad size for float, protocol won't work" -#endif - -#if (sizeof(double) != 8) - #error "Bad size for double, protocol won't work" -#endif -*/ - - - - - -int cPacket::ReadString16(const char * a_Data, int a_Size, AString & a_OutString ) -{ - int TotalBytes = 0; - short StrLen; - HANDLE_PACKET_READ(ReadShort, StrLen, TotalBytes); - - if (2 * StrLen > a_Size - TotalBytes) - { - // The string is not yet complete in the buffer - return PACKET_INCOMPLETE; - } - - // Simple UTF-16 to UTF-8 conversion - discard higher bits, ignore multishort sequences: - a_OutString.clear(); - a_OutString.reserve(StrLen); - short * UTF16 = (short *)(a_Data + TotalBytes); - for ( int i = 0; i < StrLen; ++i ) - { - a_OutString.push_back( (char)ntohs(UTF16[i]) ); - } - - return TotalBytes + StrLen * sizeof(short); -} - - - - - -int cPacket::ReadShort(const char * a_Data, int a_Size, short & a_OutShort ) -{ - if (a_Size < 2) - { - return PACKET_INCOMPLETE; - } - a_OutShort = ntohs(*((short *)a_Data)); - return 2; -} - - - - - -int cPacket::ReadInteger(const char * a_Data, int a_Size, int & a_OutInteger ) -{ - if (a_Size < 4) - { - return PACKET_INCOMPLETE; - } - a_OutInteger = ntohl(*((int *)a_Data)); - return 4; -} - - - - - -int cPacket::ReadInteger(const char * a_Data, int a_Size, unsigned int & a_OutInteger ) -{ - if (a_Size < 4) - { - return PACKET_INCOMPLETE; - } - a_OutInteger = ntohl(*((unsigned int *)a_Data)); - return 4; -} - - - - - -int cPacket::ReadFloat(const char * a_Data, int a_Size, float & a_OutFloat ) -{ - if (a_Size < sizeof(float)) - { - return PACKET_INCOMPLETE; - } - a_OutFloat = NetworkToHostFloat4(a_Data); - return sizeof(float); -} - - - - - -int cPacket::ReadDouble(const char * a_Data, int a_Size, double & a_OutDouble ) -{ - if (a_Size < sizeof(double)) - { - return PACKET_INCOMPLETE; - } - a_OutDouble = NetworkToHostDouble8(a_Data); - return sizeof(double); -} - - - - - -int cPacket::ReadByte(const char * a_Data, int a_Size, char & a_OutByte ) -{ - if (a_Size < 1) - { - return PACKET_INCOMPLETE; - } - a_OutByte = *a_Data; - return 1; -} - - - - - -int cPacket::ReadByte(const char * a_Data, int a_Size, unsigned char & a_OutByte ) -{ - if (a_Size < 1) - { - return PACKET_INCOMPLETE; - } - a_OutByte = *((unsigned char *)a_Data); - return 1; -} - - - - - -int cPacket::ReadLong(const char * a_Data, int a_Size, long long & a_OutLong ) -{ - if (a_Size < sizeof(a_OutLong)) - { - return PACKET_INCOMPLETE; - } - a_OutLong = NetworkToHostLong8(a_Data); - return sizeof(a_OutLong); -} - - - - - -int cPacket::ReadBool(const char * a_Data, int a_Size, bool & a_OutBool ) -{ - if (a_Size < sizeof(bool)) - { - return PACKET_INCOMPLETE; - } - a_OutBool = (*a_Data != 0); - return sizeof(bool); -} - - - - - -void cPacket::AppendString(AString & a_Dst, const AString & a_String) -{ - AppendShort(a_Dst, (unsigned short)a_String.size()); - a_Dst.append(a_String); -} - - - - - -void cPacket::AppendString16(AString & a_Dst, const AString & a_String) -{ - AppendShort(a_Dst, (unsigned short)a_String.size()); - AString UTF16; - UTF16.resize(a_String.size() * sizeof(short)); - for( unsigned int i = 0; i < a_String.size(); ++i ) - { - UTF16[i * sizeof( short )] = 0x00; - UTF16[i * sizeof( short ) + 1] = a_String[i]; - } - a_Dst.append(UTF16.data(), a_String.size() * sizeof(short)); -} - - - - - -void cPacket::AppendShort(AString & a_Dst, short a_Short) -{ - short ConvertedShort = htons( a_Short ); - a_Dst.append((const char *)&ConvertedShort, sizeof(short)); -} - - - - - -void cPacket::AppendShort(AString & a_Dst, unsigned short a_Short) -{ - short ConvertedShort = htons( a_Short ); - a_Dst.append((const char *)&ConvertedShort, sizeof(short)); -} - - - - - -void cPacket::AppendInteger(AString & a_Dst, int a_Integer) -{ - int ConvertedInt = htonl( a_Integer ); - a_Dst.append((const char *)&ConvertedInt, sizeof(int)); -} - - - - - -void cPacket::AppendInteger(AString & a_Dst, unsigned int a_Integer) -{ - unsigned int ConvertedInt = htonl( a_Integer ); - a_Dst.append((const char *)&ConvertedInt, sizeof(int)); -} - - - - - -void cPacket::AppendFloat(AString & a_Dst, float a_Float) -{ - unsigned int ConvertedFloat = HostToNetwork4(&a_Float); - a_Dst.append((const char *)&ConvertedFloat, sizeof(int)); -} - - - - - -void cPacket::AppendDouble(AString & a_Dst, const double & a_Double) -{ - unsigned long long ConvertedDouble = HostToNetwork8(&a_Double); - a_Dst.append((const char *)&ConvertedDouble, 8); -} - - - - - -void cPacket::AppendByte(AString & a_Dst, char a_Byte) -{ - a_Dst.append(&a_Byte, 1); -} - - - - - -void cPacket::AppendLong(AString & a_Dst, const long long & a_Long) -{ - unsigned long long ConvertedLong = HostToNetwork8(&a_Long); - a_Dst.append((const char *)&ConvertedLong, sizeof(a_Long)); -} - - - - - -void cPacket::AppendBool(AString & a_Dst, bool a_Bool) -{ - a_Dst.append((const char *)&a_Bool, 1); -} - - - - - -void cPacket::AppendData(AString & a_Dst, const char * a_Data, unsigned int a_Size) -{ - a_Dst.append(a_Data, a_Size); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket.h" +#include "../Endianness.h" + + + + + +/* +// These checks cannot be done in preprocessor, since sizeof() is evaluated while compiling, so in preprocessing it's unknown. +// Check some basic type assumptions: +#if (sizeof(int) != 4) + #error "Bad size for int, protocol won't work" +#endif + +#if (sizeof(float) != 4) + #error "Bad size for float, protocol won't work" +#endif + +#if (sizeof(double) != 8) + #error "Bad size for double, protocol won't work" +#endif +*/ + + + + + +int cPacket::ReadString16(const char * a_Data, int a_Size, AString & a_OutString ) +{ + int TotalBytes = 0; + short StrLen; + HANDLE_PACKET_READ(ReadShort, StrLen, TotalBytes); + + if (2 * StrLen > a_Size - TotalBytes) + { + // The string is not yet complete in the buffer + return PACKET_INCOMPLETE; + } + + // Simple UTF-16 to UTF-8 conversion - discard higher bits, ignore multishort sequences: + a_OutString.clear(); + a_OutString.reserve(StrLen); + short * UTF16 = (short *)(a_Data + TotalBytes); + for ( int i = 0; i < StrLen; ++i ) + { + a_OutString.push_back( (char)ntohs(UTF16[i]) ); + } + + return TotalBytes + StrLen * sizeof(short); +} + + + + + +int cPacket::ReadShort(const char * a_Data, int a_Size, short & a_OutShort ) +{ + if (a_Size < 2) + { + return PACKET_INCOMPLETE; + } + a_OutShort = ntohs(*((short *)a_Data)); + return 2; +} + + + + + +int cPacket::ReadInteger(const char * a_Data, int a_Size, int & a_OutInteger ) +{ + if (a_Size < 4) + { + return PACKET_INCOMPLETE; + } + a_OutInteger = ntohl(*((int *)a_Data)); + return 4; +} + + + + + +int cPacket::ReadInteger(const char * a_Data, int a_Size, unsigned int & a_OutInteger ) +{ + if (a_Size < 4) + { + return PACKET_INCOMPLETE; + } + a_OutInteger = ntohl(*((unsigned int *)a_Data)); + return 4; +} + + + + + +int cPacket::ReadFloat(const char * a_Data, int a_Size, float & a_OutFloat ) +{ + if (a_Size < sizeof(float)) + { + return PACKET_INCOMPLETE; + } + a_OutFloat = NetworkToHostFloat4(a_Data); + return sizeof(float); +} + + + + + +int cPacket::ReadDouble(const char * a_Data, int a_Size, double & a_OutDouble ) +{ + if (a_Size < sizeof(double)) + { + return PACKET_INCOMPLETE; + } + a_OutDouble = NetworkToHostDouble8(a_Data); + return sizeof(double); +} + + + + + +int cPacket::ReadByte(const char * a_Data, int a_Size, char & a_OutByte ) +{ + if (a_Size < 1) + { + return PACKET_INCOMPLETE; + } + a_OutByte = *a_Data; + return 1; +} + + + + + +int cPacket::ReadByte(const char * a_Data, int a_Size, unsigned char & a_OutByte ) +{ + if (a_Size < 1) + { + return PACKET_INCOMPLETE; + } + a_OutByte = *((unsigned char *)a_Data); + return 1; +} + + + + + +int cPacket::ReadLong(const char * a_Data, int a_Size, long long & a_OutLong ) +{ + if (a_Size < sizeof(a_OutLong)) + { + return PACKET_INCOMPLETE; + } + a_OutLong = NetworkToHostLong8(a_Data); + return sizeof(a_OutLong); +} + + + + + +int cPacket::ReadBool(const char * a_Data, int a_Size, bool & a_OutBool ) +{ + if (a_Size < sizeof(bool)) + { + return PACKET_INCOMPLETE; + } + a_OutBool = (*a_Data != 0); + return sizeof(bool); +} + + + + + +void cPacket::AppendString(AString & a_Dst, const AString & a_String) +{ + AppendShort(a_Dst, (unsigned short)a_String.size()); + a_Dst.append(a_String); +} + + + + + +void cPacket::AppendString16(AString & a_Dst, const AString & a_String) +{ + AppendShort(a_Dst, (unsigned short)a_String.size()); + AString UTF16; + UTF16.resize(a_String.size() * sizeof(short)); + for( unsigned int i = 0; i < a_String.size(); ++i ) + { + UTF16[i * sizeof( short )] = 0x00; + UTF16[i * sizeof( short ) + 1] = a_String[i]; + } + a_Dst.append(UTF16.data(), a_String.size() * sizeof(short)); +} + + + + + +void cPacket::AppendShort(AString & a_Dst, short a_Short) +{ + short ConvertedShort = htons( a_Short ); + a_Dst.append((const char *)&ConvertedShort, sizeof(short)); +} + + + + + +void cPacket::AppendShort(AString & a_Dst, unsigned short a_Short) +{ + short ConvertedShort = htons( a_Short ); + a_Dst.append((const char *)&ConvertedShort, sizeof(short)); +} + + + + + +void cPacket::AppendInteger(AString & a_Dst, int a_Integer) +{ + int ConvertedInt = htonl( a_Integer ); + a_Dst.append((const char *)&ConvertedInt, sizeof(int)); +} + + + + + +void cPacket::AppendInteger(AString & a_Dst, unsigned int a_Integer) +{ + unsigned int ConvertedInt = htonl( a_Integer ); + a_Dst.append((const char *)&ConvertedInt, sizeof(int)); +} + + + + + +void cPacket::AppendFloat(AString & a_Dst, float a_Float) +{ + unsigned int ConvertedFloat = HostToNetwork4(&a_Float); + a_Dst.append((const char *)&ConvertedFloat, sizeof(int)); +} + + + + + +void cPacket::AppendDouble(AString & a_Dst, const double & a_Double) +{ + unsigned long long ConvertedDouble = HostToNetwork8(&a_Double); + a_Dst.append((const char *)&ConvertedDouble, 8); +} + + + + + +void cPacket::AppendByte(AString & a_Dst, char a_Byte) +{ + a_Dst.append(&a_Byte, 1); +} + + + + + +void cPacket::AppendLong(AString & a_Dst, const long long & a_Long) +{ + unsigned long long ConvertedLong = HostToNetwork8(&a_Long); + a_Dst.append((const char *)&ConvertedLong, sizeof(a_Long)); +} + + + + + +void cPacket::AppendBool(AString & a_Dst, bool a_Bool) +{ + a_Dst.append((const char *)&a_Bool, 1); +} + + + + + +void cPacket::AppendData(AString & a_Dst, const char * a_Data, unsigned int a_Size) +{ + a_Dst.append(a_Data, a_Size); +} + + + + diff --git a/source/packets/cPacket.h b/source/packets/cPacket.h index 7eb224c9e..f5a014ed5 100644 --- a/source/packets/cPacket.h +++ b/source/packets/cPacket.h @@ -1,94 +1,94 @@ - -#pragma once - -#include "../cSocket.h" -#include "../PacketID.h" - - - - - -#define PACKET_INCOMPLETE -2 -#define PACKET_ERROR -1 - - - - - -// Use this macro to simplify handling several ReadXXX in a row. It assumes that you want [a_Data, a_Size] parsed (which is true for all Parse() functions) -#define HANDLE_PACKET_READ(Proc, Var, TotalBytes) \ - { \ - int res = Proc(a_Data + TotalBytes, a_Size - TotalBytes, Var); \ - if (res < 0) \ - { \ - return res; \ - } \ - TotalBytes += res; \ - } - - - - - -class cPacket -{ -public: - cPacket() - : m_PacketID( 0 ) - {} - virtual ~cPacket() {} - - /// Called to parse the packet. Packet type has already been read and the correct packet type created. Return the number of characters processed, PACKET_INCOMPLETE for incomplete data, PACKET_ERROR for error - virtual int Parse(const char * a_Data, int a_Size) - { - LOGERROR("Undefined Parse function for packet type 0x%x\n", m_PacketID ); - ASSERT(!"Undefined Parse function"); - return -1; - } - - /// Called to serialize the packet into a string. Append all packet data to a_Data, including the packet type! - virtual void Serialize(AString & a_Data) const - { - LOGERROR("Undefined Serialize function for packet type 0x%x\n", m_PacketID ); - ASSERT(!"Undefined Serialize function"); - } - - virtual cPacket * Clone() const = 0; - - unsigned char m_PacketID; - -protected: - - // These return the number of characters processed, PACKET_INCOMPLETE for incomplete data, PACKET_ERROR for error: - static int ReadString16(const char * a_Data, int a_Size, AString & a_OutString ); - static int ReadShort (const char * a_Data, int a_Size, short & a_Short ); - static int ReadInteger (const char * a_Data, int a_Size, int & a_OutInteger ); - static int ReadInteger (const char * a_Data, int a_Size, unsigned int & a_OutInteger ); - static int ReadFloat (const char * a_Data, int a_Size, float & a_OutFloat ); - static int ReadDouble (const char * a_Data, int a_Size, double & a_OutDouble ); - static int ReadByte (const char * a_Data, int a_Size, char & a_OutByte ); - static int ReadByte (const char * a_Data, int a_Size, unsigned char & a_OutByte ); - static int ReadLong (const char * a_Data, int a_Size, long long & a_OutLong ); - static int ReadBool (const char * a_Data, int a_Size, bool & a_OutBool ); - - // These append the data into the a_Dst string: - static void AppendString ( AString & a_Dst, const AString & a_String); - static void AppendString16( AString & a_Dst, const AString & a_String); - static void AppendShort ( AString & a_Dst, short a_Short); - static void AppendShort ( AString & a_Dst, unsigned short a_Short); - static void AppendInteger ( AString & a_Dst, int a_Integer); - static void AppendInteger ( AString & a_Dst, unsigned int a_Integer); - static void AppendFloat ( AString & a_Dst, float a_Float); - static void AppendDouble ( AString & a_Dst, const double & a_Double); - static void AppendByte ( AString & a_Dst, char a_Byte); - static void AppendLong ( AString & a_Dst, const long long & a_Long); - static void AppendBool ( AString & a_Dst, bool a_Bool); - static void AppendData ( AString & a_Dst, const char * a_Data, unsigned int a_Size); -}; - -typedef std::list PacketList; -typedef std::deque PacketQueue; - - - - + +#pragma once + +#include "../cSocket.h" +#include "../PacketID.h" + + + + + +#define PACKET_INCOMPLETE -2 +#define PACKET_ERROR -1 + + + + + +// Use this macro to simplify handling several ReadXXX in a row. It assumes that you want [a_Data, a_Size] parsed (which is true for all Parse() functions) +#define HANDLE_PACKET_READ(Proc, Var, TotalBytes) \ + { \ + int res = Proc(a_Data + TotalBytes, a_Size - TotalBytes, Var); \ + if (res < 0) \ + { \ + return res; \ + } \ + TotalBytes += res; \ + } + + + + + +class cPacket +{ +public: + cPacket() + : m_PacketID( 0 ) + {} + virtual ~cPacket() {} + + /// Called to parse the packet. Packet type has already been read and the correct packet type created. Return the number of characters processed, PACKET_INCOMPLETE for incomplete data, PACKET_ERROR for error + virtual int Parse(const char * a_Data, int a_Size) + { + LOGERROR("Undefined Parse function for packet type 0x%x\n", m_PacketID ); + ASSERT(!"Undefined Parse function"); + return -1; + } + + /// Called to serialize the packet into a string. Append all packet data to a_Data, including the packet type! + virtual void Serialize(AString & a_Data) const + { + LOGERROR("Undefined Serialize function for packet type 0x%x\n", m_PacketID ); + ASSERT(!"Undefined Serialize function"); + } + + virtual cPacket * Clone() const = 0; + + unsigned char m_PacketID; + +protected: + + // These return the number of characters processed, PACKET_INCOMPLETE for incomplete data, PACKET_ERROR for error: + static int ReadString16(const char * a_Data, int a_Size, AString & a_OutString ); + static int ReadShort (const char * a_Data, int a_Size, short & a_Short ); + static int ReadInteger (const char * a_Data, int a_Size, int & a_OutInteger ); + static int ReadInteger (const char * a_Data, int a_Size, unsigned int & a_OutInteger ); + static int ReadFloat (const char * a_Data, int a_Size, float & a_OutFloat ); + static int ReadDouble (const char * a_Data, int a_Size, double & a_OutDouble ); + static int ReadByte (const char * a_Data, int a_Size, char & a_OutByte ); + static int ReadByte (const char * a_Data, int a_Size, unsigned char & a_OutByte ); + static int ReadLong (const char * a_Data, int a_Size, long long & a_OutLong ); + static int ReadBool (const char * a_Data, int a_Size, bool & a_OutBool ); + + // These append the data into the a_Dst string: + static void AppendString ( AString & a_Dst, const AString & a_String); + static void AppendString16( AString & a_Dst, const AString & a_String); + static void AppendShort ( AString & a_Dst, short a_Short); + static void AppendShort ( AString & a_Dst, unsigned short a_Short); + static void AppendInteger ( AString & a_Dst, int a_Integer); + static void AppendInteger ( AString & a_Dst, unsigned int a_Integer); + static void AppendFloat ( AString & a_Dst, float a_Float); + static void AppendDouble ( AString & a_Dst, const double & a_Double); + static void AppendByte ( AString & a_Dst, char a_Byte); + static void AppendLong ( AString & a_Dst, const long long & a_Long); + static void AppendBool ( AString & a_Dst, bool a_Bool); + static void AppendData ( AString & a_Dst, const char * a_Data, unsigned int a_Size); +}; + +typedef std::list PacketList; +typedef std::deque PacketQueue; + + + + diff --git a/source/packets/cPacket_13.cpp b/source/packets/cPacket_13.cpp index aebef4410..4edeb8c95 100644 --- a/source/packets/cPacket_13.cpp +++ b/source/packets/cPacket_13.cpp @@ -1,20 +1,20 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_13.h" - - - - - -int cPacket_13::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadInteger, m_EntityID, TotalBytes); - HANDLE_PACKET_READ(ReadByte , m_ActionID, TotalBytes); - return TotalBytes; -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_13.h" + + + + + +int cPacket_13::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadInteger, m_EntityID, TotalBytes); + HANDLE_PACKET_READ(ReadByte , m_ActionID, TotalBytes); + return TotalBytes; +} + + + + diff --git a/source/packets/cPacket_13.h b/source/packets/cPacket_13.h index 361e35fe7..d0a257302 100644 --- a/source/packets/cPacket_13.h +++ b/source/packets/cPacket_13.h @@ -1,34 +1,34 @@ -#pragma once - -#include "cPacket.h" - - -class cPacket_13 : public cPacket -{ -public: - enum ENUM_ACTION - { - ACTION_CROUCH = 1, - ACTION_UNCROUCH = 2, - ACTION_LEAVEBED = 3, - ACTION_STARTSPRINTING = 4, - ACTION_STOPSPRINTING = 5, - }; - - cPacket_13() - : m_EntityID( 0 ) - , m_ActionID( 0 ) - { m_PacketID = E_PACKET_13; } - virtual cPacket* Clone() const { return new cPacket_13( *this ); } - - virtual int Parse(const char * a_Data, int a_Size) override; - - int m_EntityID; - char m_ActionID; - - static const unsigned int c_Size = 1; -}; - - - - +#pragma once + +#include "cPacket.h" + + +class cPacket_13 : public cPacket +{ +public: + enum ENUM_ACTION + { + ACTION_CROUCH = 1, + ACTION_UNCROUCH = 2, + ACTION_LEAVEBED = 3, + ACTION_STARTSPRINTING = 4, + ACTION_STOPSPRINTING = 5, + }; + + cPacket_13() + : m_EntityID( 0 ) + , m_ActionID( 0 ) + { m_PacketID = E_PACKET_13; } + virtual cPacket* Clone() const { return new cPacket_13( *this ); } + + virtual int Parse(const char * a_Data, int a_Size) override; + + int m_EntityID; + char m_ActionID; + + static const unsigned int c_Size = 1; +}; + + + + diff --git a/source/packets/cPacket_AddToInventory.cpp b/source/packets/cPacket_AddToInventory.cpp index c8606afe0..b9231112c 100644 --- a/source/packets/cPacket_AddToInventory.cpp +++ b/source/packets/cPacket_AddToInventory.cpp @@ -1,20 +1,20 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_AddToInventory.h" -#include "cPacket_WholeInventory.h" -#include "cPacket_ItemData.h" - - - - - -void cPacket_AddToInventory::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - cPacket_ItemData::AppendItem(a_Data, m_ItemType, m_Count, m_Life); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_AddToInventory.h" +#include "cPacket_WholeInventory.h" +#include "cPacket_ItemData.h" + + + + + +void cPacket_AddToInventory::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + cPacket_ItemData::AppendItem(a_Data, m_ItemType, m_Count, m_Life); +} + + + + diff --git a/source/packets/cPacket_AddToInventory.h b/source/packets/cPacket_AddToInventory.h index 4317607a5..f7e1a084b 100644 --- a/source/packets/cPacket_AddToInventory.h +++ b/source/packets/cPacket_AddToInventory.h @@ -1,26 +1,26 @@ -#pragma once - -#include "cPacket.h" - -#include "../BlockID.h" - -class cPacket_AddToInventory : public cPacket -{ -public: - cPacket_AddToInventory() - : m_ItemType( E_ITEM_EMPTY ) - , m_Count( 0 ) - , m_Life( 0 ) - { m_PacketID = E_ADD_TO_INV; } - virtual cPacket* Clone() const { return new cPacket_AddToInventory(*this); } - - // _X: This was unimplemented, do we need it?: - // bool Parse( cSocket & a_Socket ); - - virtual void Serialize(AString & a_Data) const override; - - ENUM_ITEM_ID m_ItemType; - char m_Count; - short m_Life; - static const unsigned int c_Size = 1; -}; +#pragma once + +#include "cPacket.h" + +#include "../BlockID.h" + +class cPacket_AddToInventory : public cPacket +{ +public: + cPacket_AddToInventory() + : m_ItemType( E_ITEM_EMPTY ) + , m_Count( 0 ) + , m_Life( 0 ) + { m_PacketID = E_ADD_TO_INV; } + virtual cPacket* Clone() const { return new cPacket_AddToInventory(*this); } + + // _X: This was unimplemented, do we need it?: + // bool Parse( cSocket & a_Socket ); + + virtual void Serialize(AString & a_Data) const override; + + ENUM_ITEM_ID m_ItemType; + char m_Count; + short m_Life; + static const unsigned int c_Size = 1; +}; diff --git a/source/packets/cPacket_ArmAnim.cpp b/source/packets/cPacket_ArmAnim.cpp index c1766e8ce..dcd416449 100644 --- a/source/packets/cPacket_ArmAnim.cpp +++ b/source/packets/cPacket_ArmAnim.cpp @@ -1,31 +1,31 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_ArmAnim.h" - - - - - -int cPacket_ArmAnim::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadInteger, m_EntityID, TotalBytes); - HANDLE_PACKET_READ(ReadByte , m_Animation, TotalBytes); - return TotalBytes; -} - - - - - -void cPacket_ArmAnim::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendInteger(a_Data, m_EntityID); - AppendByte (a_Data, m_Animation); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_ArmAnim.h" + + + + + +int cPacket_ArmAnim::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadInteger, m_EntityID, TotalBytes); + HANDLE_PACKET_READ(ReadByte , m_Animation, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_ArmAnim::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_EntityID); + AppendByte (a_Data, m_Animation); +} + + + + diff --git a/source/packets/cPacket_ArmAnim.h b/source/packets/cPacket_ArmAnim.h index 07753ebcb..79670de1c 100644 --- a/source/packets/cPacket_ArmAnim.h +++ b/source/packets/cPacket_ArmAnim.h @@ -1,21 +1,21 @@ -#pragma once - -#include "cPacket.h" - - -class cPacket_ArmAnim : public cPacket -{ -public: - cPacket_ArmAnim() - : m_EntityID( 0 ) - , m_Animation( 0 ) - { m_PacketID = E_ANIMATION; } - virtual cPacket* Clone() const { return new cPacket_ArmAnim(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - int m_EntityID; - char m_Animation; - static const unsigned int c_Size = 1 + 4 + 1; +#pragma once + +#include "cPacket.h" + + +class cPacket_ArmAnim : public cPacket +{ +public: + cPacket_ArmAnim() + : m_EntityID( 0 ) + , m_Animation( 0 ) + { m_PacketID = E_ANIMATION; } + virtual cPacket* Clone() const { return new cPacket_ArmAnim(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + int m_EntityID; + char m_Animation; + static const unsigned int c_Size = 1 + 4 + 1; }; \ No newline at end of file diff --git a/source/packets/cPacket_BlockChange.cpp b/source/packets/cPacket_BlockChange.cpp index 57c938814..e0ef5c001 100644 --- a/source/packets/cPacket_BlockChange.cpp +++ b/source/packets/cPacket_BlockChange.cpp @@ -1,22 +1,22 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_BlockChange.h" - - - - - -void cPacket_BlockChange::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendInteger(a_Data, m_PosX); - AppendByte (a_Data, m_PosY); - AppendInteger(a_Data, m_PosZ); - AppendByte (a_Data, m_BlockType); - AppendByte (a_Data, m_BlockMeta); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_BlockChange.h" + + + + + +void cPacket_BlockChange::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_PosX); + AppendByte (a_Data, m_PosY); + AppendInteger(a_Data, m_PosZ); + AppendByte (a_Data, m_BlockType); + AppendByte (a_Data, m_BlockMeta); +} + + + + diff --git a/source/packets/cPacket_BlockChange.h b/source/packets/cPacket_BlockChange.h index a0b3c8843..039043cf0 100644 --- a/source/packets/cPacket_BlockChange.h +++ b/source/packets/cPacket_BlockChange.h @@ -1,27 +1,27 @@ -#pragma once - -#include "cPacket.h" - - -class cPacket_BlockChange : public cPacket -{ -public: - cPacket_BlockChange() - : m_PosX( 0 ) - , m_PosY( 0 ) - , m_PosZ( 0 ) - , m_BlockType( 0 ) - , m_BlockMeta( 0 ) - { m_PacketID = E_BLOCK_CHANGE; } - virtual cPacket* Clone() const { return new cPacket_BlockChange(*this); } - - virtual void Serialize(AString & a_Data) const override; - - int m_PosX; - unsigned char m_PosY; - int m_PosZ; - char m_BlockType; - char m_BlockMeta; - - static const unsigned int c_Size = 1 + 4 + 1 + 4 + 1 + 1; +#pragma once + +#include "cPacket.h" + + +class cPacket_BlockChange : public cPacket +{ +public: + cPacket_BlockChange() + : m_PosX( 0 ) + , m_PosY( 0 ) + , m_PosZ( 0 ) + , m_BlockType( 0 ) + , m_BlockMeta( 0 ) + { m_PacketID = E_BLOCK_CHANGE; } + virtual cPacket* Clone() const { return new cPacket_BlockChange(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_PosX; + unsigned char m_PosY; + int m_PosZ; + char m_BlockType; + char m_BlockMeta; + + static const unsigned int c_Size = 1 + 4 + 1 + 4 + 1 + 1; }; \ No newline at end of file diff --git a/source/packets/cPacket_BlockDig.cpp b/source/packets/cPacket_BlockDig.cpp index 466e77340..be2088cd0 100644 --- a/source/packets/cPacket_BlockDig.cpp +++ b/source/packets/cPacket_BlockDig.cpp @@ -1,36 +1,36 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_BlockDig.h" - - - - - -void cPacket_BlockDig::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendInteger(a_Data, m_PosX); - AppendByte (a_Data, m_PosY); - AppendInteger(a_Data, m_PosZ); - AppendByte (a_Data, m_Direction); -} - - - - - -int cPacket_BlockDig::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadByte, m_Status, TotalBytes); - HANDLE_PACKET_READ(ReadInteger, m_PosX, TotalBytes); - HANDLE_PACKET_READ(ReadByte, m_PosY, TotalBytes); - HANDLE_PACKET_READ(ReadInteger, m_PosZ, TotalBytes); - HANDLE_PACKET_READ(ReadByte, m_Direction, TotalBytes); - return TotalBytes; -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_BlockDig.h" + + + + + +void cPacket_BlockDig::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_PosX); + AppendByte (a_Data, m_PosY); + AppendInteger(a_Data, m_PosZ); + AppendByte (a_Data, m_Direction); +} + + + + + +int cPacket_BlockDig::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadByte, m_Status, TotalBytes); + HANDLE_PACKET_READ(ReadInteger, m_PosX, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_PosY, TotalBytes); + HANDLE_PACKET_READ(ReadInteger, m_PosZ, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_Direction, TotalBytes); + return TotalBytes; +} + + + + diff --git a/source/packets/cPacket_BlockDig.h b/source/packets/cPacket_BlockDig.h index 56ddfa9ca..1fde63db6 100644 --- a/source/packets/cPacket_BlockDig.h +++ b/source/packets/cPacket_BlockDig.h @@ -1,32 +1,32 @@ -#pragma once - -#include "cPacket.h" - - -class cPacket_BlockDig : public cPacket //tolua_export -{ //tolua_export -public: - cPacket_BlockDig() //tolua_export - : m_Status( 0 ) - , m_PosX( 0 ) - , m_PosY( 0 ) - , m_PosZ( 0 ) - , m_Direction( 0 ) - { m_PacketID = E_BLOCK_DIG; } //tolua_export - virtual cPacket* Clone() const { return new cPacket_BlockDig(*this); } //tolua_export - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - char m_Status; // tolua_export - int m_PosX; // tolua_export - char m_PosY; // tolua_export - int m_PosZ; // tolua_export - char m_Direction; // tolua_export - - static const unsigned int c_Size = 12; -}; //tolua_export - - - - +#pragma once + +#include "cPacket.h" + + +class cPacket_BlockDig : public cPacket //tolua_export +{ //tolua_export +public: + cPacket_BlockDig() //tolua_export + : m_Status( 0 ) + , m_PosX( 0 ) + , m_PosY( 0 ) + , m_PosZ( 0 ) + , m_Direction( 0 ) + { m_PacketID = E_BLOCK_DIG; } //tolua_export + virtual cPacket* Clone() const { return new cPacket_BlockDig(*this); } //tolua_export + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + char m_Status; // tolua_export + int m_PosX; // tolua_export + char m_PosY; // tolua_export + int m_PosZ; // tolua_export + char m_Direction; // tolua_export + + static const unsigned int c_Size = 12; +}; //tolua_export + + + + diff --git a/source/packets/cPacket_BlockPlace.cpp b/source/packets/cPacket_BlockPlace.cpp index 6582c7890..2033bd91e 100644 --- a/source/packets/cPacket_BlockPlace.cpp +++ b/source/packets/cPacket_BlockPlace.cpp @@ -1,36 +1,36 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_BlockPlace.h" -#include "cPacket_ItemData.h" - - - - - -int cPacket_BlockPlace::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadInteger, m_PosX, TotalBytes); - HANDLE_PACKET_READ(ReadByte, m_PosY, TotalBytes); - HANDLE_PACKET_READ(ReadInteger, m_PosZ, TotalBytes); - HANDLE_PACKET_READ(ReadByte, m_Direction, TotalBytes); - - cPacket_ItemData Item; - int res = Item.Parse(a_Data + TotalBytes, a_Size - TotalBytes); - if (res < 0) - { - return res; - } - TotalBytes += res; - - m_ItemType = Item.m_ItemID; - m_Count = Item.m_ItemCount; - m_Uses = Item.m_ItemUses; - - return TotalBytes; -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_BlockPlace.h" +#include "cPacket_ItemData.h" + + + + + +int cPacket_BlockPlace::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadInteger, m_PosX, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_PosY, TotalBytes); + HANDLE_PACKET_READ(ReadInteger, m_PosZ, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_Direction, TotalBytes); + + cPacket_ItemData Item; + int res = Item.Parse(a_Data + TotalBytes, a_Size - TotalBytes); + if (res < 0) + { + return res; + } + TotalBytes += res; + + m_ItemType = Item.m_ItemID; + m_Count = Item.m_ItemCount; + m_Uses = Item.m_ItemUses; + + return TotalBytes; +} + + + + diff --git a/source/packets/cPacket_BlockPlace.h b/source/packets/cPacket_BlockPlace.h index 9fa2fbbce..b8db56fd0 100644 --- a/source/packets/cPacket_BlockPlace.h +++ b/source/packets/cPacket_BlockPlace.h @@ -1,40 +1,40 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_BlockPlace : public cPacket //tolua_export -{ //tolua_export -public: - cPacket_BlockPlace() - : m_PosX( 0 ) - , m_PosY( 0 ) - , m_PosZ( 0 ) - , m_Direction( 0 ) - , m_ItemType( 0 ) - , m_Count( 0 ) - , m_Uses( 0 ) - { m_PacketID = E_BLOCK_PLACE; } - virtual cPacket* Clone() const { return new cPacket_BlockPlace(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - - int m_PosX; //tolua_export - unsigned char m_PosY; //tolua_export - int m_PosZ; //tolua_export - char m_Direction; //tolua_export - - short m_ItemType; //tolua_export - char m_Count; //tolua_export - short m_Uses; //tolua_export - - static const unsigned int c_Size = 1 + 4 + 1 + 4 + 1 + 2;// ( + 2 ) -}; //tolua_export - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_BlockPlace : public cPacket //tolua_export +{ //tolua_export +public: + cPacket_BlockPlace() + : m_PosX( 0 ) + , m_PosY( 0 ) + , m_PosZ( 0 ) + , m_Direction( 0 ) + , m_ItemType( 0 ) + , m_Count( 0 ) + , m_Uses( 0 ) + { m_PacketID = E_BLOCK_PLACE; } + virtual cPacket* Clone() const { return new cPacket_BlockPlace(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + + int m_PosX; //tolua_export + unsigned char m_PosY; //tolua_export + int m_PosZ; //tolua_export + char m_Direction; //tolua_export + + short m_ItemType; //tolua_export + char m_Count; //tolua_export + short m_Uses; //tolua_export + + static const unsigned int c_Size = 1 + 4 + 1 + 4 + 1 + 2;// ( + 2 ) +}; //tolua_export + + + + diff --git a/source/packets/cPacket_Chat.cpp b/source/packets/cPacket_Chat.cpp index 04a65d18e..43b1af3fa 100644 --- a/source/packets/cPacket_Chat.cpp +++ b/source/packets/cPacket_Chat.cpp @@ -1,29 +1,29 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_Chat.h" - - - - - -int cPacket_Chat::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadString16, m_Message, TotalBytes); - return TotalBytes; -} - - - - - -void cPacket_Chat::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendString16(a_Data, m_Message); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_Chat.h" + + + + + +int cPacket_Chat::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadString16, m_Message, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_Chat::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendString16(a_Data, m_Message); +} + + + + diff --git a/source/packets/cPacket_Chat.h b/source/packets/cPacket_Chat.h index 4141439d9..fac4a4097 100644 --- a/source/packets/cPacket_Chat.h +++ b/source/packets/cPacket_Chat.h @@ -1,22 +1,22 @@ -#pragma once - -#include "cPacket.h" - - -class cPacket_Chat : public cPacket -{ -public: - cPacket_Chat() { m_PacketID = E_CHAT; } - cPacket_Chat( const std::string & a_Message ) : m_Message( a_Message) { m_PacketID = E_CHAT; } - virtual cPacket* Clone() const { return new cPacket_Chat(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - AString m_Message; - static const unsigned int c_Size = 3; // Minimum size -}; - - - - +#pragma once + +#include "cPacket.h" + + +class cPacket_Chat : public cPacket +{ +public: + cPacket_Chat() { m_PacketID = E_CHAT; } + cPacket_Chat( const std::string & a_Message ) : m_Message( a_Message) { m_PacketID = E_CHAT; } + virtual cPacket* Clone() const { return new cPacket_Chat(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + AString m_Message; + static const unsigned int c_Size = 3; // Minimum size +}; + + + + diff --git a/source/packets/cPacket_CollectItem.cpp b/source/packets/cPacket_CollectItem.cpp index 466eda6b7..39f4cdde2 100644 --- a/source/packets/cPacket_CollectItem.cpp +++ b/source/packets/cPacket_CollectItem.cpp @@ -1,19 +1,19 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_CollectItem.h" - - - - - -void cPacket_CollectItem::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendInteger(a_Data, m_CollectedID); - AppendInteger(a_Data, m_CollectorID); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_CollectItem.h" + + + + + +void cPacket_CollectItem::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_CollectedID); + AppendInteger(a_Data, m_CollectorID); +} + + + + diff --git a/source/packets/cPacket_CollectItem.h b/source/packets/cPacket_CollectItem.h index b424ab4b7..29ab78ff8 100644 --- a/source/packets/cPacket_CollectItem.h +++ b/source/packets/cPacket_CollectItem.h @@ -1,27 +1,27 @@ -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_CollectItem : public cPacket -{ -public: - cPacket_CollectItem() - : m_CollectedID( 0 ) - , m_CollectorID( 0 ) - { m_PacketID = E_COLLECT_ITEM; } - virtual cPacket* Clone() const { return new cPacket_CollectItem(*this); } - - virtual void Serialize(AString & a_Data) const override; - - int m_CollectedID; - int m_CollectorID; - static const unsigned int c_Size = 1 + 4 + 4; -}; - - - - +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_CollectItem : public cPacket +{ +public: + cPacket_CollectItem() + : m_CollectedID( 0 ) + , m_CollectorID( 0 ) + { m_PacketID = E_COLLECT_ITEM; } + virtual cPacket* Clone() const { return new cPacket_CollectItem(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_CollectedID; + int m_CollectorID; + static const unsigned int c_Size = 1 + 4 + 4; +}; + + + + diff --git a/source/packets/cPacket_CreativeInventoryAction.cpp b/source/packets/cPacket_CreativeInventoryAction.cpp index de6cc1488..46f125701 100644 --- a/source/packets/cPacket_CreativeInventoryAction.cpp +++ b/source/packets/cPacket_CreativeInventoryAction.cpp @@ -1,67 +1,67 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_CreativeInventoryAction.h" -#include "cPacket_ItemData.h" - - - - - -cPacket_CreativeInventoryAction::cPacket_CreativeInventoryAction( const cPacket_CreativeInventoryAction & a_Copy ) -{ - m_PacketID = E_CREATIVE_INVENTORY_ACTION; - m_Slot = a_Copy.m_Slot; - m_ItemID = a_Copy.m_ItemID; - m_Quantity = a_Copy.m_Quantity; - m_Damage = a_Copy.m_Damage; -} - - - - - -int cPacket_CreativeInventoryAction::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadShort, m_Slot, TotalBytes); - - cPacket_ItemData Item; - int res = Item.Parse(a_Data + TotalBytes, a_Size - TotalBytes); - if (res < 0) - { - return res; - } - TotalBytes += res; - - m_ItemID = Item.m_ItemID; - m_Quantity = Item.m_ItemCount; - m_Damage = Item.m_ItemUses; - - return TotalBytes; -} - - - - - -void cPacket_CreativeInventoryAction::Serialize(AString & a_Data) const -{ - short ItemID = m_ItemID; - ASSERT(ItemID >= -1); // Check validity of packets in debug runtime - if (ItemID <= 0) - { - ItemID = -1; - // Fix, to make sure no invalid values are sent. - // WARNING: HERE ITS -1, BUT IN NAMED ENTITY SPAWN PACKET ITS 0 !! - } - - AppendByte (a_Data, m_PacketID); - AppendShort (a_Data, m_Slot); - - cPacket_ItemData::AppendItem(a_Data, ItemID, m_Quantity, m_Damage); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_CreativeInventoryAction.h" +#include "cPacket_ItemData.h" + + + + + +cPacket_CreativeInventoryAction::cPacket_CreativeInventoryAction( const cPacket_CreativeInventoryAction & a_Copy ) +{ + m_PacketID = E_CREATIVE_INVENTORY_ACTION; + m_Slot = a_Copy.m_Slot; + m_ItemID = a_Copy.m_ItemID; + m_Quantity = a_Copy.m_Quantity; + m_Damage = a_Copy.m_Damage; +} + + + + + +int cPacket_CreativeInventoryAction::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadShort, m_Slot, TotalBytes); + + cPacket_ItemData Item; + int res = Item.Parse(a_Data + TotalBytes, a_Size - TotalBytes); + if (res < 0) + { + return res; + } + TotalBytes += res; + + m_ItemID = Item.m_ItemID; + m_Quantity = Item.m_ItemCount; + m_Damage = Item.m_ItemUses; + + return TotalBytes; +} + + + + + +void cPacket_CreativeInventoryAction::Serialize(AString & a_Data) const +{ + short ItemID = m_ItemID; + ASSERT(ItemID >= -1); // Check validity of packets in debug runtime + if (ItemID <= 0) + { + ItemID = -1; + // Fix, to make sure no invalid values are sent. + // WARNING: HERE ITS -1, BUT IN NAMED ENTITY SPAWN PACKET ITS 0 !! + } + + AppendByte (a_Data, m_PacketID); + AppendShort (a_Data, m_Slot); + + cPacket_ItemData::AppendItem(a_Data, ItemID, m_Quantity, m_Damage); +} + + + + diff --git a/source/packets/cPacket_DestroyEntity.cpp b/source/packets/cPacket_DestroyEntity.cpp index cd41b380b..d7e1d085b 100644 --- a/source/packets/cPacket_DestroyEntity.cpp +++ b/source/packets/cPacket_DestroyEntity.cpp @@ -1,30 +1,30 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_DestroyEntity.h" -#include "../cEntity.h" - - - - - -cPacket_DestroyEntity::cPacket_DestroyEntity(cEntity* a_Entity) -{ - m_PacketID = E_DESTROY_ENT; - - m_UniqueID = a_Entity->GetUniqueID(); -} - - - - - -void cPacket_DestroyEntity::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendInteger(a_Data, m_UniqueID); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_DestroyEntity.h" +#include "../cEntity.h" + + + + + +cPacket_DestroyEntity::cPacket_DestroyEntity(cEntity* a_Entity) +{ + m_PacketID = E_DESTROY_ENT; + + m_UniqueID = a_Entity->GetUniqueID(); +} + + + + + +void cPacket_DestroyEntity::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_UniqueID); +} + + + + diff --git a/source/packets/cPacket_DestroyEntity.h b/source/packets/cPacket_DestroyEntity.h index 5f2314e55..b4146e971 100644 --- a/source/packets/cPacket_DestroyEntity.h +++ b/source/packets/cPacket_DestroyEntity.h @@ -1,33 +1,33 @@ -#pragma once - -#include "cPacket.h" - - - - - -class cEntity; - - - - - -class cPacket_DestroyEntity : public cPacket -{ -public: - cPacket_DestroyEntity() - : m_UniqueID( 0 ) - { m_PacketID = E_DESTROY_ENT; } - cPacket_DestroyEntity(cEntity* a_Entity); - virtual cPacket* Clone() const { return new cPacket_DestroyEntity(*this); } - - virtual void Serialize(AString & a_Data) const override; - - int m_UniqueID; - - static const unsigned int c_Size = 1 + 4; -}; - - - - +#pragma once + +#include "cPacket.h" + + + + + +class cEntity; + + + + + +class cPacket_DestroyEntity : public cPacket +{ +public: + cPacket_DestroyEntity() + : m_UniqueID( 0 ) + { m_PacketID = E_DESTROY_ENT; } + cPacket_DestroyEntity(cEntity* a_Entity); + virtual cPacket* Clone() const { return new cPacket_DestroyEntity(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_UniqueID; + + static const unsigned int c_Size = 1 + 4; +}; + + + + diff --git a/source/packets/cPacket_Disconnect.cpp b/source/packets/cPacket_Disconnect.cpp index 82342c303..0ddad3744 100644 --- a/source/packets/cPacket_Disconnect.cpp +++ b/source/packets/cPacket_Disconnect.cpp @@ -1,29 +1,29 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_Disconnect.h" - - - - - -int cPacket_Disconnect::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadString16, m_Reason, TotalBytes); - return TotalBytes; -} - - - - - -void cPacket_Disconnect::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendString16(a_Data, m_Reason); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_Disconnect.h" + + + + + +int cPacket_Disconnect::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadString16, m_Reason, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_Disconnect::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendString16(a_Data, m_Reason); +} + + + + diff --git a/source/packets/cPacket_Disconnect.h b/source/packets/cPacket_Disconnect.h index ccb3811b5..e91a09980 100644 --- a/source/packets/cPacket_Disconnect.h +++ b/source/packets/cPacket_Disconnect.h @@ -1,26 +1,26 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_Disconnect : public cPacket -{ -public: - cPacket_Disconnect() { m_PacketID = E_DISCONNECT; } - cPacket_Disconnect(const AString & a_Reason) { m_PacketID = E_DISCONNECT; m_Reason = a_Reason; } - virtual cPacket* Clone() const { return new cPacket_Disconnect(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - AString m_Reason; - static const unsigned int c_Size = 3; // Minimum size -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_Disconnect : public cPacket +{ +public: + cPacket_Disconnect() { m_PacketID = E_DISCONNECT; } + cPacket_Disconnect(const AString & a_Reason) { m_PacketID = E_DISCONNECT; m_Reason = a_Reason; } + virtual cPacket* Clone() const { return new cPacket_Disconnect(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + AString m_Reason; + static const unsigned int c_Size = 3; // Minimum size +}; + + + + diff --git a/source/packets/cPacket_EntityEquipment.cpp b/source/packets/cPacket_EntityEquipment.cpp index a89cb9724..08bf30a6e 100644 --- a/source/packets/cPacket_EntityEquipment.cpp +++ b/source/packets/cPacket_EntityEquipment.cpp @@ -1,48 +1,48 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_EntityEquipment.h" - - - - - -cPacket_EntityEquipment::cPacket_EntityEquipment( const cPacket_EntityEquipment & a_Copy ) -{ - m_PacketID = E_ENTITY_EQUIPMENT; - m_UniqueID = a_Copy.m_UniqueID; - m_Slot = a_Copy.m_Slot; - m_ItemID = a_Copy.m_ItemID; - m_Short = 0; -} - - - - - -int cPacket_EntityEquipment::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadInteger, m_UniqueID, TotalBytes); - HANDLE_PACKET_READ(ReadShort, m_Slot, TotalBytes); - HANDLE_PACKET_READ(ReadShort, m_ItemID, TotalBytes); - HANDLE_PACKET_READ(ReadShort, m_Short, TotalBytes); - return TotalBytes; -} - - - - - -void cPacket_EntityEquipment::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendInteger(a_Data, m_UniqueID); - AppendShort (a_Data, m_Slot); - AppendShort (a_Data, m_ItemID); - AppendShort (a_Data, m_Short); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_EntityEquipment.h" + + + + + +cPacket_EntityEquipment::cPacket_EntityEquipment( const cPacket_EntityEquipment & a_Copy ) +{ + m_PacketID = E_ENTITY_EQUIPMENT; + m_UniqueID = a_Copy.m_UniqueID; + m_Slot = a_Copy.m_Slot; + m_ItemID = a_Copy.m_ItemID; + m_Short = 0; +} + + + + + +int cPacket_EntityEquipment::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadInteger, m_UniqueID, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_Slot, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_ItemID, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_Short, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_EntityEquipment::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_UniqueID); + AppendShort (a_Data, m_Slot); + AppendShort (a_Data, m_ItemID); + AppendShort (a_Data, m_Short); +} + + + + diff --git a/source/packets/cPacket_EntityEquipment.h b/source/packets/cPacket_EntityEquipment.h index 4beda6063..ec09bbf5c 100644 --- a/source/packets/cPacket_EntityEquipment.h +++ b/source/packets/cPacket_EntityEquipment.h @@ -1,34 +1,34 @@ -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_EntityEquipment : public cPacket -{ -public: - cPacket_EntityEquipment() - : m_UniqueID( 0 ) - , m_Slot( 0 ) - , m_ItemID( 0 ) - , m_Short( 0 ) - { m_PacketID = E_ENTITY_EQUIPMENT; m_Short = 0; } - cPacket_EntityEquipment( const cPacket_EntityEquipment & a_Copy ); - virtual cPacket* Clone() const { return new cPacket_EntityEquipment(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - int m_UniqueID; - short m_Slot; // 0 = hold 1-4 = armor - short m_ItemID; - short m_Short; - - static const unsigned int c_Size = 1 + 4 + 2 + 2 + 2; -}; - - - - +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_EntityEquipment : public cPacket +{ +public: + cPacket_EntityEquipment() + : m_UniqueID( 0 ) + , m_Slot( 0 ) + , m_ItemID( 0 ) + , m_Short( 0 ) + { m_PacketID = E_ENTITY_EQUIPMENT; m_Short = 0; } + cPacket_EntityEquipment( const cPacket_EntityEquipment & a_Copy ); + virtual cPacket* Clone() const { return new cPacket_EntityEquipment(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + int m_UniqueID; + short m_Slot; // 0 = hold 1-4 = armor + short m_ItemID; + short m_Short; + + static const unsigned int c_Size = 1 + 4 + 2 + 2 + 2; +}; + + + + diff --git a/source/packets/cPacket_EntityLook.cpp b/source/packets/cPacket_EntityLook.cpp index d25f788c0..04fc46d4d 100644 --- a/source/packets/cPacket_EntityLook.cpp +++ b/source/packets/cPacket_EntityLook.cpp @@ -1,64 +1,64 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_EntityLook.h" - -#include "../cEntity.h" - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cPacket_EntityLook: - -cPacket_EntityLook::cPacket_EntityLook(const cEntity & a_Entity) -{ - m_PacketID = E_ENT_LOOK; - - m_UniqueID = a_Entity.GetUniqueID(); - m_Rotation = (char)((a_Entity.GetRotation() / 360.f) * 256); - m_Pitch = (char)((a_Entity.GetPitch() / 360.f) * 256); -} - - - - - -void cPacket_EntityLook::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendInteger(a_Data, m_UniqueID); - AppendByte (a_Data, m_Rotation); - AppendByte (a_Data, m_Pitch); -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cPacket_EntityHeadLook: - -cPacket_EntityHeadLook::cPacket_EntityHeadLook(const cEntity & a_Entity) -{ - m_PacketID = E_ENT_HEAD_LOOK; - - m_UniqueID = a_Entity.GetUniqueID(); - m_HeadYaw = (char)((a_Entity.GetRotation() / 360.f) * 256); -} - - - - - -void cPacket_EntityHeadLook::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendInteger(a_Data, m_UniqueID); - AppendByte (a_Data, m_HeadYaw); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_EntityLook.h" + +#include "../cEntity.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPacket_EntityLook: + +cPacket_EntityLook::cPacket_EntityLook(const cEntity & a_Entity) +{ + m_PacketID = E_ENT_LOOK; + + m_UniqueID = a_Entity.GetUniqueID(); + m_Rotation = (char)((a_Entity.GetRotation() / 360.f) * 256); + m_Pitch = (char)((a_Entity.GetPitch() / 360.f) * 256); +} + + + + + +void cPacket_EntityLook::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_UniqueID); + AppendByte (a_Data, m_Rotation); + AppendByte (a_Data, m_Pitch); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPacket_EntityHeadLook: + +cPacket_EntityHeadLook::cPacket_EntityHeadLook(const cEntity & a_Entity) +{ + m_PacketID = E_ENT_HEAD_LOOK; + + m_UniqueID = a_Entity.GetUniqueID(); + m_HeadYaw = (char)((a_Entity.GetRotation() / 360.f) * 256); +} + + + + + +void cPacket_EntityHeadLook::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_UniqueID); + AppendByte (a_Data, m_HeadYaw); +} + + + + diff --git a/source/packets/cPacket_EntityLook.h b/source/packets/cPacket_EntityLook.h index e4aac18e3..7f2864d46 100644 --- a/source/packets/cPacket_EntityLook.h +++ b/source/packets/cPacket_EntityLook.h @@ -1,59 +1,59 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cEntity; - - - - - -class cPacket_EntityLook : - public cPacket -{ -public: - cPacket_EntityLook(void) - : m_UniqueID( 0 ) - , m_Rotation( 0 ) - , m_Pitch( 0 ) - { m_PacketID = E_ENT_LOOK; } - cPacket_EntityLook(const cEntity & a_Entity); - virtual cPacket* Clone(void) const { return new cPacket_EntityLook(*this); } - - virtual void Serialize(AString & a_Data) const override; - - int m_UniqueID; - char m_Rotation; - char m_Pitch; -}; - - - - - -class cPacket_EntityHeadLook : - public cPacket -{ -public: - cPacket_EntityHeadLook(void) - : m_UniqueID( 0 ) - , m_HeadYaw( 0 ) - { m_PacketID = E_ENT_LOOK; } - cPacket_EntityHeadLook(const cEntity & a_Entity); - - virtual cPacket * Clone(void) const { return new cPacket_EntityHeadLook(*this); } - - virtual void Serialize(AString & a_Data) const override; - - int m_UniqueID; - char m_HeadYaw; -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cEntity; + + + + + +class cPacket_EntityLook : + public cPacket +{ +public: + cPacket_EntityLook(void) + : m_UniqueID( 0 ) + , m_Rotation( 0 ) + , m_Pitch( 0 ) + { m_PacketID = E_ENT_LOOK; } + cPacket_EntityLook(const cEntity & a_Entity); + virtual cPacket* Clone(void) const { return new cPacket_EntityLook(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_UniqueID; + char m_Rotation; + char m_Pitch; +}; + + + + + +class cPacket_EntityHeadLook : + public cPacket +{ +public: + cPacket_EntityHeadLook(void) + : m_UniqueID( 0 ) + , m_HeadYaw( 0 ) + { m_PacketID = E_ENT_LOOK; } + cPacket_EntityHeadLook(const cEntity & a_Entity); + + virtual cPacket * Clone(void) const { return new cPacket_EntityHeadLook(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_UniqueID; + char m_HeadYaw; +}; + + + + diff --git a/source/packets/cPacket_EntityStatus.cpp b/source/packets/cPacket_EntityStatus.cpp index 0fc6195b3..1ea468a51 100644 --- a/source/packets/cPacket_EntityStatus.cpp +++ b/source/packets/cPacket_EntityStatus.cpp @@ -1,19 +1,19 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_EntityStatus.h" - - - - - -void cPacket_EntityStatus::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendInteger(a_Data, m_UniqueID); - AppendByte (a_Data, m_Status); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_EntityStatus.h" + + + + + +void cPacket_EntityStatus::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_UniqueID); + AppendByte (a_Data, m_Status); +} + + + + diff --git a/source/packets/cPacket_EntityStatus.h b/source/packets/cPacket_EntityStatus.h index a50a25390..ecacd03c5 100644 --- a/source/packets/cPacket_EntityStatus.h +++ b/source/packets/cPacket_EntityStatus.h @@ -1,31 +1,31 @@ -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_EntityStatus : public cPacket -{ -public: - cPacket_EntityStatus() - : m_UniqueID( 0 ) - , m_Status( 0 ) - { m_PacketID = E_ENT_STATUS; } - virtual cPacket* Clone() const { return new cPacket_EntityStatus( *this ); } - - virtual void Serialize(AString & a_Data) const override; - - static const char STATUS_TAKEDAMAGE = 2; - static const char STATUS_DIE = 3; - - int m_UniqueID; - char m_Status; - - static const unsigned int c_Size = 1 + 4 + 1; -}; - - - - +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_EntityStatus : public cPacket +{ +public: + cPacket_EntityStatus() + : m_UniqueID( 0 ) + , m_Status( 0 ) + { m_PacketID = E_ENT_STATUS; } + virtual cPacket* Clone() const { return new cPacket_EntityStatus( *this ); } + + virtual void Serialize(AString & a_Data) const override; + + static const char STATUS_TAKEDAMAGE = 2; + static const char STATUS_DIE = 3; + + int m_UniqueID; + char m_Status; + + static const unsigned int c_Size = 1 + 4 + 1; +}; + + + + diff --git a/source/packets/cPacket_Flying.cpp b/source/packets/cPacket_Flying.cpp index c7916957a..64fbf11ea 100644 --- a/source/packets/cPacket_Flying.cpp +++ b/source/packets/cPacket_Flying.cpp @@ -1,19 +1,19 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_Flying.h" - - - - - -int cPacket_Flying::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes= 0; - HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes); - return TotalBytes; -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_Flying.h" + + + + + +int cPacket_Flying::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes= 0; + HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes); + return TotalBytes; +} + + + + diff --git a/source/packets/cPacket_Flying.h b/source/packets/cPacket_Flying.h index 19b0ee213..2d19820de 100644 --- a/source/packets/cPacket_Flying.h +++ b/source/packets/cPacket_Flying.h @@ -1,27 +1,27 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_Flying : public cPacket -{ -public: - // The BS packet - cPacket_Flying() - : m_bFlying( false ) - { m_PacketID = E_FLYING; } - virtual cPacket* Clone() const { return new cPacket_Flying(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - - bool m_bFlying; - static const unsigned int c_Size = 2; -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_Flying : public cPacket +{ +public: + // The BS packet + cPacket_Flying() + : m_bFlying( false ) + { m_PacketID = E_FLYING; } + virtual cPacket* Clone() const { return new cPacket_Flying(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + + bool m_bFlying; + static const unsigned int c_Size = 2; +}; + + + + diff --git a/source/packets/cPacket_Handshake.cpp b/source/packets/cPacket_Handshake.cpp index 2c4f058e7..737eca330 100644 --- a/source/packets/cPacket_Handshake.cpp +++ b/source/packets/cPacket_Handshake.cpp @@ -1,29 +1,29 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_Handshake.h" - - - - - -int cPacket_Handshake::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadString16, m_Username, TotalBytes); - return TotalBytes; -} - - - - - -void cPacket_Handshake::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendString16(a_Data, m_Username); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_Handshake.h" + + + + + +int cPacket_Handshake::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadString16, m_Username, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_Handshake::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendString16(a_Data, m_Username); +} + + + + diff --git a/source/packets/cPacket_Handshake.h b/source/packets/cPacket_Handshake.h index e66827851..020be9eaf 100644 --- a/source/packets/cPacket_Handshake.h +++ b/source/packets/cPacket_Handshake.h @@ -1,25 +1,25 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_Handshake : public cPacket -{ -public: - cPacket_Handshake() { m_PacketID = E_HANDSHAKE; } - virtual cPacket* Clone() const { return new cPacket_Handshake(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - std::string m_Username; - static const unsigned int c_Size = 3; // Minimal size -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_Handshake : public cPacket +{ +public: + cPacket_Handshake() { m_PacketID = E_HANDSHAKE; } + virtual cPacket* Clone() const { return new cPacket_Handshake(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + std::string m_Username; + static const unsigned int c_Size = 3; // Minimal size +}; + + + + diff --git a/source/packets/cPacket_InventoryProgressBar.cpp b/source/packets/cPacket_InventoryProgressBar.cpp index 9df92b390..61541c8e9 100644 --- a/source/packets/cPacket_InventoryProgressBar.cpp +++ b/source/packets/cPacket_InventoryProgressBar.cpp @@ -1,20 +1,20 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_InventoryProgressBar.h" - - - - - -void cPacket_InventoryProgressBar::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendByte (a_Data, m_WindowID); - AppendShort(a_Data, m_ProgressBar); - AppendShort(a_Data, m_Value); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_InventoryProgressBar.h" + + + + + +void cPacket_InventoryProgressBar::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendByte (a_Data, m_WindowID); + AppendShort(a_Data, m_ProgressBar); + AppendShort(a_Data, m_Value); +} + + + + diff --git a/source/packets/cPacket_InventoryProgressBar.h b/source/packets/cPacket_InventoryProgressBar.h index 70bafcf9e..0aa2fd3a8 100644 --- a/source/packets/cPacket_InventoryProgressBar.h +++ b/source/packets/cPacket_InventoryProgressBar.h @@ -1,31 +1,31 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_InventoryProgressBar : public cPacket -{ -public: - cPacket_InventoryProgressBar() - : m_WindowID( 0 ) - , m_ProgressBar( 0 ) - , m_Value( 0 ) - { m_PacketID = E_INVENTORY_PROGRESS; } - virtual cPacket* Clone() const { return new cPacket_InventoryProgressBar(*this); } - - virtual void Serialize(AString & a_Data) const override; - - char m_WindowID; - short m_ProgressBar; - short m_Value; - - static const unsigned int c_Size = 1 + 1 + 2 + 2; -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_InventoryProgressBar : public cPacket +{ +public: + cPacket_InventoryProgressBar() + : m_WindowID( 0 ) + , m_ProgressBar( 0 ) + , m_Value( 0 ) + { m_PacketID = E_INVENTORY_PROGRESS; } + virtual cPacket* Clone() const { return new cPacket_InventoryProgressBar(*this); } + + virtual void Serialize(AString & a_Data) const override; + + char m_WindowID; + short m_ProgressBar; + short m_Value; + + static const unsigned int c_Size = 1 + 1 + 2 + 2; +}; + + + + diff --git a/source/packets/cPacket_InventorySlot.cpp b/source/packets/cPacket_InventorySlot.cpp index 46f3bf3d4..5bf247541 100644 --- a/source/packets/cPacket_InventorySlot.cpp +++ b/source/packets/cPacket_InventorySlot.cpp @@ -1,23 +1,23 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_InventorySlot.h" -#include "cPacket_WholeInventory.h" -#include "cPacket_ItemData.h" - - - - - -void cPacket_InventorySlot::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendByte (a_Data, m_WindowID); - AppendShort(a_Data, m_SlotNum); - - cPacket_ItemData::AppendItem(a_Data, m_ItemID, m_ItemCount, m_ItemUses); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_InventorySlot.h" +#include "cPacket_WholeInventory.h" +#include "cPacket_ItemData.h" + + + + + +void cPacket_InventorySlot::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendByte (a_Data, m_WindowID); + AppendShort(a_Data, m_SlotNum); + + cPacket_ItemData::AppendItem(a_Data, m_ItemID, m_ItemCount, m_ItemUses); +} + + + + diff --git a/source/packets/cPacket_InventorySlot.h b/source/packets/cPacket_InventorySlot.h index cc04a0bb0..3f9fdc13f 100644 --- a/source/packets/cPacket_InventorySlot.h +++ b/source/packets/cPacket_InventorySlot.h @@ -1,44 +1,44 @@ - -#pragma once - -#include "cPacket.h" - -#include "../BlockID.h" - - - - - -class cPacket_InventorySlot : public cPacket // Set item [S -> C] ? -{ -public: - cPacket_InventorySlot() - : m_WindowID( 0 ) - , m_SlotNum( 0 ) - , m_ItemID( E_ITEM_EMPTY ) - , m_ItemCount( 0 ) - , m_ItemUses( 0 ) - { m_PacketID = E_INVENTORY_SLOT; } - virtual cPacket* Clone() const { return new cPacket_InventorySlot(*this); } - - virtual void Serialize(AString & a_Data) const override; - - char m_WindowID; - short m_SlotNum; // Slot - // 0 = craft result - // 1-4 = crafting table - // 5-8 = armor - // 9-35 = inventory - // 36-44 = Hot bar - - // Below = item - short m_ItemID; // if this is -1 the next stuff dont exist - char m_ItemCount; - short m_ItemUses; - - static const unsigned int c_Size = 1 + 1 + 2; // Minimal size ( +1+1 = max) -}; - - - - + +#pragma once + +#include "cPacket.h" + +#include "../BlockID.h" + + + + + +class cPacket_InventorySlot : public cPacket // Set item [S -> C] ? +{ +public: + cPacket_InventorySlot() + : m_WindowID( 0 ) + , m_SlotNum( 0 ) + , m_ItemID( E_ITEM_EMPTY ) + , m_ItemCount( 0 ) + , m_ItemUses( 0 ) + { m_PacketID = E_INVENTORY_SLOT; } + virtual cPacket* Clone() const { return new cPacket_InventorySlot(*this); } + + virtual void Serialize(AString & a_Data) const override; + + char m_WindowID; + short m_SlotNum; // Slot + // 0 = craft result + // 1-4 = crafting table + // 5-8 = armor + // 9-35 = inventory + // 36-44 = Hot bar + + // Below = item + short m_ItemID; // if this is -1 the next stuff dont exist + char m_ItemCount; + short m_ItemUses; + + static const unsigned int c_Size = 1 + 1 + 2; // Minimal size ( +1+1 = max) +}; + + + + diff --git a/source/packets/cPacket_ItemData.cpp b/source/packets/cPacket_ItemData.cpp index db025a838..0892f433a 100644 --- a/source/packets/cPacket_ItemData.cpp +++ b/source/packets/cPacket_ItemData.cpp @@ -1,81 +1,81 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_ItemData.h" - - - - - -int cPacket_ItemData::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadShort, m_ItemID, TotalBytes); - - if (m_ItemID <= -1) - { - m_ItemCount = 0; - m_ItemUses = 0; - return TotalBytes; - } - - HANDLE_PACKET_READ(ReadByte , m_ItemCount, TotalBytes); - HANDLE_PACKET_READ(ReadShort, m_ItemUses, TotalBytes); - - if (cItem::IsEnchantable((ENUM_ITEM_ID) m_ItemID)) - { - HANDLE_PACKET_READ(ReadShort, m_EnchantNums, TotalBytes); - - if ( m_EnchantNums > -1 ) - { - // TODO: Enchantment not implemented yet! - } - } - return TotalBytes; -} - - - - - -int cPacket_ItemData::GetSize(short a_ItemID) -{ - if(a_ItemID <= -1) - return 2; - if(cItem::IsEnchantable((ENUM_ITEM_ID) a_ItemID)) - return 7; - return 5; -} - - - - - -void cPacket_ItemData::AppendItem(AString & a_Data, const cItem * a_Item) -{ - return AppendItem(a_Data, a_Item->m_ItemID, a_Item->m_ItemCount, a_Item->m_ItemHealth); -} - - - - - -void cPacket_ItemData::AppendItem(AString & a_Data, short a_ItemID, char a_Quantity, short a_Damage) -{ - AppendShort(a_Data, (short) a_ItemID); - if (a_ItemID > -1) - { - AppendByte (a_Data, a_Quantity); - AppendShort(a_Data, a_Damage); - - if (cItem::IsEnchantable((ENUM_ITEM_ID) a_ItemID)) - { - // TODO: Implement enchantments - AppendShort(a_Data, (short) -1); - } - } -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_ItemData.h" + + + + + +int cPacket_ItemData::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadShort, m_ItemID, TotalBytes); + + if (m_ItemID <= -1) + { + m_ItemCount = 0; + m_ItemUses = 0; + return TotalBytes; + } + + HANDLE_PACKET_READ(ReadByte , m_ItemCount, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_ItemUses, TotalBytes); + + if (cItem::IsEnchantable((ENUM_ITEM_ID) m_ItemID)) + { + HANDLE_PACKET_READ(ReadShort, m_EnchantNums, TotalBytes); + + if ( m_EnchantNums > -1 ) + { + // TODO: Enchantment not implemented yet! + } + } + return TotalBytes; +} + + + + + +int cPacket_ItemData::GetSize(short a_ItemID) +{ + if(a_ItemID <= -1) + return 2; + if(cItem::IsEnchantable((ENUM_ITEM_ID) a_ItemID)) + return 7; + return 5; +} + + + + + +void cPacket_ItemData::AppendItem(AString & a_Data, const cItem * a_Item) +{ + return AppendItem(a_Data, a_Item->m_ItemID, a_Item->m_ItemCount, a_Item->m_ItemHealth); +} + + + + + +void cPacket_ItemData::AppendItem(AString & a_Data, short a_ItemID, char a_Quantity, short a_Damage) +{ + AppendShort(a_Data, (short) a_ItemID); + if (a_ItemID > -1) + { + AppendByte (a_Data, a_Quantity); + AppendShort(a_Data, a_Damage); + + if (cItem::IsEnchantable((ENUM_ITEM_ID) a_ItemID)) + { + // TODO: Implement enchantments + AppendShort(a_Data, (short) -1); + } + } +} + + + + diff --git a/source/packets/cPacket_ItemData.h b/source/packets/cPacket_ItemData.h index 6aa1eed69..47878969f 100644 --- a/source/packets/cPacket_ItemData.h +++ b/source/packets/cPacket_ItemData.h @@ -1,35 +1,35 @@ -#pragma once - - -#include "cPacket.h" -#include "../cItem.h" - -class cPacket_ItemData : public cPacket -{ -public: - cPacket_ItemData() - : m_ItemID( 0 ) - , m_ItemCount( 0 ) - , m_ItemUses( 0 ) - , m_EnchantNums(-1) - { - } - - virtual cPacket* Clone() const { return new cPacket_ItemData(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - - static void AppendItem(AString & a_Data, short a_ItemID, char a_Quantity, short a_Damage); - static void AppendItem(AString & a_Data, const cItem * a_Item); - - int GetSize(short a_ItemID); - - // Below = item - short m_ItemID; // if this is -1 the next stuff dont exist - char m_ItemCount; - short m_ItemUses; - - short m_EnchantNums; - - static unsigned int c_Size; // Minimal size ( +1+1 = max) +#pragma once + + +#include "cPacket.h" +#include "../cItem.h" + +class cPacket_ItemData : public cPacket +{ +public: + cPacket_ItemData() + : m_ItemID( 0 ) + , m_ItemCount( 0 ) + , m_ItemUses( 0 ) + , m_EnchantNums(-1) + { + } + + virtual cPacket* Clone() const { return new cPacket_ItemData(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + + static void AppendItem(AString & a_Data, short a_ItemID, char a_Quantity, short a_Damage); + static void AppendItem(AString & a_Data, const cItem * a_Item); + + int GetSize(short a_ItemID); + + // Below = item + short m_ItemID; // if this is -1 the next stuff dont exist + char m_ItemCount; + short m_ItemUses; + + short m_EnchantNums; + + static unsigned int c_Size; // Minimal size ( +1+1 = max) }; \ No newline at end of file diff --git a/source/packets/cPacket_ItemSwitch.cpp b/source/packets/cPacket_ItemSwitch.cpp index 630c2ada4..bd4532938 100644 --- a/source/packets/cPacket_ItemSwitch.cpp +++ b/source/packets/cPacket_ItemSwitch.cpp @@ -1,29 +1,29 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_ItemSwitch.h" - - - - - -int cPacket_ItemSwitch::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadShort, m_SlotNum, TotalBytes); - return TotalBytes; -} - - - - - -void cPacket_ItemSwitch::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendShort(a_Data, m_SlotNum); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_ItemSwitch.h" + + + + + +int cPacket_ItemSwitch::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadShort, m_SlotNum, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_ItemSwitch::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendShort(a_Data, m_SlotNum); +} + + + + diff --git a/source/packets/cPacket_ItemSwitch.h b/source/packets/cPacket_ItemSwitch.h index 00e37b9c8..fb6860624 100644 --- a/source/packets/cPacket_ItemSwitch.h +++ b/source/packets/cPacket_ItemSwitch.h @@ -1,28 +1,28 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_ItemSwitch : public cPacket -{ -public: - cPacket_ItemSwitch() - : m_SlotNum( 0 ) - { m_PacketID = E_ITEM_SWITCH; } - virtual cPacket* Clone() const { return new cPacket_ItemSwitch(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - short m_SlotNum; - - static const unsigned int c_Size = 1 + 2; -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_ItemSwitch : public cPacket +{ +public: + cPacket_ItemSwitch() + : m_SlotNum( 0 ) + { m_PacketID = E_ITEM_SWITCH; } + virtual cPacket* Clone() const { return new cPacket_ItemSwitch(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + short m_SlotNum; + + static const unsigned int c_Size = 1 + 2; +}; + + + + diff --git a/source/packets/cPacket_KeepAlive.cpp b/source/packets/cPacket_KeepAlive.cpp index cf251bf16..cfc6b99b3 100644 --- a/source/packets/cPacket_KeepAlive.cpp +++ b/source/packets/cPacket_KeepAlive.cpp @@ -1,29 +1,29 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_KeepAlive.h" - - - - - -void cPacket_KeepAlive::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendInteger(a_Data, m_KeepAliveID); -} - - - - - -int cPacket_KeepAlive::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadInteger, m_KeepAliveID, TotalBytes); - return TotalBytes; -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_KeepAlive.h" + + + + + +void cPacket_KeepAlive::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_KeepAliveID); +} + + + + + +int cPacket_KeepAlive::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadInteger, m_KeepAliveID, TotalBytes); + return TotalBytes; +} + + + + diff --git a/source/packets/cPacket_KeepAlive.h b/source/packets/cPacket_KeepAlive.h index 3611b6e18..e94ec72a6 100644 --- a/source/packets/cPacket_KeepAlive.h +++ b/source/packets/cPacket_KeepAlive.h @@ -1,27 +1,27 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_KeepAlive : public cPacket -{ -public: - cPacket_KeepAlive() { m_PacketID = E_KEEP_ALIVE; } - cPacket_KeepAlive(int a_PingID) { m_KeepAliveID = a_PingID; } - virtual cPacket* Clone() const { return new cPacket_KeepAlive(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - int m_KeepAliveID; - - static const unsigned int c_Size = 1 + 4; -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_KeepAlive : public cPacket +{ +public: + cPacket_KeepAlive() { m_PacketID = E_KEEP_ALIVE; } + cPacket_KeepAlive(int a_PingID) { m_KeepAliveID = a_PingID; } + virtual cPacket* Clone() const { return new cPacket_KeepAlive(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + int m_KeepAliveID; + + static const unsigned int c_Size = 1 + 4; +}; + + + + diff --git a/source/packets/cPacket_Login.cpp b/source/packets/cPacket_Login.cpp index 588892b3a..2a8ae7135 100644 --- a/source/packets/cPacket_Login.cpp +++ b/source/packets/cPacket_Login.cpp @@ -1,52 +1,52 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_Login.h" - - - - - -const std::string cPacket_Login::LEVEL_TYPE_DEFAULT = "DEFAULT"; -const std::string cPacket_Login::LEVEL_TYPE_SUPERFLAT = "SUPERFLAT"; - - - - - -int cPacket_Login::Parse(const char * a_Data, int a_Size) -{ - //printf("Parse: NEW Login\n"); - int TotalBytes = 0; - m_Username.clear(); - HANDLE_PACKET_READ(ReadInteger, m_ProtocolVersion, TotalBytes); - HANDLE_PACKET_READ(ReadString16, m_Username, TotalBytes); - HANDLE_PACKET_READ(ReadString16, m_LevelType, TotalBytes); - HANDLE_PACKET_READ(ReadInteger, m_ServerMode, TotalBytes); - HANDLE_PACKET_READ(ReadInteger, m_Dimension, TotalBytes); - HANDLE_PACKET_READ(ReadByte, m_Difficulty, TotalBytes); - HANDLE_PACKET_READ(ReadByte, m_WorldHeight, TotalBytes); - HANDLE_PACKET_READ(ReadByte, m_MaxPlayers, TotalBytes); - return TotalBytes; -} - - - - - -void cPacket_Login::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendInteger (a_Data, m_ProtocolVersion); - AppendString16(a_Data, m_Username); - AppendString16(a_Data, m_LevelType); - AppendInteger (a_Data, m_ServerMode); - AppendInteger (a_Data, m_Dimension); - AppendByte (a_Data, m_Difficulty); - AppendByte (a_Data, m_WorldHeight); - AppendByte (a_Data, m_MaxPlayers); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_Login.h" + + + + + +const std::string cPacket_Login::LEVEL_TYPE_DEFAULT = "DEFAULT"; +const std::string cPacket_Login::LEVEL_TYPE_SUPERFLAT = "SUPERFLAT"; + + + + + +int cPacket_Login::Parse(const char * a_Data, int a_Size) +{ + //printf("Parse: NEW Login\n"); + int TotalBytes = 0; + m_Username.clear(); + HANDLE_PACKET_READ(ReadInteger, m_ProtocolVersion, TotalBytes); + HANDLE_PACKET_READ(ReadString16, m_Username, TotalBytes); + HANDLE_PACKET_READ(ReadString16, m_LevelType, TotalBytes); + HANDLE_PACKET_READ(ReadInteger, m_ServerMode, TotalBytes); + HANDLE_PACKET_READ(ReadInteger, m_Dimension, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_Difficulty, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_WorldHeight, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_MaxPlayers, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_Login::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger (a_Data, m_ProtocolVersion); + AppendString16(a_Data, m_Username); + AppendString16(a_Data, m_LevelType); + AppendInteger (a_Data, m_ServerMode); + AppendInteger (a_Data, m_Dimension); + AppendByte (a_Data, m_Difficulty); + AppendByte (a_Data, m_WorldHeight); + AppendByte (a_Data, m_MaxPlayers); +} + + + + diff --git a/source/packets/cPacket_Login.h b/source/packets/cPacket_Login.h index 86666090c..b9769fdec 100644 --- a/source/packets/cPacket_Login.h +++ b/source/packets/cPacket_Login.h @@ -1,42 +1,42 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_Login : public cPacket //tolua_export -{ //tolua_export -public: - cPacket_Login() - : m_ProtocolVersion( 0 ) - , m_ServerMode( 0 ) - , m_Dimension( 0 ) - , m_Difficulty( 0 ) - , m_WorldHeight( 0 ) - , m_MaxPlayers( 0 ) - , m_LevelType( LEVEL_TYPE_DEFAULT ) - { m_PacketID = E_LOGIN; } - virtual cPacket* Clone() const { return new cPacket_Login(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - int m_ProtocolVersion; //tolua_export - AString m_Username; //tolua_export - AString m_LevelType; //tolua_export - int m_ServerMode; //tolua_export - int m_Dimension; - char m_Difficulty; //tolua_export - unsigned char m_WorldHeight; //tolua_export - unsigned char m_MaxPlayers; //tolua_export - - static const AString LEVEL_TYPE_DEFAULT; - static const AString LEVEL_TYPE_SUPERFLAT; -}; //tolua_export - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_Login : public cPacket //tolua_export +{ //tolua_export +public: + cPacket_Login() + : m_ProtocolVersion( 0 ) + , m_ServerMode( 0 ) + , m_Dimension( 0 ) + , m_Difficulty( 0 ) + , m_WorldHeight( 0 ) + , m_MaxPlayers( 0 ) + , m_LevelType( LEVEL_TYPE_DEFAULT ) + { m_PacketID = E_LOGIN; } + virtual cPacket* Clone() const { return new cPacket_Login(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + int m_ProtocolVersion; //tolua_export + AString m_Username; //tolua_export + AString m_LevelType; //tolua_export + int m_ServerMode; //tolua_export + int m_Dimension; + char m_Difficulty; //tolua_export + unsigned char m_WorldHeight; //tolua_export + unsigned char m_MaxPlayers; //tolua_export + + static const AString LEVEL_TYPE_DEFAULT; + static const AString LEVEL_TYPE_SUPERFLAT; +}; //tolua_export + + + + diff --git a/source/packets/cPacket_MapChunk.cpp b/source/packets/cPacket_MapChunk.cpp index 279dee808..21c62da45 100644 --- a/source/packets/cPacket_MapChunk.cpp +++ b/source/packets/cPacket_MapChunk.cpp @@ -1,154 +1,154 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_MapChunk.h" -#include "../ChunkDef.h" - -#include "zlib.h" - - - - - -cPacket_MapChunk::~cPacket_MapChunk() -{ - delete [] m_CompressedData; -} - - - - - -cPacket_MapChunk::cPacket_MapChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const BLOCKTYPE * a_BlockData, const unsigned char * a_BiomeData) -{ - m_PacketID = E_MAP_CHUNK; - - m_PosX = a_ChunkX; // Chunk coordinates now, instead of block coordinates - m_PosZ = a_ChunkZ; - - m_bContiguous = true; // false = no biome data, true = with biome data - m_BitMap1 = 0; - m_BitMap2 = 0; - - m_UnusedInt = 0; - - - const int BlockDataSize = (cChunkDef::Height / 16) * (4096 + 2048 + 2048 + 2048); - const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width; - char AllData [ BlockDataSize + BiomeDataSize ]; - -#if AXIS_ORDER == AXIS_ORDER_YZX - memset( AllData, 0, BlockDataSize ); - - unsigned int iterator = 0; - for ( int i = 0; i < (cChunkDef::Height / 16); ++i ) - { - m_BitMap1 |= (1 << i); // This tells what chunks are sent. Use this to NOT send air only chunks (right now everything is sent) - for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z ) for( int x = 0; x < 16; ++x ) - { - int idx = cChunk::MakeIndex(x, y + i * 16, z); - AllData[iterator] = a_BlockData[idx]; - ++iterator; - } // for y, z, x - } - - // Send block metadata: - char * Meta = a_BlockData + cChunkDef::NumBlocks; - for ( int i = 0; i < (cChunkDef::Height / 16); ++i ) - { - for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z ) - { - for ( int x = 0; x < 8; ++x ) - { - AllData[iterator] = cChunk::GetNibble(Meta, x * 2 + 0, y + i * 16, z) | (cChunk::GetNibble(Meta, x * 2 + 1, y + i * 16, z ) << 4); - ++iterator; - } // for x - } // for y, z - } - - // Send block light: - char * Light = Meta + cChunkDef::NumBlocks / 2; - for ( int i = 0; i < (cChunkDef::Height / 16); ++i ) - { - for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z ) - { - for ( int x = 0; x < 8; ++x ) - { - AllData[iterator] = cChunk::GetNibble(Light, x * 2 + 0, y + i * 16, z ) | (cChunk::GetNibble(Light, x * 2 + 1, y + i * 16, z ) << 4); - ++iterator; - } - } - } - - // Send sky light: - char * SkyLight = Light + cChunkDef::NumBlocks / 2; - for( int i = 0; i < (cChunkDef::Height/16); ++i ) - { - for( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z ) - { - for( int x = 0; x < 8; ++x ) - { - AllData[iterator] = cChunk::GetNibble(SkyLight, x * 2 + 0, y + i * 16, z ) | (cChunk::GetNibble(SkyLight, x * 2 + 1, y + i * 16, z ) << 4); - ++iterator; - } - } - } - memcpy(AllData + BlockDataSize, a_BiomeData, BiomeDataSize); -#elif AXIS_ORDER == AXIS_ORDER_XZY - for ( int i = 0; i < 16; ++i ) - { - m_BitMap1 |= (1 << i); - } - memcpy(AllData, a_BlockData, BlockDataSize); - memcpy(AllData + BlockDataSize, a_BiomeData, BiomeDataSize); -#endif // AXIS_ORDER - - uLongf CompressedSize = compressBound( sizeof(AllData) ); - char * CompressedBlockData = new char[CompressedSize]; - - compress2( (Bytef*)CompressedBlockData, &CompressedSize, (const Bytef*)AllData, sizeof(AllData), Z_DEFAULT_COMPRESSION); - - m_CompressedData = CompressedBlockData; - m_CompressedSize = CompressedSize; -} - - - - - -cPacket_MapChunk::cPacket_MapChunk( const cPacket_MapChunk & a_Copy ) -{ - m_PacketID = E_MAP_CHUNK; - - m_PosX = a_Copy.m_PosX; - m_PosZ = a_Copy.m_PosZ; - m_bContiguous = a_Copy.m_bContiguous; - m_BitMap1 = a_Copy.m_BitMap1; - m_BitMap2 = a_Copy.m_BitMap2; - - m_CompressedSize = a_Copy.m_CompressedSize; - m_CompressedData = new char[m_CompressedSize]; - memcpy( m_CompressedData, a_Copy.m_CompressedData, m_CompressedSize ); -} - - - - - -void cPacket_MapChunk::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - - AppendInteger(a_Data, m_PosX); - AppendInteger(a_Data, m_PosZ); - AppendBool (a_Data, m_bContiguous); - AppendShort (a_Data, m_BitMap1); - AppendShort (a_Data, m_BitMap2); - AppendInteger(a_Data, m_CompressedSize); - AppendInteger(a_Data, m_UnusedInt); - AppendData (a_Data, m_CompressedData, m_CompressedSize); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_MapChunk.h" +#include "../ChunkDef.h" + +#include "zlib.h" + + + + + +cPacket_MapChunk::~cPacket_MapChunk() +{ + delete [] m_CompressedData; +} + + + + + +cPacket_MapChunk::cPacket_MapChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const BLOCKTYPE * a_BlockData, const unsigned char * a_BiomeData) +{ + m_PacketID = E_MAP_CHUNK; + + m_PosX = a_ChunkX; // Chunk coordinates now, instead of block coordinates + m_PosZ = a_ChunkZ; + + m_bContiguous = true; // false = no biome data, true = with biome data + m_BitMap1 = 0; + m_BitMap2 = 0; + + m_UnusedInt = 0; + + + const int BlockDataSize = (cChunkDef::Height / 16) * (4096 + 2048 + 2048 + 2048); + const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width; + char AllData [ BlockDataSize + BiomeDataSize ]; + +#if AXIS_ORDER == AXIS_ORDER_YZX + memset( AllData, 0, BlockDataSize ); + + unsigned int iterator = 0; + for ( int i = 0; i < (cChunkDef::Height / 16); ++i ) + { + m_BitMap1 |= (1 << i); // This tells what chunks are sent. Use this to NOT send air only chunks (right now everything is sent) + for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z ) for( int x = 0; x < 16; ++x ) + { + int idx = cChunk::MakeIndex(x, y + i * 16, z); + AllData[iterator] = a_BlockData[idx]; + ++iterator; + } // for y, z, x + } + + // Send block metadata: + char * Meta = a_BlockData + cChunkDef::NumBlocks; + for ( int i = 0; i < (cChunkDef::Height / 16); ++i ) + { + for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z ) + { + for ( int x = 0; x < 8; ++x ) + { + AllData[iterator] = cChunk::GetNibble(Meta, x * 2 + 0, y + i * 16, z) | (cChunk::GetNibble(Meta, x * 2 + 1, y + i * 16, z ) << 4); + ++iterator; + } // for x + } // for y, z + } + + // Send block light: + char * Light = Meta + cChunkDef::NumBlocks / 2; + for ( int i = 0; i < (cChunkDef::Height / 16); ++i ) + { + for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z ) + { + for ( int x = 0; x < 8; ++x ) + { + AllData[iterator] = cChunk::GetNibble(Light, x * 2 + 0, y + i * 16, z ) | (cChunk::GetNibble(Light, x * 2 + 1, y + i * 16, z ) << 4); + ++iterator; + } + } + } + + // Send sky light: + char * SkyLight = Light + cChunkDef::NumBlocks / 2; + for( int i = 0; i < (cChunkDef::Height/16); ++i ) + { + for( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z ) + { + for( int x = 0; x < 8; ++x ) + { + AllData[iterator] = cChunk::GetNibble(SkyLight, x * 2 + 0, y + i * 16, z ) | (cChunk::GetNibble(SkyLight, x * 2 + 1, y + i * 16, z ) << 4); + ++iterator; + } + } + } + memcpy(AllData + BlockDataSize, a_BiomeData, BiomeDataSize); +#elif AXIS_ORDER == AXIS_ORDER_XZY + for ( int i = 0; i < 16; ++i ) + { + m_BitMap1 |= (1 << i); + } + memcpy(AllData, a_BlockData, BlockDataSize); + memcpy(AllData + BlockDataSize, a_BiomeData, BiomeDataSize); +#endif // AXIS_ORDER + + uLongf CompressedSize = compressBound( sizeof(AllData) ); + char * CompressedBlockData = new char[CompressedSize]; + + compress2( (Bytef*)CompressedBlockData, &CompressedSize, (const Bytef*)AllData, sizeof(AllData), Z_DEFAULT_COMPRESSION); + + m_CompressedData = CompressedBlockData; + m_CompressedSize = CompressedSize; +} + + + + + +cPacket_MapChunk::cPacket_MapChunk( const cPacket_MapChunk & a_Copy ) +{ + m_PacketID = E_MAP_CHUNK; + + m_PosX = a_Copy.m_PosX; + m_PosZ = a_Copy.m_PosZ; + m_bContiguous = a_Copy.m_bContiguous; + m_BitMap1 = a_Copy.m_BitMap1; + m_BitMap2 = a_Copy.m_BitMap2; + + m_CompressedSize = a_Copy.m_CompressedSize; + m_CompressedData = new char[m_CompressedSize]; + memcpy( m_CompressedData, a_Copy.m_CompressedData, m_CompressedSize ); +} + + + + + +void cPacket_MapChunk::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + + AppendInteger(a_Data, m_PosX); + AppendInteger(a_Data, m_PosZ); + AppendBool (a_Data, m_bContiguous); + AppendShort (a_Data, m_BitMap1); + AppendShort (a_Data, m_BitMap2); + AppendInteger(a_Data, m_CompressedSize); + AppendInteger(a_Data, m_UnusedInt); + AppendData (a_Data, m_CompressedData, m_CompressedSize); +} + + + + diff --git a/source/packets/cPacket_MapChunk.h b/source/packets/cPacket_MapChunk.h index 0daf5af34..ec2f68632 100644 --- a/source/packets/cPacket_MapChunk.h +++ b/source/packets/cPacket_MapChunk.h @@ -1,45 +1,45 @@ - -#pragma once - -#include "cPacket.h" -#include "../ChunkDef.h" - - - - - -class cPacket_MapChunk : - public cPacket -{ -public: - cPacket_MapChunk() - : m_PosX( 0 ) - , m_PosZ( 0 ) - , m_bContiguous( false ) - , m_BitMap1( 0 ) - , m_BitMap2( 0 ) - , m_CompressedSize( 0 ) - , m_UnusedInt( 0 ) - , m_CompressedData( NULL ) - { m_PacketID = E_MAP_CHUNK; } - - cPacket_MapChunk( const cPacket_MapChunk & a_Copy ); - cPacket_MapChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const BLOCKTYPE * a_BlockData, const unsigned char * a_BiomeData); - ~cPacket_MapChunk(); - virtual cPacket* Clone() const { return new cPacket_MapChunk(*this); } - - virtual void Serialize(AString & a_Data) const override; - - int m_PosX; - int m_PosZ; - bool m_bContiguous; - short m_BitMap1; - short m_BitMap2; - int m_CompressedSize; - int m_UnusedInt; - char * m_CompressedData; -}; - - - - + +#pragma once + +#include "cPacket.h" +#include "../ChunkDef.h" + + + + + +class cPacket_MapChunk : + public cPacket +{ +public: + cPacket_MapChunk() + : m_PosX( 0 ) + , m_PosZ( 0 ) + , m_bContiguous( false ) + , m_BitMap1( 0 ) + , m_BitMap2( 0 ) + , m_CompressedSize( 0 ) + , m_UnusedInt( 0 ) + , m_CompressedData( NULL ) + { m_PacketID = E_MAP_CHUNK; } + + cPacket_MapChunk( const cPacket_MapChunk & a_Copy ); + cPacket_MapChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const BLOCKTYPE * a_BlockData, const unsigned char * a_BiomeData); + ~cPacket_MapChunk(); + virtual cPacket* Clone() const { return new cPacket_MapChunk(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_PosX; + int m_PosZ; + bool m_bContiguous; + short m_BitMap1; + short m_BitMap2; + int m_CompressedSize; + int m_UnusedInt; + char * m_CompressedData; +}; + + + + diff --git a/source/packets/cPacket_MultiBlock.cpp b/source/packets/cPacket_MultiBlock.cpp index cfa13c4d4..9ae175508 100644 --- a/source/packets/cPacket_MultiBlock.cpp +++ b/source/packets/cPacket_MultiBlock.cpp @@ -1,50 +1,50 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_MultiBlock.h" - - - - - -cPacket_MultiBlock::cPacket_MultiBlock( const cPacket_MultiBlock & a_Copy ) -{ - m_PacketID = E_MULTI_BLOCK; - m_ChunkX = a_Copy.m_ChunkX; - m_ChunkZ = a_Copy.m_ChunkZ; - m_NumBlocks = a_Copy.m_NumBlocks; - m_DataSize = a_Copy.m_DataSize; - m_Data = new sBlockChange[m_NumBlocks]; - memcpy( m_Data, a_Copy.m_Data, sizeof(sBlockChange)*m_NumBlocks ); -} - - - - - -cPacket_MultiBlock::~cPacket_MultiBlock() -{ - delete [] m_Data; -} - - - - - -void cPacket_MultiBlock::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendInteger(a_Data, m_ChunkX); - AppendInteger(a_Data, m_ChunkZ); - AppendShort (a_Data, m_NumBlocks); - - AppendInteger(a_Data, m_DataSize); - for( int i = 0; i < m_NumBlocks; ++i ) - { - AppendInteger(a_Data, m_Data[i].Data); - } -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_MultiBlock.h" + + + + + +cPacket_MultiBlock::cPacket_MultiBlock( const cPacket_MultiBlock & a_Copy ) +{ + m_PacketID = E_MULTI_BLOCK; + m_ChunkX = a_Copy.m_ChunkX; + m_ChunkZ = a_Copy.m_ChunkZ; + m_NumBlocks = a_Copy.m_NumBlocks; + m_DataSize = a_Copy.m_DataSize; + m_Data = new sBlockChange[m_NumBlocks]; + memcpy( m_Data, a_Copy.m_Data, sizeof(sBlockChange)*m_NumBlocks ); +} + + + + + +cPacket_MultiBlock::~cPacket_MultiBlock() +{ + delete [] m_Data; +} + + + + + +void cPacket_MultiBlock::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_ChunkX); + AppendInteger(a_Data, m_ChunkZ); + AppendShort (a_Data, m_NumBlocks); + + AppendInteger(a_Data, m_DataSize); + for( int i = 0; i < m_NumBlocks; ++i ) + { + AppendInteger(a_Data, m_Data[i].Data); + } +} + + + + diff --git a/source/packets/cPacket_MultiBlock.h b/source/packets/cPacket_MultiBlock.h index 31cb96628..af3d24267 100644 --- a/source/packets/cPacket_MultiBlock.h +++ b/source/packets/cPacket_MultiBlock.h @@ -1,47 +1,47 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_MultiBlock : public cPacket -{ -public: - struct sBlockChange - { - sBlockChange() - : Data( 0 ) - {} - unsigned int Data; -// short Data; // 4bits metadata ... 12bits block ID -// short Coords; // 8bits Y ... 4bits Z ... 4bits X - }; - - cPacket_MultiBlock() - : m_ChunkX( 0 ) - , m_ChunkZ( 0 ) - , m_NumBlocks( 0 ) - , m_DataSize( 0 ) - , m_Data( NULL ) - { m_PacketID = E_MULTI_BLOCK; } - - cPacket_MultiBlock( const cPacket_MultiBlock & a_Copy ); - ~cPacket_MultiBlock(); - virtual cPacket* Clone() const { return new cPacket_MultiBlock(*this); } - - virtual void Serialize(AString & a_Data) const override; - - int m_ChunkX; - int m_ChunkZ; - short m_NumBlocks; - - int m_DataSize; // Should be 4 * m_NumBlocks ?? - sBlockChange * m_Data; -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_MultiBlock : public cPacket +{ +public: + struct sBlockChange + { + sBlockChange() + : Data( 0 ) + {} + unsigned int Data; +// short Data; // 4bits metadata ... 12bits block ID +// short Coords; // 8bits Y ... 4bits Z ... 4bits X + }; + + cPacket_MultiBlock() + : m_ChunkX( 0 ) + , m_ChunkZ( 0 ) + , m_NumBlocks( 0 ) + , m_DataSize( 0 ) + , m_Data( NULL ) + { m_PacketID = E_MULTI_BLOCK; } + + cPacket_MultiBlock( const cPacket_MultiBlock & a_Copy ); + ~cPacket_MultiBlock(); + virtual cPacket* Clone() const { return new cPacket_MultiBlock(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_ChunkX; + int m_ChunkZ; + short m_NumBlocks; + + int m_DataSize; // Should be 4 * m_NumBlocks ?? + sBlockChange * m_Data; +}; + + + + diff --git a/source/packets/cPacket_NamedEntitySpawn.cpp b/source/packets/cPacket_NamedEntitySpawn.cpp index 8b4b912d8..798376372 100644 --- a/source/packets/cPacket_NamedEntitySpawn.cpp +++ b/source/packets/cPacket_NamedEntitySpawn.cpp @@ -1,34 +1,34 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_NamedEntitySpawn.h" - - - - - -void cPacket_NamedEntitySpawn::Serialize(AString & a_Data) const -{ - short CurrentItem = m_CurrentItem; - ASSERT(CurrentItem >= 0); - if (CurrentItem <= 0) - { - CurrentItem = 0; - // Fix, to make sure no invalid values are sent. - // WARNING: HERE ITS 0, BUT IN EQUIP PACKET ITS -1 !! - } - - AppendByte (a_Data, m_PacketID); - AppendInteger (a_Data, m_UniqueID); - AppendString16(a_Data, m_PlayerName); - AppendInteger (a_Data, m_PosX); - AppendInteger (a_Data, m_PosY); - AppendInteger (a_Data, m_PosZ); - AppendByte (a_Data, m_Rotation); - AppendByte (a_Data, m_Pitch); - AppendShort (a_Data, CurrentItem); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_NamedEntitySpawn.h" + + + + + +void cPacket_NamedEntitySpawn::Serialize(AString & a_Data) const +{ + short CurrentItem = m_CurrentItem; + ASSERT(CurrentItem >= 0); + if (CurrentItem <= 0) + { + CurrentItem = 0; + // Fix, to make sure no invalid values are sent. + // WARNING: HERE ITS 0, BUT IN EQUIP PACKET ITS -1 !! + } + + AppendByte (a_Data, m_PacketID); + AppendInteger (a_Data, m_UniqueID); + AppendString16(a_Data, m_PlayerName); + AppendInteger (a_Data, m_PosX); + AppendInteger (a_Data, m_PosY); + AppendInteger (a_Data, m_PosZ); + AppendByte (a_Data, m_Rotation); + AppendByte (a_Data, m_Pitch); + AppendShort (a_Data, CurrentItem); +} + + + + diff --git a/source/packets/cPacket_NamedEntitySpawn.h b/source/packets/cPacket_NamedEntitySpawn.h index ceec10c35..365d28c37 100644 --- a/source/packets/cPacket_NamedEntitySpawn.h +++ b/source/packets/cPacket_NamedEntitySpawn.h @@ -1,40 +1,40 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_NamedEntitySpawn : public cPacket -{ -public: - cPacket_NamedEntitySpawn() - : m_UniqueID( 0 ) - , m_PosX( 0 ) - , m_PosY( 0 ) - , m_PosZ( 0 ) - , m_Rotation( 0 ) - , m_Pitch( 0 ) - , m_CurrentItem( 0 ) - { m_PacketID = E_NAMED_ENTITY_SPAWN; } - virtual cPacket* Clone() const { return new cPacket_NamedEntitySpawn(*this); } - - virtual void Serialize(AString & a_Data) const override; - - int m_UniqueID; - AString m_PlayerName; - int m_PosX; // Pixel position, devide by 32 for block position - int m_PosY; - int m_PosZ; - char m_Rotation; - char m_Pitch; - short m_CurrentItem; - - static const unsigned int c_Size = 1 + 4 + 2 + 4 + 4 + 4 + 1 + 1 + 2; // Minimum size -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_NamedEntitySpawn : public cPacket +{ +public: + cPacket_NamedEntitySpawn() + : m_UniqueID( 0 ) + , m_PosX( 0 ) + , m_PosY( 0 ) + , m_PosZ( 0 ) + , m_Rotation( 0 ) + , m_Pitch( 0 ) + , m_CurrentItem( 0 ) + { m_PacketID = E_NAMED_ENTITY_SPAWN; } + virtual cPacket* Clone() const { return new cPacket_NamedEntitySpawn(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_UniqueID; + AString m_PlayerName; + int m_PosX; // Pixel position, devide by 32 for block position + int m_PosY; + int m_PosZ; + char m_Rotation; + char m_Pitch; + short m_CurrentItem; + + static const unsigned int c_Size = 1 + 4 + 2 + 4 + 4 + 4 + 1 + 1 + 2; // Minimum size +}; + + + + diff --git a/source/packets/cPacket_PickupSpawn.cpp b/source/packets/cPacket_PickupSpawn.cpp index d8970650d..a1a60947d 100644 --- a/source/packets/cPacket_PickupSpawn.cpp +++ b/source/packets/cPacket_PickupSpawn.cpp @@ -1,47 +1,47 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_PickupSpawn.h" - - - - - -int cPacket_PickupSpawn::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadInteger, m_UniqueID, TotalBytes); - HANDLE_PACKET_READ(ReadShort, m_Item, TotalBytes); - HANDLE_PACKET_READ(ReadByte, m_Count, TotalBytes); - HANDLE_PACKET_READ(ReadShort, m_Health, TotalBytes); - HANDLE_PACKET_READ(ReadInteger, m_PosX, TotalBytes); - HANDLE_PACKET_READ(ReadInteger, m_PosY, TotalBytes); - HANDLE_PACKET_READ(ReadInteger, m_PosZ, TotalBytes); - HANDLE_PACKET_READ(ReadByte, m_Rotation, TotalBytes); - HANDLE_PACKET_READ(ReadByte, m_Pitch, TotalBytes); - HANDLE_PACKET_READ(ReadByte, m_Roll, TotalBytes); - return TotalBytes; -} - - - - - -void cPacket_PickupSpawn::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendInteger(a_Data, m_UniqueID); - AppendShort (a_Data, m_Item); - AppendByte (a_Data, m_Count); - AppendShort (a_Data, m_Health); - AppendInteger(a_Data, m_PosX); - AppendInteger(a_Data, m_PosY); - AppendInteger(a_Data, m_PosZ); - AppendByte (a_Data, m_Rotation); - AppendByte (a_Data, m_Pitch); - AppendByte (a_Data, m_Roll); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_PickupSpawn.h" + + + + + +int cPacket_PickupSpawn::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadInteger, m_UniqueID, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_Item, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_Count, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_Health, TotalBytes); + HANDLE_PACKET_READ(ReadInteger, m_PosX, TotalBytes); + HANDLE_PACKET_READ(ReadInteger, m_PosY, TotalBytes); + HANDLE_PACKET_READ(ReadInteger, m_PosZ, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_Rotation, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_Pitch, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_Roll, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_PickupSpawn::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_UniqueID); + AppendShort (a_Data, m_Item); + AppendByte (a_Data, m_Count); + AppendShort (a_Data, m_Health); + AppendInteger(a_Data, m_PosX); + AppendInteger(a_Data, m_PosY); + AppendInteger(a_Data, m_PosZ); + AppendByte (a_Data, m_Rotation); + AppendByte (a_Data, m_Pitch); + AppendByte (a_Data, m_Roll); +} + + + + diff --git a/source/packets/cPacket_PickupSpawn.h b/source/packets/cPacket_PickupSpawn.h index d46999a5a..1c1a6c640 100644 --- a/source/packets/cPacket_PickupSpawn.h +++ b/source/packets/cPacket_PickupSpawn.h @@ -1,46 +1,46 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_PickupSpawn : public cPacket -{ -public: - cPacket_PickupSpawn() - : m_UniqueID( 0 ) - , m_Item( 0 ) - , m_Count( 0 ) - , m_Health( 0 ) - , m_PosX( 0 ) - , m_PosY( 0 ) - , m_PosZ( 0 ) - , m_Rotation( 0 ) - , m_Pitch( 0 ) - , m_Roll( 0 ) - { m_PacketID = E_PICKUP_SPAWN; } - virtual cPacket* Clone() const { return new cPacket_PickupSpawn(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - int m_UniqueID; - short m_Item; - char m_Count; - short m_Health; - int m_PosX; - int m_PosY; - int m_PosZ; - char m_Rotation; - char m_Pitch; - char m_Roll; - - static const unsigned int c_Size = 1 + 4 + 2 + 1 + 2 + 4 + 4 + 4 + 1 + 1 + 1; -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_PickupSpawn : public cPacket +{ +public: + cPacket_PickupSpawn() + : m_UniqueID( 0 ) + , m_Item( 0 ) + , m_Count( 0 ) + , m_Health( 0 ) + , m_PosX( 0 ) + , m_PosY( 0 ) + , m_PosZ( 0 ) + , m_Rotation( 0 ) + , m_Pitch( 0 ) + , m_Roll( 0 ) + { m_PacketID = E_PICKUP_SPAWN; } + virtual cPacket* Clone() const { return new cPacket_PickupSpawn(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + int m_UniqueID; + short m_Item; + char m_Count; + short m_Health; + int m_PosX; + int m_PosY; + int m_PosZ; + char m_Rotation; + char m_Pitch; + char m_Roll; + + static const unsigned int c_Size = 1 + 4 + 2 + 1 + 2 + 4 + 4 + 4 + 1 + 1 + 1; +}; + + + + diff --git a/source/packets/cPacket_Ping.h b/source/packets/cPacket_Ping.h index 0a0609aeb..0a856c7ec 100644 --- a/source/packets/cPacket_Ping.h +++ b/source/packets/cPacket_Ping.h @@ -1,24 +1,24 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_Ping : public cPacket -{ -public: - cPacket_Ping() - { m_PacketID = E_PING; } - virtual cPacket* Clone() const { return new cPacket_Ping(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override {return 0; } - - static const unsigned int c_Size = 1; -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_Ping : public cPacket +{ +public: + cPacket_Ping() + { m_PacketID = E_PING; } + virtual cPacket* Clone() const { return new cPacket_Ping(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override {return 0; } + + static const unsigned int c_Size = 1; +}; + + + + diff --git a/source/packets/cPacket_Player.cpp b/source/packets/cPacket_Player.cpp index 86214d725..7d9a5de6b 100644 --- a/source/packets/cPacket_Player.cpp +++ b/source/packets/cPacket_Player.cpp @@ -1,243 +1,243 @@ - -// cPacket_Player.cpp - -/* Implements the player-related packets: - - PlayerAbilities (0xca) - - PlayerListItem (0xc9) - - PlayerLook (0x0c) - - PlayerMoveLook (0x0d) - - PlayerPosition (0x0b) -*/ - -#include "Globals.h" - -#include "cPacket_Player.h" -#include "../cPlayer.h" -#include "../cChatColor.h" - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cPacket_PlayerAbilities: - -int cPacket_PlayerAbilities::Parse(const char * a_Data, int a_Size) -{ - if (a_Size < 4) - { - return PACKET_INCOMPLETE; - } - m_Invulnerable = (a_Data[0] != 0); - m_IsFlying = (a_Data[1] != 0); - m_CanFly = (a_Data[2] != 0); - m_InstaMine = (a_Data[3] != 0); - return 4; -} - - - - - -void cPacket_PlayerAbilities::Serialize(AString & a_Data) const -{ - char Data[5]; - Data[0] = m_PacketID; - Data[1] = (char)m_Invulnerable; - Data[2] = (char)m_IsFlying; - Data[3] = (char)m_CanFly; - Data[4] = (char)m_InstaMine; - a_Data.append(Data, 5); -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cPacket_PlayerListItem: - -cPacket_PlayerListItem::cPacket_PlayerListItem(const AString & a_PlayerName, bool a_Online, short a_Ping) -{ - m_PacketID = E_PLAYER_LIST_ITEM; - m_PlayerName = a_PlayerName; - m_Online = a_Online; - m_Ping = a_Ping; -} - - - - - -int cPacket_PlayerListItem::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadString16, m_PlayerName, TotalBytes); - HANDLE_PACKET_READ(ReadBool, m_Online, TotalBytes); - HANDLE_PACKET_READ(ReadShort, m_Ping, TotalBytes); - return TotalBytes; -} - - - - - -void cPacket_PlayerListItem::Serialize(AString & a_Data) const -{ - AString PlayerName(m_PlayerName); - if (PlayerName.length() > 16) - { - PlayerName.erase(16); - } - else if (PlayerName.length() <= 14) - { - PlayerName += cChatColor::White; - } - - AppendByte (a_Data, m_PacketID); - AppendString16(a_Data, PlayerName); - AppendBool (a_Data, m_Online); - AppendShort (a_Data, m_Ping); -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cPacket_PlayerLook: - -cPacket_PlayerLook::cPacket_PlayerLook( cPlayer* a_Player ) -{ - m_PacketID = E_PLAYERLOOK; - m_Rotation = a_Player->GetRotation(); - m_Pitch = a_Player->GetPitch(); - m_bFlying = a_Player->GetFlying(); -} - - - - - -int cPacket_PlayerLook::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadFloat, m_Rotation, TotalBytes); - HANDLE_PACKET_READ(ReadFloat, m_Pitch, TotalBytes); - HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes); - return TotalBytes; -} - - - - - -void cPacket_PlayerLook::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendFloat (a_Data, m_Rotation); - AppendFloat (a_Data, m_Pitch); - AppendBool (a_Data, m_bFlying); -} - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cPacket_PlayerMoveLook: - -cPacket_PlayerMoveLook::cPacket_PlayerMoveLook( cPlayer* a_Player ) -{ - m_PacketID = E_PLAYERMOVELOOK; - m_PosX = a_Player->GetPosX(); - m_PosY = a_Player->GetPosY() + 1.65; - m_PosZ = a_Player->GetPosZ(); - m_Stance = a_Player->GetStance(); - m_Rotation = a_Player->GetRotation(); - m_Pitch = a_Player->GetPitch(); - m_bFlying = a_Player->GetFlying(); -} - - - - - -int cPacket_PlayerMoveLook::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadDouble, m_PosX, TotalBytes); - HANDLE_PACKET_READ(ReadDouble, m_PosY, TotalBytes); - HANDLE_PACKET_READ(ReadDouble, m_Stance, TotalBytes); - HANDLE_PACKET_READ(ReadDouble, m_PosZ, TotalBytes); - HANDLE_PACKET_READ(ReadFloat, m_Rotation, TotalBytes); - HANDLE_PACKET_READ(ReadFloat, m_Pitch, TotalBytes); - HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes); - return TotalBytes; -} - - - - - -void cPacket_PlayerMoveLook::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendDouble(a_Data, m_PosX); - AppendDouble(a_Data, m_PosY); - AppendDouble(a_Data, m_Stance); - AppendDouble(a_Data, m_PosZ); - AppendFloat (a_Data, m_Rotation); - AppendFloat (a_Data, m_Pitch); - AppendBool (a_Data, m_bFlying); -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cPacket_PlayerPosition: - -cPacket_PlayerPosition::cPacket_PlayerPosition( cPlayer* a_Player ) -{ - m_PacketID = E_PLAYERPOS; - - m_PosX = a_Player->GetPosX(); - m_PosY = a_Player->GetPosY() + 1.65; - m_PosZ = a_Player->GetPosZ(); - m_Stance = a_Player->GetStance(); - m_bFlying = a_Player->GetFlying(); -} - - - - - -int cPacket_PlayerPosition::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadDouble, m_PosX, TotalBytes); - HANDLE_PACKET_READ(ReadDouble, m_PosY, TotalBytes); - HANDLE_PACKET_READ(ReadDouble, m_Stance, TotalBytes); - HANDLE_PACKET_READ(ReadDouble, m_PosZ, TotalBytes); - HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes); - return TotalBytes; -} - - - - - -void cPacket_PlayerPosition::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendDouble (a_Data, m_PosX); - AppendDouble (a_Data, m_PosY); - AppendDouble (a_Data, m_Stance); - AppendDouble (a_Data, m_PosZ); - AppendBool (a_Data, m_bFlying); -} - - - - + +// cPacket_Player.cpp + +/* Implements the player-related packets: + - PlayerAbilities (0xca) + - PlayerListItem (0xc9) + - PlayerLook (0x0c) + - PlayerMoveLook (0x0d) + - PlayerPosition (0x0b) +*/ + +#include "Globals.h" + +#include "cPacket_Player.h" +#include "../cPlayer.h" +#include "../cChatColor.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPacket_PlayerAbilities: + +int cPacket_PlayerAbilities::Parse(const char * a_Data, int a_Size) +{ + if (a_Size < 4) + { + return PACKET_INCOMPLETE; + } + m_Invulnerable = (a_Data[0] != 0); + m_IsFlying = (a_Data[1] != 0); + m_CanFly = (a_Data[2] != 0); + m_InstaMine = (a_Data[3] != 0); + return 4; +} + + + + + +void cPacket_PlayerAbilities::Serialize(AString & a_Data) const +{ + char Data[5]; + Data[0] = m_PacketID; + Data[1] = (char)m_Invulnerable; + Data[2] = (char)m_IsFlying; + Data[3] = (char)m_CanFly; + Data[4] = (char)m_InstaMine; + a_Data.append(Data, 5); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPacket_PlayerListItem: + +cPacket_PlayerListItem::cPacket_PlayerListItem(const AString & a_PlayerName, bool a_Online, short a_Ping) +{ + m_PacketID = E_PLAYER_LIST_ITEM; + m_PlayerName = a_PlayerName; + m_Online = a_Online; + m_Ping = a_Ping; +} + + + + + +int cPacket_PlayerListItem::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadString16, m_PlayerName, TotalBytes); + HANDLE_PACKET_READ(ReadBool, m_Online, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_Ping, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_PlayerListItem::Serialize(AString & a_Data) const +{ + AString PlayerName(m_PlayerName); + if (PlayerName.length() > 16) + { + PlayerName.erase(16); + } + else if (PlayerName.length() <= 14) + { + PlayerName += cChatColor::White; + } + + AppendByte (a_Data, m_PacketID); + AppendString16(a_Data, PlayerName); + AppendBool (a_Data, m_Online); + AppendShort (a_Data, m_Ping); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPacket_PlayerLook: + +cPacket_PlayerLook::cPacket_PlayerLook( cPlayer* a_Player ) +{ + m_PacketID = E_PLAYERLOOK; + m_Rotation = a_Player->GetRotation(); + m_Pitch = a_Player->GetPitch(); + m_bFlying = a_Player->GetFlying(); +} + + + + + +int cPacket_PlayerLook::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadFloat, m_Rotation, TotalBytes); + HANDLE_PACKET_READ(ReadFloat, m_Pitch, TotalBytes); + HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_PlayerLook::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendFloat (a_Data, m_Rotation); + AppendFloat (a_Data, m_Pitch); + AppendBool (a_Data, m_bFlying); +} + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPacket_PlayerMoveLook: + +cPacket_PlayerMoveLook::cPacket_PlayerMoveLook( cPlayer* a_Player ) +{ + m_PacketID = E_PLAYERMOVELOOK; + m_PosX = a_Player->GetPosX(); + m_PosY = a_Player->GetPosY() + 1.65; + m_PosZ = a_Player->GetPosZ(); + m_Stance = a_Player->GetStance(); + m_Rotation = a_Player->GetRotation(); + m_Pitch = a_Player->GetPitch(); + m_bFlying = a_Player->GetFlying(); +} + + + + + +int cPacket_PlayerMoveLook::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadDouble, m_PosX, TotalBytes); + HANDLE_PACKET_READ(ReadDouble, m_PosY, TotalBytes); + HANDLE_PACKET_READ(ReadDouble, m_Stance, TotalBytes); + HANDLE_PACKET_READ(ReadDouble, m_PosZ, TotalBytes); + HANDLE_PACKET_READ(ReadFloat, m_Rotation, TotalBytes); + HANDLE_PACKET_READ(ReadFloat, m_Pitch, TotalBytes); + HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_PlayerMoveLook::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendDouble(a_Data, m_PosX); + AppendDouble(a_Data, m_PosY); + AppendDouble(a_Data, m_Stance); + AppendDouble(a_Data, m_PosZ); + AppendFloat (a_Data, m_Rotation); + AppendFloat (a_Data, m_Pitch); + AppendBool (a_Data, m_bFlying); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPacket_PlayerPosition: + +cPacket_PlayerPosition::cPacket_PlayerPosition( cPlayer* a_Player ) +{ + m_PacketID = E_PLAYERPOS; + + m_PosX = a_Player->GetPosX(); + m_PosY = a_Player->GetPosY() + 1.65; + m_PosZ = a_Player->GetPosZ(); + m_Stance = a_Player->GetStance(); + m_bFlying = a_Player->GetFlying(); +} + + + + + +int cPacket_PlayerPosition::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadDouble, m_PosX, TotalBytes); + HANDLE_PACKET_READ(ReadDouble, m_PosY, TotalBytes); + HANDLE_PACKET_READ(ReadDouble, m_Stance, TotalBytes); + HANDLE_PACKET_READ(ReadDouble, m_PosZ, TotalBytes); + HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_PlayerPosition::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendDouble (a_Data, m_PosX); + AppendDouble (a_Data, m_PosY); + AppendDouble (a_Data, m_Stance); + AppendDouble (a_Data, m_PosZ); + AppendBool (a_Data, m_bFlying); +} + + + + diff --git a/source/packets/cPacket_Player.h b/source/packets/cPacket_Player.h index ce88cc451..5b17feabf 100644 --- a/source/packets/cPacket_Player.h +++ b/source/packets/cPacket_Player.h @@ -1,150 +1,150 @@ - -// cPacket_Player.h - -/* Interfaces to the player-related packets: - - PlayerAbilities (0xca) - - PlayerListItem (0xc9) - - PlayerLook (0x0c) - - PlayerMoveLook (0x0d) - - PlayerPosition (0x0b) -*/ - -#pragma once - - - - - -#include "cPacket.h" - - - - - -// fwd: -class cPlayer; - - - - - -class cPacket_PlayerAbilities : public cPacket -{ -public: - cPacket_PlayerAbilities(void) { m_PacketID = E_PLAYER_LIST_ITEM; } - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - virtual cPacket * Clone() const { return new cPacket_PlayerAbilities(*this); } - - bool m_Invulnerable; // Speculation - bool m_IsFlying; - bool m_CanFly; - bool m_InstaMine; // Speculation -} ; - - - - - -class cPacket_PlayerListItem : public cPacket -{ -public: - cPacket_PlayerListItem() { m_PacketID = E_PLAYER_LIST_ITEM; } - cPacket_PlayerListItem(const AString & a_PlayerName, bool a_Online, short a_Ping); - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - virtual cPacket* Clone() const { return new cPacket_PlayerListItem(*this); } - - AString m_PlayerName; // Supports chat coloring, limited to 16 characters. - bool m_Online; - short m_Ping; -} ; - - - - - -class cPacket_PlayerLook : public cPacket -{ -public: - cPacket_PlayerLook() - : m_Rotation( 0 ) - , m_Pitch( 0 ) - , m_bFlying( false ) - { m_PacketID = E_PLAYERLOOK; } - cPacket_PlayerLook( cPlayer* a_Player ); - virtual cPacket* Clone() const { return new cPacket_PlayerLook(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - float m_Rotation; - float m_Pitch; - bool m_bFlying; // Yeah.. wtf -} ; - - - - - -class cPacket_PlayerMoveLook : public cPacket -{ -public: - cPacket_PlayerMoveLook() - : m_PosX( 0.0 ) - , m_PosY( 0.0 ) - , m_Stance( 0.0 ) - , m_PosZ( 0.0 ) - , m_Rotation( 0.f ) - , m_Pitch( 0.f ) - , m_bFlying( false ) - { m_PacketID = E_PLAYERMOVELOOK; } - cPacket_PlayerMoveLook( cPlayer* a_Player ); - virtual cPacket* Clone() const { return new cPacket_PlayerMoveLook(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - double m_PosX; - double m_PosY; - double m_Stance; - double m_PosZ; - float m_Rotation; - float m_Pitch; - bool m_bFlying; // Yeah.. wtf -} ; - - - - - -class cPacket_PlayerPosition : public cPacket -{ -public: - cPacket_PlayerPosition( cPlayer* a_Player ); - cPacket_PlayerPosition() - : m_PosX( 0.0 ) - , m_PosY( 0.0 ) - , m_Stance( 0.0 ) - , m_PosZ( 0.0 ) - , m_bFlying( false ) - { m_PacketID = E_PLAYERPOS; } - virtual cPacket* Clone() const { return new cPacket_PlayerPosition(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - double m_PosX; - double m_PosY; - double m_Stance; - double m_PosZ; - bool m_bFlying; // Yeah.. wtf -} ; - - - - + +// cPacket_Player.h + +/* Interfaces to the player-related packets: + - PlayerAbilities (0xca) + - PlayerListItem (0xc9) + - PlayerLook (0x0c) + - PlayerMoveLook (0x0d) + - PlayerPosition (0x0b) +*/ + +#pragma once + + + + + +#include "cPacket.h" + + + + + +// fwd: +class cPlayer; + + + + + +class cPacket_PlayerAbilities : public cPacket +{ +public: + cPacket_PlayerAbilities(void) { m_PacketID = E_PLAYER_LIST_ITEM; } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + virtual cPacket * Clone() const { return new cPacket_PlayerAbilities(*this); } + + bool m_Invulnerable; // Speculation + bool m_IsFlying; + bool m_CanFly; + bool m_InstaMine; // Speculation +} ; + + + + + +class cPacket_PlayerListItem : public cPacket +{ +public: + cPacket_PlayerListItem() { m_PacketID = E_PLAYER_LIST_ITEM; } + cPacket_PlayerListItem(const AString & a_PlayerName, bool a_Online, short a_Ping); + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + virtual cPacket* Clone() const { return new cPacket_PlayerListItem(*this); } + + AString m_PlayerName; // Supports chat coloring, limited to 16 characters. + bool m_Online; + short m_Ping; +} ; + + + + + +class cPacket_PlayerLook : public cPacket +{ +public: + cPacket_PlayerLook() + : m_Rotation( 0 ) + , m_Pitch( 0 ) + , m_bFlying( false ) + { m_PacketID = E_PLAYERLOOK; } + cPacket_PlayerLook( cPlayer* a_Player ); + virtual cPacket* Clone() const { return new cPacket_PlayerLook(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + float m_Rotation; + float m_Pitch; + bool m_bFlying; // Yeah.. wtf +} ; + + + + + +class cPacket_PlayerMoveLook : public cPacket +{ +public: + cPacket_PlayerMoveLook() + : m_PosX( 0.0 ) + , m_PosY( 0.0 ) + , m_Stance( 0.0 ) + , m_PosZ( 0.0 ) + , m_Rotation( 0.f ) + , m_Pitch( 0.f ) + , m_bFlying( false ) + { m_PacketID = E_PLAYERMOVELOOK; } + cPacket_PlayerMoveLook( cPlayer* a_Player ); + virtual cPacket* Clone() const { return new cPacket_PlayerMoveLook(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + double m_PosX; + double m_PosY; + double m_Stance; + double m_PosZ; + float m_Rotation; + float m_Pitch; + bool m_bFlying; // Yeah.. wtf +} ; + + + + + +class cPacket_PlayerPosition : public cPacket +{ +public: + cPacket_PlayerPosition( cPlayer* a_Player ); + cPacket_PlayerPosition() + : m_PosX( 0.0 ) + , m_PosY( 0.0 ) + , m_Stance( 0.0 ) + , m_PosZ( 0.0 ) + , m_bFlying( false ) + { m_PacketID = E_PLAYERPOS; } + virtual cPacket* Clone() const { return new cPacket_PlayerPosition(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + double m_PosX; + double m_PosY; + double m_Stance; + double m_PosZ; + bool m_bFlying; // Yeah.. wtf +} ; + + + + diff --git a/source/packets/cPacket_PreChunk.cpp b/source/packets/cPacket_PreChunk.cpp index a792ce124..f7824bba2 100644 --- a/source/packets/cPacket_PreChunk.cpp +++ b/source/packets/cPacket_PreChunk.cpp @@ -1,20 +1,20 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_PreChunk.h" - - - - - -void cPacket_PreChunk::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendInteger(a_Data, m_PosX); - AppendInteger(a_Data, m_PosZ); - AppendBool (a_Data, m_bLoad); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_PreChunk.h" + + + + + +void cPacket_PreChunk::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_PosX); + AppendInteger(a_Data, m_PosZ); + AppendBool (a_Data, m_bLoad); +} + + + + diff --git a/source/packets/cPacket_PreChunk.h b/source/packets/cPacket_PreChunk.h index cc8147c4a..902fa2a02 100644 --- a/source/packets/cPacket_PreChunk.h +++ b/source/packets/cPacket_PreChunk.h @@ -1,36 +1,36 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_PreChunk: public cPacket -{ -public: - cPacket_PreChunk() - : m_PosX( 0 ) - , m_PosZ( 0 ) - , m_bLoad( false ) - { m_PacketID = E_PRE_CHUNK; } - cPacket_PreChunk( int a_PosX, int a_PosZ, bool a_bLoad ) - : m_PosX( a_PosX ) - , m_PosZ( a_PosZ ) - , m_bLoad( a_bLoad ) - { m_PacketID = E_PRE_CHUNK; } - virtual cPacket* Clone() const { return new cPacket_PreChunk(*this); } - - virtual void Serialize(AString & a_Data) const override; - - int m_PosX; - int m_PosZ; - bool m_bLoad; - - static const unsigned int c_Size = 10; -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_PreChunk: public cPacket +{ +public: + cPacket_PreChunk() + : m_PosX( 0 ) + , m_PosZ( 0 ) + , m_bLoad( false ) + { m_PacketID = E_PRE_CHUNK; } + cPacket_PreChunk( int a_PosX, int a_PosZ, bool a_bLoad ) + : m_PosX( a_PosX ) + , m_PosZ( a_PosZ ) + , m_bLoad( a_bLoad ) + { m_PacketID = E_PRE_CHUNK; } + virtual cPacket* Clone() const { return new cPacket_PreChunk(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_PosX; + int m_PosZ; + bool m_bLoad; + + static const unsigned int c_Size = 10; +}; + + + + diff --git a/source/packets/cPacket_RelativeEntityMove.cpp b/source/packets/cPacket_RelativeEntityMove.cpp index c4d0f3196..de3746024 100644 --- a/source/packets/cPacket_RelativeEntityMove.cpp +++ b/source/packets/cPacket_RelativeEntityMove.cpp @@ -1,21 +1,21 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_RelativeEntityMove.h" - - - - - -void cPacket_RelativeEntityMove::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendInteger(a_Data, m_UniqueID); - AppendByte (a_Data, m_MoveX); - AppendByte (a_Data, m_MoveY); - AppendByte (a_Data, m_MoveZ); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_RelativeEntityMove.h" + + + + + +void cPacket_RelativeEntityMove::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_UniqueID); + AppendByte (a_Data, m_MoveX); + AppendByte (a_Data, m_MoveY); + AppendByte (a_Data, m_MoveZ); +} + + + + diff --git a/source/packets/cPacket_RelativeEntityMove.h b/source/packets/cPacket_RelativeEntityMove.h index 9ccf0d95f..7dd2cbdbc 100644 --- a/source/packets/cPacket_RelativeEntityMove.h +++ b/source/packets/cPacket_RelativeEntityMove.h @@ -1,33 +1,33 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_RelativeEntityMove : public cPacket -{ -public: - cPacket_RelativeEntityMove() - : m_UniqueID( 0 ) - , m_MoveX( 0 ) - , m_MoveY( 0 ) - , m_MoveZ( 0 ) - { m_PacketID = E_REL_ENT_MOVE; } - virtual cPacket* Clone() const { return new cPacket_RelativeEntityMove(*this); } - - virtual void Serialize(AString & a_Data) const override; - - int m_UniqueID; - char m_MoveX; // Pixels, devide by 32 for block - char m_MoveY; - char m_MoveZ; - - static const unsigned int c_Size = 1 + 4 + 1 + 1 + 1; -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_RelativeEntityMove : public cPacket +{ +public: + cPacket_RelativeEntityMove() + : m_UniqueID( 0 ) + , m_MoveX( 0 ) + , m_MoveY( 0 ) + , m_MoveZ( 0 ) + { m_PacketID = E_REL_ENT_MOVE; } + virtual cPacket* Clone() const { return new cPacket_RelativeEntityMove(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_UniqueID; + char m_MoveX; // Pixels, devide by 32 for block + char m_MoveY; + char m_MoveZ; + + static const unsigned int c_Size = 1 + 4 + 1 + 1 + 1; +}; + + + + diff --git a/source/packets/cPacket_RelativeEntityMoveLook.cpp b/source/packets/cPacket_RelativeEntityMoveLook.cpp index 1e8a9ae6c..fad2c0620 100644 --- a/source/packets/cPacket_RelativeEntityMoveLook.cpp +++ b/source/packets/cPacket_RelativeEntityMoveLook.cpp @@ -1,24 +1,24 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_RelativeEntityMoveLook.h" - - - - - -void cPacket_RelativeEntityMoveLook::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendInteger(a_Data, m_UniqueID); - AppendByte (a_Data, m_MoveX); - AppendByte (a_Data, m_MoveY); - AppendByte (a_Data, m_MoveZ); - AppendByte (a_Data, m_Yaw); - AppendByte (a_Data, m_Pitch); -} - - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_RelativeEntityMoveLook.h" + + + + + +void cPacket_RelativeEntityMoveLook::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_UniqueID); + AppendByte (a_Data, m_MoveX); + AppendByte (a_Data, m_MoveY); + AppendByte (a_Data, m_MoveZ); + AppendByte (a_Data, m_Yaw); + AppendByte (a_Data, m_Pitch); +} + + + + + diff --git a/source/packets/cPacket_RelativeEntityMoveLook.h b/source/packets/cPacket_RelativeEntityMoveLook.h index 79cb1a7eb..8fa6bf015 100644 --- a/source/packets/cPacket_RelativeEntityMoveLook.h +++ b/source/packets/cPacket_RelativeEntityMoveLook.h @@ -1,37 +1,37 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_RelativeEntityMoveLook : public cPacket -{ -public: - cPacket_RelativeEntityMoveLook() - : m_UniqueID( 0 ) - , m_MoveX( 0 ) - , m_MoveY( 0 ) - , m_MoveZ( 0 ) - , m_Yaw( 0 ) - , m_Pitch( 0 ) - { m_PacketID = E_REL_ENT_MOVE_LOOK; } - virtual cPacket* Clone() const { return new cPacket_RelativeEntityMoveLook(*this); } - - virtual void Serialize(AString & a_Data) const override; - - int m_UniqueID; - char m_MoveX; // Pixels, divide by 32 for block - char m_MoveY; - char m_MoveZ; - char m_Yaw; - char m_Pitch; - - static const unsigned int c_Size = 1 + 4 + 1 + 1 + 1 + 1 + 1; -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_RelativeEntityMoveLook : public cPacket +{ +public: + cPacket_RelativeEntityMoveLook() + : m_UniqueID( 0 ) + , m_MoveX( 0 ) + , m_MoveY( 0 ) + , m_MoveZ( 0 ) + , m_Yaw( 0 ) + , m_Pitch( 0 ) + { m_PacketID = E_REL_ENT_MOVE_LOOK; } + virtual cPacket* Clone() const { return new cPacket_RelativeEntityMoveLook(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_UniqueID; + char m_MoveX; // Pixels, divide by 32 for block + char m_MoveY; + char m_MoveZ; + char m_Yaw; + char m_Pitch; + + static const unsigned int c_Size = 1 + 4 + 1 + 1 + 1 + 1 + 1; +}; + + + + diff --git a/source/packets/cPacket_Respawn.cpp b/source/packets/cPacket_Respawn.cpp index a6b3b5bc4..657fd70b5 100644 --- a/source/packets/cPacket_Respawn.cpp +++ b/source/packets/cPacket_Respawn.cpp @@ -1,39 +1,39 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_Respawn.h" - - - - - -void cPacket_Respawn::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - - AppendInteger (a_Data, m_Dimension); - AppendByte (a_Data, m_Difficulty); - AppendByte (a_Data, m_CreativeMode); - AppendShort (a_Data, m_WorldHeight); - AppendString16(a_Data, m_LevelType); -} - - - - - -int cPacket_Respawn::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - - HANDLE_PACKET_READ(ReadInteger, m_Dimension, TotalBytes); - HANDLE_PACKET_READ(ReadByte, m_Difficulty, TotalBytes); - HANDLE_PACKET_READ(ReadByte, m_CreativeMode, TotalBytes); - HANDLE_PACKET_READ(ReadShort, m_WorldHeight, TotalBytes); - HANDLE_PACKET_READ(ReadString16, m_LevelType, TotalBytes); - return TotalBytes; -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_Respawn.h" + + + + + +void cPacket_Respawn::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + + AppendInteger (a_Data, m_Dimension); + AppendByte (a_Data, m_Difficulty); + AppendByte (a_Data, m_CreativeMode); + AppendShort (a_Data, m_WorldHeight); + AppendString16(a_Data, m_LevelType); +} + + + + + +int cPacket_Respawn::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + + HANDLE_PACKET_READ(ReadInteger, m_Dimension, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_Difficulty, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_CreativeMode, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_WorldHeight, TotalBytes); + HANDLE_PACKET_READ(ReadString16, m_LevelType, TotalBytes); + return TotalBytes; +} + + + + diff --git a/source/packets/cPacket_Respawn.h b/source/packets/cPacket_Respawn.h index b95ecc384..302dbe25e 100644 --- a/source/packets/cPacket_Respawn.h +++ b/source/packets/cPacket_Respawn.h @@ -1,37 +1,37 @@ - -#pragma once - -#include "cPacket.h" - -#include "cPacket_Login.h" - - - - - -class cPacket_Respawn : public cPacket -{ -public: - cPacket_Respawn() - : m_Dimension( 0 ) - , m_Difficulty( 0 ) - , m_CreativeMode( 0 ) - , m_WorldHeight( 0 ) - , m_LevelType( cPacket_Login::LEVEL_TYPE_DEFAULT ) - { m_PacketID = E_RESPAWN; } - - virtual cPacket* Clone() const { return new cPacket_Respawn( *this ); } - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - int m_Dimension; - char m_Difficulty; - char m_CreativeMode; - short m_WorldHeight; - AString m_LevelType; -}; - - - - + +#pragma once + +#include "cPacket.h" + +#include "cPacket_Login.h" + + + + + +class cPacket_Respawn : public cPacket +{ +public: + cPacket_Respawn() + : m_Dimension( 0 ) + , m_Difficulty( 0 ) + , m_CreativeMode( 0 ) + , m_WorldHeight( 0 ) + , m_LevelType( cPacket_Login::LEVEL_TYPE_DEFAULT ) + { m_PacketID = E_RESPAWN; } + + virtual cPacket* Clone() const { return new cPacket_Respawn( *this ); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + int m_Dimension; + char m_Difficulty; + char m_CreativeMode; + short m_WorldHeight; + AString m_LevelType; +}; + + + + diff --git a/source/packets/cPacket_SpawnMob.cpp b/source/packets/cPacket_SpawnMob.cpp index d3f1850b3..47339c7e0 100644 --- a/source/packets/cPacket_SpawnMob.cpp +++ b/source/packets/cPacket_SpawnMob.cpp @@ -1,75 +1,75 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_SpawnMob.h" -#include "../Vector3i.h" - - - - - -cPacket_SpawnMob::~cPacket_SpawnMob() -{ - if( m_MetaData ) delete [] m_MetaData; - delete m_Pos; -} - - - - - -cPacket_SpawnMob::cPacket_SpawnMob() - : m_UniqueID( 0 ) - , m_Type( 0 ) - , m_Pos( new Vector3i() ) - , m_Yaw( 0 ) - , m_Pitch( 0 ) - , m_MetaDataSize( 0 ) - , m_MetaData( 0 ) - , m_HeadYaw(0) -{ - m_PacketID = E_SPAWN_MOB; -} - - - - - -cPacket_SpawnMob::cPacket_SpawnMob( const cPacket_SpawnMob & a_Clone ) -{ - m_Pos = new Vector3i(); - - m_PacketID = E_SPAWN_MOB; - m_UniqueID = a_Clone.m_UniqueID; - m_Type = a_Clone.m_Type; - *m_Pos = *a_Clone.m_Pos; - m_Yaw = a_Clone.m_Yaw; - m_Pitch = a_Clone.m_Pitch; - m_HeadYaw = a_Clone.m_HeadYaw; - - m_MetaDataSize = a_Clone.m_MetaDataSize; - m_MetaData = new char[m_MetaDataSize]; - memcpy( m_MetaData, a_Clone.m_MetaData, sizeof( char ) * m_MetaDataSize ); -} - - - - - -void cPacket_SpawnMob::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendInteger (a_Data, m_UniqueID); - AppendByte (a_Data, m_Type); - AppendInteger (a_Data, m_Pos->x); - AppendInteger (a_Data, m_Pos->y); - AppendInteger (a_Data, m_Pos->z); - AppendByte (a_Data, m_Yaw); - AppendByte (a_Data, m_Pitch); - AppendByte (a_Data, m_HeadYaw); - AppendData (a_Data, m_MetaData, m_MetaDataSize); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_SpawnMob.h" +#include "../Vector3i.h" + + + + + +cPacket_SpawnMob::~cPacket_SpawnMob() +{ + if( m_MetaData ) delete [] m_MetaData; + delete m_Pos; +} + + + + + +cPacket_SpawnMob::cPacket_SpawnMob() + : m_UniqueID( 0 ) + , m_Type( 0 ) + , m_Pos( new Vector3i() ) + , m_Yaw( 0 ) + , m_Pitch( 0 ) + , m_MetaDataSize( 0 ) + , m_MetaData( 0 ) + , m_HeadYaw(0) +{ + m_PacketID = E_SPAWN_MOB; +} + + + + + +cPacket_SpawnMob::cPacket_SpawnMob( const cPacket_SpawnMob & a_Clone ) +{ + m_Pos = new Vector3i(); + + m_PacketID = E_SPAWN_MOB; + m_UniqueID = a_Clone.m_UniqueID; + m_Type = a_Clone.m_Type; + *m_Pos = *a_Clone.m_Pos; + m_Yaw = a_Clone.m_Yaw; + m_Pitch = a_Clone.m_Pitch; + m_HeadYaw = a_Clone.m_HeadYaw; + + m_MetaDataSize = a_Clone.m_MetaDataSize; + m_MetaData = new char[m_MetaDataSize]; + memcpy( m_MetaData, a_Clone.m_MetaData, sizeof( char ) * m_MetaDataSize ); +} + + + + + +void cPacket_SpawnMob::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger (a_Data, m_UniqueID); + AppendByte (a_Data, m_Type); + AppendInteger (a_Data, m_Pos->x); + AppendInteger (a_Data, m_Pos->y); + AppendInteger (a_Data, m_Pos->z); + AppendByte (a_Data, m_Yaw); + AppendByte (a_Data, m_Pitch); + AppendByte (a_Data, m_HeadYaw); + AppendData (a_Data, m_MetaData, m_MetaDataSize); +} + + + + diff --git a/source/packets/cPacket_SpawnMob.h b/source/packets/cPacket_SpawnMob.h index ff579af99..bc7fbe235 100644 --- a/source/packets/cPacket_SpawnMob.h +++ b/source/packets/cPacket_SpawnMob.h @@ -1,39 +1,39 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class Vector3i; - - - - - -class cPacket_SpawnMob : public cPacket -{ -public: - cPacket_SpawnMob(); - cPacket_SpawnMob( const cPacket_SpawnMob & a_Clone ); - virtual cPacket* Clone() const { return new cPacket_SpawnMob( *this ); } - ~cPacket_SpawnMob(); - - virtual void Serialize(AString & a_Data) const override; - - int m_UniqueID; - char m_Type; - Vector3i* m_Pos; - char m_Yaw; - char m_Pitch; - char m_HeadYaw; - - unsigned int m_MetaDataSize; - char * m_MetaData; -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class Vector3i; + + + + + +class cPacket_SpawnMob : public cPacket +{ +public: + cPacket_SpawnMob(); + cPacket_SpawnMob( const cPacket_SpawnMob & a_Clone ); + virtual cPacket* Clone() const { return new cPacket_SpawnMob( *this ); } + ~cPacket_SpawnMob(); + + virtual void Serialize(AString & a_Data) const override; + + int m_UniqueID; + char m_Type; + Vector3i* m_Pos; + char m_Yaw; + char m_Pitch; + char m_HeadYaw; + + unsigned int m_MetaDataSize; + char * m_MetaData; +}; + + + + diff --git a/source/packets/cPacket_TeleportEntity.cpp b/source/packets/cPacket_TeleportEntity.cpp index a888f009d..396095037 100644 --- a/source/packets/cPacket_TeleportEntity.cpp +++ b/source/packets/cPacket_TeleportEntity.cpp @@ -1,41 +1,41 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_TeleportEntity.h" - -#include "../cEntity.h" - - - - - -cPacket_TeleportEntity::cPacket_TeleportEntity(cEntity* a_Client) -{ - m_PacketID = E_ENT_TELEPORT; - - m_UniqueID = a_Client->GetUniqueID(); - m_PosX = (int)(a_Client->GetPosX() * 32); - m_PosY = (int)(a_Client->GetPosY() * 32); - m_PosZ = (int)(a_Client->GetPosZ() * 32); - m_Rotation = (char)((a_Client->GetRotation() / 360.f) * 256); - m_Pitch = (char)((a_Client->GetPitch() / 360.f) * 256); -} - - - - - -void cPacket_TeleportEntity::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendInteger(a_Data, m_UniqueID); - AppendInteger(a_Data, m_PosX); - AppendInteger(a_Data, m_PosY); - AppendInteger(a_Data, m_PosZ); - AppendByte (a_Data, m_Rotation); - AppendByte (a_Data, m_Pitch); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_TeleportEntity.h" + +#include "../cEntity.h" + + + + + +cPacket_TeleportEntity::cPacket_TeleportEntity(cEntity* a_Client) +{ + m_PacketID = E_ENT_TELEPORT; + + m_UniqueID = a_Client->GetUniqueID(); + m_PosX = (int)(a_Client->GetPosX() * 32); + m_PosY = (int)(a_Client->GetPosY() * 32); + m_PosZ = (int)(a_Client->GetPosZ() * 32); + m_Rotation = (char)((a_Client->GetRotation() / 360.f) * 256); + m_Pitch = (char)((a_Client->GetPitch() / 360.f) * 256); +} + + + + + +void cPacket_TeleportEntity::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_UniqueID); + AppendInteger(a_Data, m_PosX); + AppendInteger(a_Data, m_PosY); + AppendInteger(a_Data, m_PosZ); + AppendByte (a_Data, m_Rotation); + AppendByte (a_Data, m_Pitch); +} + + + + diff --git a/source/packets/cPacket_TeleportEntity.h b/source/packets/cPacket_TeleportEntity.h index 0cff50a85..d0504f901 100644 --- a/source/packets/cPacket_TeleportEntity.h +++ b/source/packets/cPacket_TeleportEntity.h @@ -1,39 +1,39 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cEntity; -class cPacket_TeleportEntity : public cPacket -{ -public: - cPacket_TeleportEntity() - : m_UniqueID( 0 ) - , m_PosX( 0 ) - , m_PosY( 0 ) - , m_PosZ( 0 ) - , m_Rotation( 0 ) - , m_Pitch( 0 ) - { m_PacketID = E_ENT_TELEPORT; } - virtual cPacket* Clone() const { return new cPacket_TeleportEntity(*this); } - cPacket_TeleportEntity(cEntity* a_Client); - - virtual void Serialize(AString & a_Data) const override; - - int m_UniqueID; - int m_PosX; // Pixel position, divide by 32 for block position - int m_PosY; - int m_PosZ; - char m_Rotation; - char m_Pitch; - - static const unsigned int c_Size = 1 + 4 + 4 + 4 + 4 + 1 + 1; -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cEntity; +class cPacket_TeleportEntity : public cPacket +{ +public: + cPacket_TeleportEntity() + : m_UniqueID( 0 ) + , m_PosX( 0 ) + , m_PosY( 0 ) + , m_PosZ( 0 ) + , m_Rotation( 0 ) + , m_Pitch( 0 ) + { m_PacketID = E_ENT_TELEPORT; } + virtual cPacket* Clone() const { return new cPacket_TeleportEntity(*this); } + cPacket_TeleportEntity(cEntity* a_Client); + + virtual void Serialize(AString & a_Data) const override; + + int m_UniqueID; + int m_PosX; // Pixel position, divide by 32 for block position + int m_PosY; + int m_PosZ; + char m_Rotation; + char m_Pitch; + + static const unsigned int c_Size = 1 + 4 + 4 + 4 + 4 + 1 + 1; +}; + + + + diff --git a/source/packets/cPacket_TimeUpdate.cpp b/source/packets/cPacket_TimeUpdate.cpp index a0bf05677..be54e1484 100644 --- a/source/packets/cPacket_TimeUpdate.cpp +++ b/source/packets/cPacket_TimeUpdate.cpp @@ -1,29 +1,29 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_TimeUpdate.h" - - - - - -int cPacket_TimeUpdate::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadLong, m_Time, TotalBytes); - return TotalBytes; -} - - - - - -void cPacket_TimeUpdate::Serialize(AString & a_Data) const -{ - AppendByte(a_Data, m_PacketID); - AppendLong(a_Data, m_Time); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_TimeUpdate.h" + + + + + +int cPacket_TimeUpdate::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadLong, m_Time, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_TimeUpdate::Serialize(AString & a_Data) const +{ + AppendByte(a_Data, m_PacketID); + AppendLong(a_Data, m_Time); +} + + + + diff --git a/source/packets/cPacket_TimeUpdate.h b/source/packets/cPacket_TimeUpdate.h index 1cc66c2f9..8864c9b00 100644 --- a/source/packets/cPacket_TimeUpdate.h +++ b/source/packets/cPacket_TimeUpdate.h @@ -1,29 +1,29 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_TimeUpdate : public cPacket -{ -public: - cPacket_TimeUpdate() - : m_Time( 0 ) - { m_PacketID = E_UPDATE_TIME; } - cPacket_TimeUpdate( long long a_Time ) { m_PacketID = E_UPDATE_TIME; m_Time = a_Time; } - virtual cPacket* Clone() const { return new cPacket_TimeUpdate(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - long long m_Time; - - static const unsigned int c_Size = 1 + 8; -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_TimeUpdate : public cPacket +{ +public: + cPacket_TimeUpdate() + : m_Time( 0 ) + { m_PacketID = E_UPDATE_TIME; } + cPacket_TimeUpdate( long long a_Time ) { m_PacketID = E_UPDATE_TIME; m_Time = a_Time; } + virtual cPacket* Clone() const { return new cPacket_TimeUpdate(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + long long m_Time; + + static const unsigned int c_Size = 1 + 8; +}; + + + + diff --git a/source/packets/cPacket_UpdateHealth.cpp b/source/packets/cPacket_UpdateHealth.cpp index 4380e25d6..ff54b6530 100644 --- a/source/packets/cPacket_UpdateHealth.cpp +++ b/source/packets/cPacket_UpdateHealth.cpp @@ -1,20 +1,20 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_UpdateHealth.h" - - - - - -void cPacket_UpdateHealth::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendShort(a_Data, m_Health); - AppendShort(a_Data, m_Food); - AppendFloat(a_Data, m_Saturation); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_UpdateHealth.h" + + + + + +void cPacket_UpdateHealth::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendShort(a_Data, m_Health); + AppendShort(a_Data, m_Food); + AppendFloat(a_Data, m_Saturation); +} + + + + diff --git a/source/packets/cPacket_UpdateHealth.h b/source/packets/cPacket_UpdateHealth.h index 3a6135e07..67fd32399 100644 --- a/source/packets/cPacket_UpdateHealth.h +++ b/source/packets/cPacket_UpdateHealth.h @@ -1,32 +1,32 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_UpdateHealth : public cPacket -{ -public: - cPacket_UpdateHealth() - : m_Health( 0 ) - , m_Food( 0 ) - , m_Saturation( 0.f ) - { m_PacketID = E_UPDATE_HEALTH; } - cPacket_UpdateHealth( short a_Health ) { m_Health = a_Health; m_PacketID = E_UPDATE_HEALTH; } - virtual cPacket* Clone() const { return new cPacket_UpdateHealth( *this ); } - - virtual void Serialize(AString & a_Data) const override; - - short m_Health; - short m_Food; - float m_Saturation; - - static const unsigned int c_Size = 1 + 2 + 2 + 4; -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_UpdateHealth : public cPacket +{ +public: + cPacket_UpdateHealth() + : m_Health( 0 ) + , m_Food( 0 ) + , m_Saturation( 0.f ) + { m_PacketID = E_UPDATE_HEALTH; } + cPacket_UpdateHealth( short a_Health ) { m_Health = a_Health; m_PacketID = E_UPDATE_HEALTH; } + virtual cPacket* Clone() const { return new cPacket_UpdateHealth( *this ); } + + virtual void Serialize(AString & a_Data) const override; + + short m_Health; + short m_Food; + float m_Saturation; + + static const unsigned int c_Size = 1 + 2 + 2 + 4; +}; + + + + diff --git a/source/packets/cPacket_UpdateSign.cpp b/source/packets/cPacket_UpdateSign.cpp index 723fca6af..a3ea53968 100644 --- a/source/packets/cPacket_UpdateSign.cpp +++ b/source/packets/cPacket_UpdateSign.cpp @@ -1,41 +1,41 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_UpdateSign.h" - - - - - -int cPacket_UpdateSign::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadInteger, m_PosX, TotalBytes); - HANDLE_PACKET_READ(ReadShort, m_PosY, TotalBytes); - HANDLE_PACKET_READ(ReadInteger, m_PosZ, TotalBytes); - HANDLE_PACKET_READ(ReadString16, m_Line1, TotalBytes); - HANDLE_PACKET_READ(ReadString16, m_Line2, TotalBytes); - HANDLE_PACKET_READ(ReadString16, m_Line3, TotalBytes); - HANDLE_PACKET_READ(ReadString16, m_Line4, TotalBytes); - return TotalBytes; -} - - - - - -void cPacket_UpdateSign::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendInteger (a_Data, m_PosX); - AppendShort (a_Data, m_PosY); - AppendInteger (a_Data, m_PosZ); - AppendString16(a_Data, m_Line1); - AppendString16(a_Data, m_Line2); - AppendString16(a_Data, m_Line3); - AppendString16(a_Data, m_Line4); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_UpdateSign.h" + + + + + +int cPacket_UpdateSign::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadInteger, m_PosX, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_PosY, TotalBytes); + HANDLE_PACKET_READ(ReadInteger, m_PosZ, TotalBytes); + HANDLE_PACKET_READ(ReadString16, m_Line1, TotalBytes); + HANDLE_PACKET_READ(ReadString16, m_Line2, TotalBytes); + HANDLE_PACKET_READ(ReadString16, m_Line3, TotalBytes); + HANDLE_PACKET_READ(ReadString16, m_Line4, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_UpdateSign::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger (a_Data, m_PosX); + AppendShort (a_Data, m_PosY); + AppendInteger (a_Data, m_PosZ); + AppendString16(a_Data, m_Line1); + AppendString16(a_Data, m_Line2); + AppendString16(a_Data, m_Line3); + AppendString16(a_Data, m_Line4); +} + + + + diff --git a/source/packets/cPacket_UpdateSign.h b/source/packets/cPacket_UpdateSign.h index 1e4da6471..b2c0effad 100644 --- a/source/packets/cPacket_UpdateSign.h +++ b/source/packets/cPacket_UpdateSign.h @@ -1,36 +1,36 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_UpdateSign : public cPacket -{ -public: - cPacket_UpdateSign() - : m_PosX( 0 ) - , m_PosY( 0 ) - , m_PosZ( 0 ) - { m_PacketID = E_UPDATE_SIGN; } - virtual cPacket* Clone() const { return new cPacket_UpdateSign( *this ); } - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - int m_PosX; - short m_PosY; - int m_PosZ; - AString m_Line1; - AString m_Line2; - AString m_Line3; - AString m_Line4; - - static const unsigned int c_Size = 1 + 4 + 2 + 4 + 2 + 2 + 2 + 2; // minimum size -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_UpdateSign : public cPacket +{ +public: + cPacket_UpdateSign() + : m_PosX( 0 ) + , m_PosY( 0 ) + , m_PosZ( 0 ) + { m_PacketID = E_UPDATE_SIGN; } + virtual cPacket* Clone() const { return new cPacket_UpdateSign( *this ); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + int m_PosX; + short m_PosY; + int m_PosZ; + AString m_Line1; + AString m_Line2; + AString m_Line3; + AString m_Line4; + + static const unsigned int c_Size = 1 + 4 + 2 + 4 + 2 + 2 + 2 + 2; // minimum size +}; + + + + diff --git a/source/packets/cPacket_UseEntity.cpp b/source/packets/cPacket_UseEntity.cpp index b131cb4fa..6f296e96b 100644 --- a/source/packets/cPacket_UseEntity.cpp +++ b/source/packets/cPacket_UseEntity.cpp @@ -1,21 +1,21 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_UseEntity.h" - - - - - -int cPacket_UseEntity::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadInteger, m_UniqueID, TotalBytes); - HANDLE_PACKET_READ(ReadInteger, m_TargetID, TotalBytes); - HANDLE_PACKET_READ(ReadBool, m_bLeftClick, TotalBytes); - return TotalBytes; -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_UseEntity.h" + + + + + +int cPacket_UseEntity::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadInteger, m_UniqueID, TotalBytes); + HANDLE_PACKET_READ(ReadInteger, m_TargetID, TotalBytes); + HANDLE_PACKET_READ(ReadBool, m_bLeftClick, TotalBytes); + return TotalBytes; +} + + + + diff --git a/source/packets/cPacket_UseEntity.h b/source/packets/cPacket_UseEntity.h index a81352664..7a35bd54c 100644 --- a/source/packets/cPacket_UseEntity.h +++ b/source/packets/cPacket_UseEntity.h @@ -1,31 +1,31 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_UseEntity : public cPacket -{ -public: - cPacket_UseEntity() - : m_UniqueID( 0 ) - , m_TargetID( 0 ) - , m_bLeftClick( false ) - { m_PacketID = E_USE_ENTITY; } - virtual cPacket* Clone() const { return new cPacket_UseEntity(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - - int m_UniqueID; - int m_TargetID; - bool m_bLeftClick; - - static const unsigned int c_Size = 1 + 4 + 4 + 1; -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_UseEntity : public cPacket +{ +public: + cPacket_UseEntity() + : m_UniqueID( 0 ) + , m_TargetID( 0 ) + , m_bLeftClick( false ) + { m_PacketID = E_USE_ENTITY; } + virtual cPacket* Clone() const { return new cPacket_UseEntity(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + + int m_UniqueID; + int m_TargetID; + bool m_bLeftClick; + + static const unsigned int c_Size = 1 + 4 + 4 + 1; +}; + + + + diff --git a/source/packets/cPacket_WholeInventory.cpp b/source/packets/cPacket_WholeInventory.cpp index 5e83f481f..3b8fa5cde 100644 --- a/source/packets/cPacket_WholeInventory.cpp +++ b/source/packets/cPacket_WholeInventory.cpp @@ -1,77 +1,77 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_WholeInventory.h" -#include "../cItem.h" -#include "../cInventory.h" -#include "../cWindow.h" -#include "cPacket_ItemData.h" - - - - - -cPacket_WholeInventory::cPacket_WholeInventory( const cPacket_WholeInventory & a_Clone ) -{ - m_PacketID = E_INVENTORY_WHOLE; - m_WindowID = a_Clone.m_WindowID; - m_Count = a_Clone.m_Count; - m_Items = new cItem[m_Count]; - memcpy( m_Items, a_Clone.m_Items, sizeof(cItem)*m_Count ); -} - - - - - -cPacket_WholeInventory::cPacket_WholeInventory( cInventory* a_Inventory ) -{ - m_PacketID = E_INVENTORY_WHOLE; - m_WindowID = 0; - m_Count = a_Inventory->c_NumSlots; - m_Items = new cItem[m_Count]; - memcpy( m_Items, a_Inventory->GetSlots(), sizeof(cItem)*m_Count ); -} - - - - - -cPacket_WholeInventory::cPacket_WholeInventory( cWindow* a_Window ) -{ - m_PacketID = E_INVENTORY_WHOLE; - m_WindowID = (char)a_Window->GetWindowID(); - m_Count = (short)a_Window->GetNumSlots(); - m_Items = new cItem[m_Count]; - memcpy( m_Items, a_Window->GetSlots(), sizeof(cItem)*m_Count ); -} - - - - - -cPacket_WholeInventory::~cPacket_WholeInventory() -{ - delete [] m_Items; -} - - - - - -void cPacket_WholeInventory::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendByte (a_Data, m_WindowID); - AppendShort(a_Data, m_Count); - - for (int j = 0; j < m_Count; j++) - { - cPacket_ItemData::AppendItem(a_Data, &(m_Items[j])); - } -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_WholeInventory.h" +#include "../cItem.h" +#include "../cInventory.h" +#include "../cWindow.h" +#include "cPacket_ItemData.h" + + + + + +cPacket_WholeInventory::cPacket_WholeInventory( const cPacket_WholeInventory & a_Clone ) +{ + m_PacketID = E_INVENTORY_WHOLE; + m_WindowID = a_Clone.m_WindowID; + m_Count = a_Clone.m_Count; + m_Items = new cItem[m_Count]; + memcpy( m_Items, a_Clone.m_Items, sizeof(cItem)*m_Count ); +} + + + + + +cPacket_WholeInventory::cPacket_WholeInventory( cInventory* a_Inventory ) +{ + m_PacketID = E_INVENTORY_WHOLE; + m_WindowID = 0; + m_Count = a_Inventory->c_NumSlots; + m_Items = new cItem[m_Count]; + memcpy( m_Items, a_Inventory->GetSlots(), sizeof(cItem)*m_Count ); +} + + + + + +cPacket_WholeInventory::cPacket_WholeInventory( cWindow* a_Window ) +{ + m_PacketID = E_INVENTORY_WHOLE; + m_WindowID = (char)a_Window->GetWindowID(); + m_Count = (short)a_Window->GetNumSlots(); + m_Items = new cItem[m_Count]; + memcpy( m_Items, a_Window->GetSlots(), sizeof(cItem)*m_Count ); +} + + + + + +cPacket_WholeInventory::~cPacket_WholeInventory() +{ + delete [] m_Items; +} + + + + + +void cPacket_WholeInventory::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendByte (a_Data, m_WindowID); + AppendShort(a_Data, m_Count); + + for (int j = 0; j < m_Count; j++) + { + cPacket_ItemData::AppendItem(a_Data, &(m_Items[j])); + } +} + + + + \ No newline at end of file diff --git a/source/packets/cPacket_WholeInventory.h b/source/packets/cPacket_WholeInventory.h index 5d895b367..3a9cc0a1b 100644 --- a/source/packets/cPacket_WholeInventory.h +++ b/source/packets/cPacket_WholeInventory.h @@ -1,47 +1,47 @@ - -#pragma once - -#include "cPacket.h" - -#include "../BlockID.h" - - - - - -class cInventory; -class cWindow; -class cItem; - - - - - -class cPacket_WholeInventory : public cPacket // full inventory [S -> C] ? -{ -public: - cPacket_WholeInventory( const cPacket_WholeInventory & a_Clone ); - cPacket_WholeInventory( cInventory* a_Inventory ); - cPacket_WholeInventory( cWindow* a_Window ); - ~cPacket_WholeInventory(); - cPacket_WholeInventory() - : m_WindowID( 0 ) - , m_Count( 0 ) - , m_Items( 0 ) - { m_PacketID = E_INVENTORY_WHOLE; } - - - virtual cPacket* Clone() const { return new cPacket_WholeInventory(*this); } - - virtual void Serialize(AString & a_Data) const override; - - char m_WindowID; // WTF? - short m_Count; // Number of items - cItem * m_Items; // Array of m_Count items - - static const unsigned int c_Size = 1 + 1 + 2; // Minimal size -}; - - - - + +#pragma once + +#include "cPacket.h" + +#include "../BlockID.h" + + + + + +class cInventory; +class cWindow; +class cItem; + + + + + +class cPacket_WholeInventory : public cPacket // full inventory [S -> C] ? +{ +public: + cPacket_WholeInventory( const cPacket_WholeInventory & a_Clone ); + cPacket_WholeInventory( cInventory* a_Inventory ); + cPacket_WholeInventory( cWindow* a_Window ); + ~cPacket_WholeInventory(); + cPacket_WholeInventory() + : m_WindowID( 0 ) + , m_Count( 0 ) + , m_Items( 0 ) + { m_PacketID = E_INVENTORY_WHOLE; } + + + virtual cPacket* Clone() const { return new cPacket_WholeInventory(*this); } + + virtual void Serialize(AString & a_Data) const override; + + char m_WindowID; // WTF? + short m_Count; // Number of items + cItem * m_Items; // Array of m_Count items + + static const unsigned int c_Size = 1 + 1 + 2; // Minimal size +}; + + + + diff --git a/source/packets/cPacket_WindowClick.cpp b/source/packets/cPacket_WindowClick.cpp index 0b2d18415..ac3191c28 100644 --- a/source/packets/cPacket_WindowClick.cpp +++ b/source/packets/cPacket_WindowClick.cpp @@ -1,43 +1,43 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_WindowClick.h" -#include "cPacket_WholeInventory.h" -#include "cPacket_ItemData.h" - - - - - -int cPacket_WindowClick::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadByte, m_WindowID, TotalBytes); - HANDLE_PACKET_READ(ReadShort, m_SlotNum, TotalBytes); - HANDLE_PACKET_READ(ReadByte, m_RightMouse, TotalBytes); - HANDLE_PACKET_READ(ReadShort, m_NumClicks, TotalBytes); - HANDLE_PACKET_READ(ReadBool, m_Bool, TotalBytes); - - // LOG("WindowClick: WindowID: %i; FromSlot: %i; Right/Le: %i; NumClick: %i", m_Type, m_SlotNum, m_RightMouse, m_NumClicks ); - - cPacket_ItemData Item; - - int res = Item.Parse(a_Data + TotalBytes, a_Size - TotalBytes); - if (res < 0) - { - return res; - } - TotalBytes += res; - - m_ItemID = Item.m_ItemID; - m_ItemCount = Item.m_ItemCount; - m_ItemUses = Item.m_ItemUses; - - m_EnchantNums = Item.m_EnchantNums; - - return TotalBytes; -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_WindowClick.h" +#include "cPacket_WholeInventory.h" +#include "cPacket_ItemData.h" + + + + + +int cPacket_WindowClick::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadByte, m_WindowID, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_SlotNum, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_RightMouse, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_NumClicks, TotalBytes); + HANDLE_PACKET_READ(ReadBool, m_Bool, TotalBytes); + + // LOG("WindowClick: WindowID: %i; FromSlot: %i; Right/Le: %i; NumClick: %i", m_Type, m_SlotNum, m_RightMouse, m_NumClicks ); + + cPacket_ItemData Item; + + int res = Item.Parse(a_Data + TotalBytes, a_Size - TotalBytes); + if (res < 0) + { + return res; + } + TotalBytes += res; + + m_ItemID = Item.m_ItemID; + m_ItemCount = Item.m_ItemCount; + m_ItemUses = Item.m_ItemUses; + + m_EnchantNums = Item.m_EnchantNums; + + return TotalBytes; +} + + + + diff --git a/source/packets/cPacket_WindowClick.h b/source/packets/cPacket_WindowClick.h index 09fc1d862..2d78d3f00 100644 --- a/source/packets/cPacket_WindowClick.h +++ b/source/packets/cPacket_WindowClick.h @@ -1,52 +1,52 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_WindowClick : public cPacket // [C -> S] -{ -public: - cPacket_WindowClick() - : m_WindowID( 0 ) - , m_SlotNum( 0 ) - , m_RightMouse( 0 ) - , m_NumClicks( 0 ) - , m_Bool( false ) - , m_ItemID( 0 ) - , m_ItemCount( 0 ) - , m_ItemUses( 0 ) - , m_EnchantNums(-1) - { m_PacketID = E_WINDOW_CLICK; } - virtual cPacket* Clone() const { return new cPacket_WindowClick(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - - char m_WindowID; - short m_SlotNum; // Slot - // 0 = craft result - // 1-4 = crafting table - // 5-8 = armor - // 9-35 = inventory - // 36-44 = Hot bar - - char m_RightMouse; // 0 = left 1 = Right mb - short m_NumClicks; // Num clicks - bool m_Bool; // unkown???????????? SHIFT clicked - - // Below = item - short m_ItemID; // if this is -1 the next stuff dont exist - char m_ItemCount; - short m_ItemUses; - - short m_EnchantNums; - - static const unsigned int c_Size = 1 + 1 + 2 + 1 + 2 + 2; // Minimal size ( +1+1 = max) -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_WindowClick : public cPacket // [C -> S] +{ +public: + cPacket_WindowClick() + : m_WindowID( 0 ) + , m_SlotNum( 0 ) + , m_RightMouse( 0 ) + , m_NumClicks( 0 ) + , m_Bool( false ) + , m_ItemID( 0 ) + , m_ItemCount( 0 ) + , m_ItemUses( 0 ) + , m_EnchantNums(-1) + { m_PacketID = E_WINDOW_CLICK; } + virtual cPacket* Clone() const { return new cPacket_WindowClick(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + + char m_WindowID; + short m_SlotNum; // Slot + // 0 = craft result + // 1-4 = crafting table + // 5-8 = armor + // 9-35 = inventory + // 36-44 = Hot bar + + char m_RightMouse; // 0 = left 1 = Right mb + short m_NumClicks; // Num clicks + bool m_Bool; // unkown???????????? SHIFT clicked + + // Below = item + short m_ItemID; // if this is -1 the next stuff dont exist + char m_ItemCount; + short m_ItemUses; + + short m_EnchantNums; + + static const unsigned int c_Size = 1 + 1 + 2 + 1 + 2 + 2; // Minimal size ( +1+1 = max) +}; + + + + diff --git a/source/packets/cPacket_WindowClose.cpp b/source/packets/cPacket_WindowClose.cpp index 25669bf79..f4361e4a1 100644 --- a/source/packets/cPacket_WindowClose.cpp +++ b/source/packets/cPacket_WindowClose.cpp @@ -1,29 +1,29 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_WindowClose.h" - - - - - -int cPacket_WindowClose::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadByte, m_Close, TotalBytes); - return TotalBytes; -} - - - - - -void cPacket_WindowClose::Serialize(AString & a_Data) const -{ - AppendByte(a_Data, m_PacketID); - AppendByte(a_Data, m_Close); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_WindowClose.h" + + + + + +int cPacket_WindowClose::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadByte, m_Close, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_WindowClose::Serialize(AString & a_Data) const +{ + AppendByte(a_Data, m_PacketID); + AppendByte(a_Data, m_Close); +} + + + + diff --git a/source/packets/cPacket_WindowClose.h b/source/packets/cPacket_WindowClose.h index 1063896ff..674c071d1 100644 --- a/source/packets/cPacket_WindowClose.h +++ b/source/packets/cPacket_WindowClose.h @@ -1,28 +1,28 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_WindowClose : public cPacket -{ -public: - cPacket_WindowClose() - : m_Close( 0 ) - { m_PacketID = E_WINDOW_CLOSE; } - virtual cPacket* Clone() const { return new cPacket_WindowClose(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - char m_Close; // m_Close == cWindow WindowType number - - static const unsigned int c_Size = 1 + 1; -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_WindowClose : public cPacket +{ +public: + cPacket_WindowClose() + : m_Close( 0 ) + { m_PacketID = E_WINDOW_CLOSE; } + virtual cPacket* Clone() const { return new cPacket_WindowClose(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + char m_Close; // m_Close == cWindow WindowType number + + static const unsigned int c_Size = 1 + 1; +}; + + + + diff --git a/source/packets/cPacket_WindowOpen.cpp b/source/packets/cPacket_WindowOpen.cpp index a5c3ade7e..8c4402139 100644 --- a/source/packets/cPacket_WindowOpen.cpp +++ b/source/packets/cPacket_WindowOpen.cpp @@ -1,21 +1,21 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_WindowOpen.h" - - - - - -void cPacket_WindowOpen::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendByte (a_Data, m_WindowID); - AppendByte (a_Data, m_InventoryType); - AppendString16(a_Data, m_WindowTitle); - AppendByte (a_Data, m_NumSlots); -} - - - - + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_WindowOpen.h" + + + + + +void cPacket_WindowOpen::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendByte (a_Data, m_WindowID); + AppendByte (a_Data, m_InventoryType); + AppendString16(a_Data, m_WindowTitle); + AppendByte (a_Data, m_NumSlots); +} + + + + diff --git a/source/packets/cPacket_WindowOpen.h b/source/packets/cPacket_WindowOpen.h index f3b225639..3896f5f02 100644 --- a/source/packets/cPacket_WindowOpen.h +++ b/source/packets/cPacket_WindowOpen.h @@ -1,32 +1,32 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_WindowOpen : public cPacket -{ -public: - cPacket_WindowOpen() - : m_WindowID( 0 ) - , m_InventoryType( 0 ) - , m_NumSlots( 0 ) - { m_PacketID = E_WINDOW_OPEN; } - virtual cPacket* Clone() const { return new cPacket_WindowOpen(*this); } - - virtual void Serialize(AString & a_Data) const override; - - char m_WindowID; - char m_InventoryType; - AString m_WindowTitle; - char m_NumSlots; - - static const unsigned int c_Size = 1 + 1 + 1 + 2 + 1; // + sizeof(string) -}; - - - - + +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_WindowOpen : public cPacket +{ +public: + cPacket_WindowOpen() + : m_WindowID( 0 ) + , m_InventoryType( 0 ) + , m_NumSlots( 0 ) + { m_PacketID = E_WINDOW_OPEN; } + virtual cPacket* Clone() const { return new cPacket_WindowOpen(*this); } + + virtual void Serialize(AString & a_Data) const override; + + char m_WindowID; + char m_InventoryType; + AString m_WindowTitle; + char m_NumSlots; + + static const unsigned int c_Size = 1 + 1 + 1 + 2 + 1; // + sizeof(string) +}; + + + + diff --git a/source/tolua_base.h b/source/tolua_base.h index 28708eb59..4f1038c09 100644 --- a/source/tolua_base.h +++ b/source/tolua_base.h @@ -1,128 +1,128 @@ -#ifndef TOLUA_BASE_H -#define TOLUA_BASE_H - -#pragma warning(disable:4800) // This file is ONLY included by Bindings.cpp and it throws lots of C4800 warnings - -#include "tolua++.h" - - - - - -class ToluaBase { - - int lua_instance; - -protected: - - lua_State* lua_state; - - void lua_stacktrace(lua_State* L) const - { - lua_Debug entry; - int depth = 0; - - while (lua_getstack(L, depth, &entry)) - { - lua_getinfo(L, "Sln", &entry); - - LOGERROR("%s(%d): %s", entry.short_src, entry.currentline, entry.name ? entry.name : "?"); - depth++; - } - } - - - bool report_errors(int status) const - { - if ( status!=0 ) - { - const char* s = lua_tostring(lua_state, -1); - LOGERROR("-- %s", s ); - //lua_pop(lua_state, 1); - LOGERROR("Stack:"); - lua_stacktrace( lua_state ); - return true; - } - return false; - } - - bool push_method(const char* name, lua_CFunction f) const { - - if (!lua_state) return false; - - lua_getref(lua_state, lua_instance); - lua_pushstring(lua_state, name); - //LOGINFO("1. push_method() Stack size: %i", lua_gettop( lua_state ) ); - lua_gettable(lua_state, -2); - //LOGINFO("2. push_method() Stack size: %i", lua_gettop( lua_state ) ); - - if (lua_isnil(lua_state, -1)) { - - // pop the table - lua_pop(lua_state, 2); - return false; - - } else { - - if (f) { - if (lua_iscfunction(lua_state, -1)) { - lua_pop(lua_state, 2); - return false; - }; - /* // not for now - lua_pushcfunction(lua_state, f); - if (lua_rawequal(lua_state, -1, -2)) { - - // avoid recursion, pop both functions and the table - lua_pop(lua_state, 3); - return false; - }; - - // pop f - lua_pop(lua_state, 1); - */ - }; - - // swap table with function - lua_insert(lua_state, -2); - }; - - return true; - }; - - void dbcall(lua_State* L, int nargs, int nresults) const { - - // using lua_call for now - int s = lua_pcall(L, nargs, nresults, 0); - report_errors( s ); - }; -public: - - int GetInstance() { return lua_instance; } - lua_State* GetLuaState() { return lua_state; } - - void tolua__set_instance(lua_State* L, lua_Object lo) { - - lua_state = L; - - lua_pushvalue(L, lo); - lua_instance = lua_ref(lua_state, 1); - }; - - ToluaBase() { - - lua_state = NULL; - }; - - ~ToluaBase() { - - if (lua_state) { - - lua_unref(lua_state, lua_instance); - }; - }; -}; - -#endif - - +#ifndef TOLUA_BASE_H +#define TOLUA_BASE_H + +#pragma warning(disable:4800) // This file is ONLY included by Bindings.cpp and it throws lots of C4800 warnings + +#include "tolua++.h" + + + + + +class ToluaBase { + + int lua_instance; + +protected: + + lua_State* lua_state; + + void lua_stacktrace(lua_State* L) const + { + lua_Debug entry; + int depth = 0; + + while (lua_getstack(L, depth, &entry)) + { + lua_getinfo(L, "Sln", &entry); + + LOGERROR("%s(%d): %s", entry.short_src, entry.currentline, entry.name ? entry.name : "?"); + depth++; + } + } + + + bool report_errors(int status) const + { + if ( status!=0 ) + { + const char* s = lua_tostring(lua_state, -1); + LOGERROR("-- %s", s ); + //lua_pop(lua_state, 1); + LOGERROR("Stack:"); + lua_stacktrace( lua_state ); + return true; + } + return false; + } + + bool push_method(const char* name, lua_CFunction f) const { + + if (!lua_state) return false; + + lua_getref(lua_state, lua_instance); + lua_pushstring(lua_state, name); + //LOGINFO("1. push_method() Stack size: %i", lua_gettop( lua_state ) ); + lua_gettable(lua_state, -2); + //LOGINFO("2. push_method() Stack size: %i", lua_gettop( lua_state ) ); + + if (lua_isnil(lua_state, -1)) { + + // pop the table + lua_pop(lua_state, 2); + return false; + + } else { + + if (f) { + if (lua_iscfunction(lua_state, -1)) { + lua_pop(lua_state, 2); + return false; + }; + /* // not for now + lua_pushcfunction(lua_state, f); + if (lua_rawequal(lua_state, -1, -2)) { + + // avoid recursion, pop both functions and the table + lua_pop(lua_state, 3); + return false; + }; + + // pop f + lua_pop(lua_state, 1); + */ + }; + + // swap table with function + lua_insert(lua_state, -2); + }; + + return true; + }; + + void dbcall(lua_State* L, int nargs, int nresults) const { + + // using lua_call for now + int s = lua_pcall(L, nargs, nresults, 0); + report_errors( s ); + }; +public: + + int GetInstance() { return lua_instance; } + lua_State* GetLuaState() { return lua_state; } + + void tolua__set_instance(lua_State* L, lua_Object lo) { + + lua_state = L; + + lua_pushvalue(L, lo); + lua_instance = lua_ref(lua_state, 1); + }; + + ToluaBase() { + + lua_state = NULL; + }; + + ~ToluaBase() { + + if (lua_state) { + + lua_unref(lua_state, lua_instance); + }; + }; +}; + +#endif + + diff --git a/squirrel_3_0_1_stable/include/sqstdaux.h b/squirrel_3_0_1_stable/include/sqstdaux.h index b90034823..c16b04373 100644 --- a/squirrel_3_0_1_stable/include/sqstdaux.h +++ b/squirrel_3_0_1_stable/include/sqstdaux.h @@ -1,16 +1,16 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTD_AUXLIB_H_ -#define _SQSTD_AUXLIB_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -SQUIRREL_API void sqstd_seterrorhandlers(HSQUIRRELVM v); -SQUIRREL_API void sqstd_printcallstack(HSQUIRRELVM v); - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /* _SQSTD_AUXLIB_H_ */ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_AUXLIB_H_ +#define _SQSTD_AUXLIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +SQUIRREL_API void sqstd_seterrorhandlers(HSQUIRRELVM v); +SQUIRREL_API void sqstd_printcallstack(HSQUIRRELVM v); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* _SQSTD_AUXLIB_H_ */ diff --git a/squirrel_3_0_1_stable/include/sqstdblob.h b/squirrel_3_0_1_stable/include/sqstdblob.h index eda4cc9c5..1d9a4cdc3 100644 --- a/squirrel_3_0_1_stable/include/sqstdblob.h +++ b/squirrel_3_0_1_stable/include/sqstdblob.h @@ -1,20 +1,20 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTDBLOB_H_ -#define _SQSTDBLOB_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -SQUIRREL_API SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size); -SQUIRREL_API SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr); -SQUIRREL_API SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx); - -SQUIRREL_API SQRESULT sqstd_register_bloblib(HSQUIRRELVM v); - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*_SQSTDBLOB_H_*/ - +/* see copyright notice in squirrel.h */ +#ifndef _SQSTDBLOB_H_ +#define _SQSTDBLOB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +SQUIRREL_API SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size); +SQUIRREL_API SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr); +SQUIRREL_API SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx); + +SQUIRREL_API SQRESULT sqstd_register_bloblib(HSQUIRRELVM v); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*_SQSTDBLOB_H_*/ + diff --git a/squirrel_3_0_1_stable/include/sqstdio.h b/squirrel_3_0_1_stable/include/sqstdio.h index 1174201a9..2cb744bcf 100644 --- a/squirrel_3_0_1_stable/include/sqstdio.h +++ b/squirrel_3_0_1_stable/include/sqstdio.h @@ -1,53 +1,53 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTDIO_H_ -#define _SQSTDIO_H_ - -#ifdef __cplusplus - -#define SQSTD_STREAM_TYPE_TAG 0x80000000 - -struct SQStream { - virtual SQInteger Read(void *buffer, SQInteger size) = 0; - virtual SQInteger Write(void *buffer, SQInteger size) = 0; - virtual SQInteger Flush() = 0; - virtual SQInteger Tell() = 0; - virtual SQInteger Len() = 0; - virtual SQInteger Seek(SQInteger offset, SQInteger origin) = 0; - virtual bool IsValid() = 0; - virtual bool EOS() = 0; -}; - -extern "C" { -#endif - -#define SQ_SEEK_CUR 0 -#define SQ_SEEK_END 1 -#define SQ_SEEK_SET 2 - -typedef void* SQFILE; - -SQUIRREL_API SQFILE sqstd_fopen(const SQChar *,const SQChar *); -SQUIRREL_API SQInteger sqstd_fread(SQUserPointer, SQInteger, SQInteger, SQFILE); -SQUIRREL_API SQInteger sqstd_fwrite(const SQUserPointer, SQInteger, SQInteger, SQFILE); -SQUIRREL_API SQInteger sqstd_fseek(SQFILE , SQInteger , SQInteger); -SQUIRREL_API SQInteger sqstd_ftell(SQFILE); -SQUIRREL_API SQInteger sqstd_fflush(SQFILE); -SQUIRREL_API SQInteger sqstd_fclose(SQFILE); -SQUIRREL_API SQInteger sqstd_feof(SQFILE); - -SQUIRREL_API SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own); -SQUIRREL_API SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file); - -//compiler helpers -SQUIRREL_API SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror); -SQUIRREL_API SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror); -SQUIRREL_API SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename); - -SQUIRREL_API SQRESULT sqstd_register_iolib(HSQUIRRELVM v); - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*_SQSTDIO_H_*/ - +/* see copyright notice in squirrel.h */ +#ifndef _SQSTDIO_H_ +#define _SQSTDIO_H_ + +#ifdef __cplusplus + +#define SQSTD_STREAM_TYPE_TAG 0x80000000 + +struct SQStream { + virtual SQInteger Read(void *buffer, SQInteger size) = 0; + virtual SQInteger Write(void *buffer, SQInteger size) = 0; + virtual SQInteger Flush() = 0; + virtual SQInteger Tell() = 0; + virtual SQInteger Len() = 0; + virtual SQInteger Seek(SQInteger offset, SQInteger origin) = 0; + virtual bool IsValid() = 0; + virtual bool EOS() = 0; +}; + +extern "C" { +#endif + +#define SQ_SEEK_CUR 0 +#define SQ_SEEK_END 1 +#define SQ_SEEK_SET 2 + +typedef void* SQFILE; + +SQUIRREL_API SQFILE sqstd_fopen(const SQChar *,const SQChar *); +SQUIRREL_API SQInteger sqstd_fread(SQUserPointer, SQInteger, SQInteger, SQFILE); +SQUIRREL_API SQInteger sqstd_fwrite(const SQUserPointer, SQInteger, SQInteger, SQFILE); +SQUIRREL_API SQInteger sqstd_fseek(SQFILE , SQInteger , SQInteger); +SQUIRREL_API SQInteger sqstd_ftell(SQFILE); +SQUIRREL_API SQInteger sqstd_fflush(SQFILE); +SQUIRREL_API SQInteger sqstd_fclose(SQFILE); +SQUIRREL_API SQInteger sqstd_feof(SQFILE); + +SQUIRREL_API SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own); +SQUIRREL_API SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file); + +//compiler helpers +SQUIRREL_API SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror); +SQUIRREL_API SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror); +SQUIRREL_API SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename); + +SQUIRREL_API SQRESULT sqstd_register_iolib(HSQUIRRELVM v); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*_SQSTDIO_H_*/ + diff --git a/squirrel_3_0_1_stable/include/sqstdmath.h b/squirrel_3_0_1_stable/include/sqstdmath.h index 420f2ce67..65de6fd72 100644 --- a/squirrel_3_0_1_stable/include/sqstdmath.h +++ b/squirrel_3_0_1_stable/include/sqstdmath.h @@ -1,15 +1,15 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTD_MATH_H_ -#define _SQSTD_MATH_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -SQUIRREL_API SQRESULT sqstd_register_mathlib(HSQUIRRELVM v); - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*_SQSTD_MATH_H_*/ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_MATH_H_ +#define _SQSTD_MATH_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +SQUIRREL_API SQRESULT sqstd_register_mathlib(HSQUIRRELVM v); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*_SQSTD_MATH_H_*/ diff --git a/squirrel_3_0_1_stable/include/sqstdstring.h b/squirrel_3_0_1_stable/include/sqstdstring.h index 771c2f658..3c3bce826 100644 --- a/squirrel_3_0_1_stable/include/sqstdstring.h +++ b/squirrel_3_0_1_stable/include/sqstdstring.h @@ -1,33 +1,33 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTD_STRING_H_ -#define _SQSTD_STRING_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef unsigned int SQRexBool; -typedef struct SQRex SQRex; - -typedef struct { - const SQChar *begin; - SQInteger len; -} SQRexMatch; - -SQUIRREL_API SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error); -SQUIRREL_API void sqstd_rex_free(SQRex *exp); -SQUIRREL_API SQBool sqstd_rex_match(SQRex* exp,const SQChar* text); -SQUIRREL_API SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end); -SQUIRREL_API SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end); -SQUIRREL_API SQInteger sqstd_rex_getsubexpcount(SQRex* exp); -SQUIRREL_API SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp); - -SQUIRREL_API SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output); - -SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v); - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*_SQSTD_STRING_H_*/ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_STRING_H_ +#define _SQSTD_STRING_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned int SQRexBool; +typedef struct SQRex SQRex; + +typedef struct { + const SQChar *begin; + SQInteger len; +} SQRexMatch; + +SQUIRREL_API SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error); +SQUIRREL_API void sqstd_rex_free(SQRex *exp); +SQUIRREL_API SQBool sqstd_rex_match(SQRex* exp,const SQChar* text); +SQUIRREL_API SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end); +SQUIRREL_API SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end); +SQUIRREL_API SQInteger sqstd_rex_getsubexpcount(SQRex* exp); +SQUIRREL_API SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp); + +SQUIRREL_API SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output); + +SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*_SQSTD_STRING_H_*/ diff --git a/squirrel_3_0_1_stable/include/sqstdsystem.h b/squirrel_3_0_1_stable/include/sqstdsystem.h index daefa0fd5..b155a91f8 100644 --- a/squirrel_3_0_1_stable/include/sqstdsystem.h +++ b/squirrel_3_0_1_stable/include/sqstdsystem.h @@ -1,15 +1,15 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTD_SYSTEMLIB_H_ -#define _SQSTD_SYSTEMLIB_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -SQUIRREL_API SQInteger sqstd_register_systemlib(HSQUIRRELVM v); - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /* _SQSTD_SYSTEMLIB_H_ */ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_SYSTEMLIB_H_ +#define _SQSTD_SYSTEMLIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +SQUIRREL_API SQInteger sqstd_register_systemlib(HSQUIRRELVM v); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* _SQSTD_SYSTEMLIB_H_ */ diff --git a/squirrel_3_0_1_stable/include/squirrel.h b/squirrel_3_0_1_stable/include/squirrel.h index baaaf39c5..e030a31da 100644 --- a/squirrel_3_0_1_stable/include/squirrel.h +++ b/squirrel_3_0_1_stable/include/squirrel.h @@ -1,500 +1,500 @@ -/* -Copyright (c) 2003-2011 Alberto Demichelis - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ -#ifndef _SQUIRREL_H_ -#define _SQUIRREL_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef SQUIRREL_API -#define SQUIRREL_API extern -#endif - -#if (defined(_WIN64) || defined(_LP64)) -#ifndef _SQ64 -#define _SQ64 -#endif -#endif - -#ifdef _SQ64 - -#ifdef _MSC_VER -typedef __int64 SQInteger; -typedef unsigned __int64 SQUnsignedInteger; -typedef unsigned __int64 SQHash; /*should be the same size of a pointer*/ -#else -typedef long long SQInteger; -typedef unsigned long long SQUnsignedInteger; -typedef unsigned long long SQHash; /*should be the same size of a pointer*/ -#endif -typedef int SQInt32; -typedef unsigned int SQUnsignedInteger32; -#else -typedef int SQInteger; -typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/ -typedef unsigned int SQUnsignedInteger32; /*must be 32 bits(also on 64bits processors)*/ -typedef unsigned int SQUnsignedInteger; -typedef unsigned int SQHash; /*should be the same size of a pointer*/ -#endif - - -#ifdef SQUSEDOUBLE -typedef double SQFloat; -#else -typedef float SQFloat; -#endif - -#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64) -#ifdef _MSC_VER -typedef __int64 SQRawObjectVal; //must be 64bits -#else -typedef long long SQRawObjectVal; //must be 64bits -#endif -#define SQ_OBJECT_RAWINIT() { _unVal.raw = 0; } -#else -typedef SQUnsignedInteger SQRawObjectVal; //is 32 bits on 32 bits builds and 64 bits otherwise -#define SQ_OBJECT_RAWINIT() -#endif - -#ifndef SQ_ALIGNMENT // SQ_ALIGNMENT shall be less than or equal to SQ_MALLOC alignments, and its value shall be power of 2. -#if defined(SQUSEDOUBLE) || defined(_SQ64) -#define SQ_ALIGNMENT 8 -#else -#define SQ_ALIGNMENT 4 -#endif -#endif - -typedef void* SQUserPointer; -typedef SQUnsignedInteger SQBool; -typedef SQInteger SQRESULT; - -#define SQTrue (1) -#define SQFalse (0) - -struct SQVM; -struct SQTable; -struct SQArray; -struct SQString; -struct SQClosure; -struct SQGenerator; -struct SQNativeClosure; -struct SQUserData; -struct SQFunctionProto; -struct SQRefCounted; -struct SQClass; -struct SQInstance; -struct SQDelegable; -struct SQOuter; - -#ifdef _UNICODE -#define SQUNICODE -#endif - -#ifdef SQUNICODE -#if (defined(_MSC_VER) && _MSC_VER >= 1400) // 1400 = VS8 - -#if !defined(_NATIVE_WCHAR_T_DEFINED) //this is if the compiler considers wchar_t as native type -#define wchar_t unsigned short -#endif - -#else -typedef unsigned short wchar_t; -#endif - -typedef wchar_t SQChar; -#define _SC(a) L##a -#define scstrcmp wcscmp -#define scsprintf swprintf -#define scstrlen wcslen -#define scstrtod wcstod -#ifdef _SQ64 -#define scstrtol _wcstoi64 -#else -#define scstrtol wcstol -#endif -#define scatoi _wtoi -#define scstrtoul wcstoul -#define scvsprintf vswprintf -#define scstrstr wcsstr -#define scisspace iswspace -#define scisdigit iswdigit -#define scisxdigit iswxdigit -#define scisalpha iswalpha -#define sciscntrl iswcntrl -#define scisalnum iswalnum -#define scprintf wprintf -#define MAX_CHAR 0xFFFF -#else -typedef char SQChar; -#define _SC(a) a -#define scstrcmp strcmp -#define scsprintf sprintf -#define scstrlen strlen -#define scstrtod strtod -#ifdef _SQ64 -#ifdef _MSC_VER -#define scstrtol _strtoi64 -#else -#define scstrtol strtoll -#endif -#else -#define scstrtol strtol -#endif -#define scatoi atoi -#define scstrtoul strtoul -#define scvsprintf vsprintf -#define scstrstr strstr -#define scisspace isspace -#define scisdigit isdigit -#define scisxdigit isxdigit -#define sciscntrl iscntrl -#define scisalpha isalpha -#define scisalnum isalnum -#define scprintf printf -#define MAX_CHAR 0xFF -#endif - -#ifdef _SQ64 -#define _PRINT_INT_PREC _SC("ll") -#define _PRINT_INT_FMT _SC("%lld") -#else -#define _PRINT_INT_FMT _SC("%d") -#endif - -#define SQUIRREL_VERSION _SC("Squirrel 3.0.1 stable") -#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2011 Alberto Demichelis") -#define SQUIRREL_AUTHOR _SC("Alberto Demichelis") -#define SQUIRREL_VERSION_NUMBER 301 - -#define SQ_VMSTATE_IDLE 0 -#define SQ_VMSTATE_RUNNING 1 -#define SQ_VMSTATE_SUSPENDED 2 - -#define SQUIRREL_EOB 0 -#define SQ_BYTECODE_STREAM_TAG 0xFAFA - -#define SQOBJECT_REF_COUNTED 0x08000000 -#define SQOBJECT_NUMERIC 0x04000000 -#define SQOBJECT_DELEGABLE 0x02000000 -#define SQOBJECT_CANBEFALSE 0x01000000 - -#define SQ_MATCHTYPEMASKSTRING (-99999) - -#define _RT_MASK 0x00FFFFFF -#define _RAW_TYPE(type) (type&_RT_MASK) - -#define _RT_NULL 0x00000001 -#define _RT_INTEGER 0x00000002 -#define _RT_FLOAT 0x00000004 -#define _RT_BOOL 0x00000008 -#define _RT_STRING 0x00000010 -#define _RT_TABLE 0x00000020 -#define _RT_ARRAY 0x00000040 -#define _RT_USERDATA 0x00000080 -#define _RT_CLOSURE 0x00000100 -#define _RT_NATIVECLOSURE 0x00000200 -#define _RT_GENERATOR 0x00000400 -#define _RT_USERPOINTER 0x00000800 -#define _RT_THREAD 0x00001000 -#define _RT_FUNCPROTO 0x00002000 -#define _RT_CLASS 0x00004000 -#define _RT_INSTANCE 0x00008000 -#define _RT_WEAKREF 0x00010000 -#define _RT_OUTER 0x00020000 - -typedef enum tagSQObjectType{ - OT_NULL = (_RT_NULL|SQOBJECT_CANBEFALSE), - OT_INTEGER = (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE), - OT_FLOAT = (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE), - OT_BOOL = (_RT_BOOL|SQOBJECT_CANBEFALSE), - OT_STRING = (_RT_STRING|SQOBJECT_REF_COUNTED), - OT_TABLE = (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE), - OT_ARRAY = (_RT_ARRAY|SQOBJECT_REF_COUNTED), - OT_USERDATA = (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE), - OT_CLOSURE = (_RT_CLOSURE|SQOBJECT_REF_COUNTED), - OT_NATIVECLOSURE = (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED), - OT_GENERATOR = (_RT_GENERATOR|SQOBJECT_REF_COUNTED), - OT_USERPOINTER = _RT_USERPOINTER, - OT_THREAD = (_RT_THREAD|SQOBJECT_REF_COUNTED) , - OT_FUNCPROTO = (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only - OT_CLASS = (_RT_CLASS|SQOBJECT_REF_COUNTED), - OT_INSTANCE = (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE), - OT_WEAKREF = (_RT_WEAKREF|SQOBJECT_REF_COUNTED), - OT_OUTER = (_RT_OUTER|SQOBJECT_REF_COUNTED) //internal usage only -}SQObjectType; - -#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED) - - -typedef union tagSQObjectValue -{ - struct SQTable *pTable; - struct SQArray *pArray; - struct SQClosure *pClosure; - struct SQOuter *pOuter; - struct SQGenerator *pGenerator; - struct SQNativeClosure *pNativeClosure; - struct SQString *pString; - struct SQUserData *pUserData; - SQInteger nInteger; - SQFloat fFloat; - SQUserPointer pUserPointer; - struct SQFunctionProto *pFunctionProto; - struct SQRefCounted *pRefCounted; - struct SQDelegable *pDelegable; - struct SQVM *pThread; - struct SQClass *pClass; - struct SQInstance *pInstance; - struct SQWeakRef *pWeakRef; - SQRawObjectVal raw; -}SQObjectValue; - - -typedef struct tagSQObject -{ - SQObjectType _type; - SQObjectValue _unVal; -}SQObject; - -typedef struct tagSQMemberHandle{ - SQBool _static; - SQInteger _index; -}SQMemberHandle; - -typedef struct tagSQStackInfos{ - const SQChar* funcname; - const SQChar* source; - SQInteger line; -}SQStackInfos; - -typedef struct SQVM* HSQUIRRELVM; -typedef SQObject HSQOBJECT; -typedef SQMemberHandle HSQMEMBERHANDLE; -typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM); -typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size); -typedef void (*SQCOMPILERERROR)(HSQUIRRELVM,const SQChar * /*desc*/,const SQChar * /*source*/,SQInteger /*line*/,SQInteger /*column*/); -typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM,const SQChar * ,...); -typedef void (*SQDEBUGHOOK)(HSQUIRRELVM /*v*/, SQInteger /*type*/, const SQChar * /*sourcename*/, SQInteger /*line*/, const SQChar * /*funcname*/); -typedef SQInteger (*SQWRITEFUNC)(SQUserPointer,SQUserPointer,SQInteger); -typedef SQInteger (*SQREADFUNC)(SQUserPointer,SQUserPointer,SQInteger); - -typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer); - -typedef struct tagSQRegFunction{ - const SQChar *name; - SQFUNCTION f; - SQInteger nparamscheck; - const SQChar *typemask; -}SQRegFunction; - -typedef struct tagSQFunctionInfo { - SQUserPointer funcid; - const SQChar *name; - const SQChar *source; -}SQFunctionInfo; - -/*vm*/ -SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize); -SQUIRREL_API HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize); -SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v); -SQUIRREL_API void sq_close(HSQUIRRELVM v); -SQUIRREL_API void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p); -SQUIRREL_API SQUserPointer sq_getforeignptr(HSQUIRRELVM v); -SQUIRREL_API void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc,SQPRINTFUNCTION errfunc); -SQUIRREL_API SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v); -SQUIRREL_API SQPRINTFUNCTION sq_geterrorfunc(HSQUIRRELVM v); -SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v); -SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool resumedret,SQBool retval,SQBool raiseerror,SQBool throwerror); -SQUIRREL_API SQInteger sq_getvmstate(HSQUIRRELVM v); - -/*compiler*/ -SQUIRREL_API SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror); -SQUIRREL_API SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror); -SQUIRREL_API void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable); -SQUIRREL_API void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable); -SQUIRREL_API void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f); - -/*stack operations*/ -SQUIRREL_API void sq_push(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API void sq_pop(HSQUIRRELVM v,SQInteger nelemstopop); -SQUIRREL_API void sq_poptop(HSQUIRRELVM v); -SQUIRREL_API void sq_remove(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API SQInteger sq_gettop(HSQUIRRELVM v); -SQUIRREL_API void sq_settop(HSQUIRRELVM v,SQInteger newtop); -SQUIRREL_API SQRESULT sq_reservestack(HSQUIRRELVM v,SQInteger nsize); -SQUIRREL_API SQInteger sq_cmp(HSQUIRRELVM v); -SQUIRREL_API void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx); - -/*object creation handling*/ -SQUIRREL_API SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size); -SQUIRREL_API void sq_newtable(HSQUIRRELVM v); -SQUIRREL_API void sq_newtableex(HSQUIRRELVM v,SQInteger initialcapacity); -SQUIRREL_API void sq_newarray(HSQUIRRELVM v,SQInteger size); -SQUIRREL_API void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars); -SQUIRREL_API SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask); -SQUIRREL_API SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len); -SQUIRREL_API void sq_pushfloat(HSQUIRRELVM v,SQFloat f); -SQUIRREL_API void sq_pushinteger(HSQUIRRELVM v,SQInteger n); -SQUIRREL_API void sq_pushbool(HSQUIRRELVM v,SQBool b); -SQUIRREL_API void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p); -SQUIRREL_API void sq_pushnull(HSQUIRRELVM v); -SQUIRREL_API SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API SQInteger sq_getsize(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API SQBool sq_instanceof(HSQUIRRELVM v); -SQUIRREL_API SQRESULT sq_tostring(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b); -SQUIRREL_API SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c); -SQUIRREL_API SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i); -SQUIRREL_API SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f); -SQUIRREL_API SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b); -SQUIRREL_API SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread); -SQUIRREL_API SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p); -SQUIRREL_API SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag); -SQUIRREL_API SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag); -SQUIRREL_API SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag); -SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook); -SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize); -SQUIRREL_API SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger idx,SQFunctionInfo *fi); -SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars); -SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name); -SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p); -SQUIRREL_API SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag); -SQUIRREL_API SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize); -SQUIRREL_API SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase); -SQUIRREL_API SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API void sq_weakref(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t); -SQUIRREL_API SQRESULT sq_getmemberhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle); -SQUIRREL_API SQRESULT sq_getbyhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle); -SQUIRREL_API SQRESULT sq_setbyhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle); - -/*object manipulation*/ -SQUIRREL_API void sq_pushroottable(HSQUIRRELVM v); -SQUIRREL_API void sq_pushregistrytable(HSQUIRRELVM v); -SQUIRREL_API void sq_pushconsttable(HSQUIRRELVM v); -SQUIRREL_API SQRESULT sq_setroottable(HSQUIRRELVM v); -SQUIRREL_API SQRESULT sq_setconsttable(HSQUIRRELVM v); -SQUIRREL_API SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic); -SQUIRREL_API SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval); -SQUIRREL_API SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval); -SQUIRREL_API SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval); -SQUIRREL_API SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize); -SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx); -SQUIRREL_API SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos); -SQUIRREL_API SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval); -SQUIRREL_API SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx); -SQUIRREL_API SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx); - -/*calls*/ -SQUIRREL_API SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror); -SQUIRREL_API SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror); -SQUIRREL_API const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx); -SQUIRREL_API SQRESULT sq_getcallee(HSQUIRRELVM v); -SQUIRREL_API const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval); -SQUIRREL_API SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err); -SQUIRREL_API SQRESULT sq_throwobject(HSQUIRRELVM v); -SQUIRREL_API void sq_reseterror(HSQUIRRELVM v); -SQUIRREL_API void sq_getlasterror(HSQUIRRELVM v); - -/*raw object handling*/ -SQUIRREL_API SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po); -SQUIRREL_API void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj); -SQUIRREL_API void sq_addref(HSQUIRRELVM v,HSQOBJECT *po); -SQUIRREL_API SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po); -SQUIRREL_API SQUnsignedInteger sq_getrefcount(HSQUIRRELVM v,HSQOBJECT *po); -SQUIRREL_API void sq_resetobject(HSQOBJECT *po); -SQUIRREL_API const SQChar *sq_objtostring(const HSQOBJECT *o); -SQUIRREL_API SQBool sq_objtobool(const HSQOBJECT *o); -SQUIRREL_API SQInteger sq_objtointeger(const HSQOBJECT *o); -SQUIRREL_API SQFloat sq_objtofloat(const HSQOBJECT *o); -SQUIRREL_API SQUserPointer sq_objtouserpointer(const HSQOBJECT *o); -SQUIRREL_API SQRESULT sq_getobjtypetag(const HSQOBJECT *o,SQUserPointer * typetag); - -/*GC*/ -SQUIRREL_API SQInteger sq_collectgarbage(HSQUIRRELVM v); -SQUIRREL_API SQRESULT sq_resurrectunreachable(HSQUIRRELVM v); - -/*serialization*/ -SQUIRREL_API SQRESULT sq_writeclosure(HSQUIRRELVM vm,SQWRITEFUNC writef,SQUserPointer up); -SQUIRREL_API SQRESULT sq_readclosure(HSQUIRRELVM vm,SQREADFUNC readf,SQUserPointer up); - -/*mem allocation*/ -SQUIRREL_API void *sq_malloc(SQUnsignedInteger size); -SQUIRREL_API void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize); -SQUIRREL_API void sq_free(void *p,SQUnsignedInteger size); - -/*debug*/ -SQUIRREL_API SQRESULT sq_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos *si); -SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v); -SQUIRREL_API void sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook); - -/*UTILITY MACRO*/ -#define sq_isnumeric(o) ((o)._type&SQOBJECT_NUMERIC) -#define sq_istable(o) ((o)._type==OT_TABLE) -#define sq_isarray(o) ((o)._type==OT_ARRAY) -#define sq_isfunction(o) ((o)._type==OT_FUNCPROTO) -#define sq_isclosure(o) ((o)._type==OT_CLOSURE) -#define sq_isgenerator(o) ((o)._type==OT_GENERATOR) -#define sq_isnativeclosure(o) ((o)._type==OT_NATIVECLOSURE) -#define sq_isstring(o) ((o)._type==OT_STRING) -#define sq_isinteger(o) ((o)._type==OT_INTEGER) -#define sq_isfloat(o) ((o)._type==OT_FLOAT) -#define sq_isuserpointer(o) ((o)._type==OT_USERPOINTER) -#define sq_isuserdata(o) ((o)._type==OT_USERDATA) -#define sq_isthread(o) ((o)._type==OT_THREAD) -#define sq_isnull(o) ((o)._type==OT_NULL) -#define sq_isclass(o) ((o)._type==OT_CLASS) -#define sq_isinstance(o) ((o)._type==OT_INSTANCE) -#define sq_isbool(o) ((o)._type==OT_BOOL) -#define sq_isweakref(o) ((o)._type==OT_WEAKREF) -#define sq_type(o) ((o)._type) - -/* deprecated */ -#define sq_createslot(v,n) sq_newslot(v,n,SQFalse) - -#define SQ_OK (0) -#define SQ_ERROR (-1) - -#define SQ_FAILED(res) (res<0) -#define SQ_SUCCEEDED(res) (res>=0) - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*_SQUIRREL_H_*/ +/* +Copyright (c) 2003-2011 Alberto Demichelis + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +#ifndef _SQUIRREL_H_ +#define _SQUIRREL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SQUIRREL_API +#define SQUIRREL_API extern +#endif + +#if (defined(_WIN64) || defined(_LP64)) +#ifndef _SQ64 +#define _SQ64 +#endif +#endif + +#ifdef _SQ64 + +#ifdef _MSC_VER +typedef __int64 SQInteger; +typedef unsigned __int64 SQUnsignedInteger; +typedef unsigned __int64 SQHash; /*should be the same size of a pointer*/ +#else +typedef long long SQInteger; +typedef unsigned long long SQUnsignedInteger; +typedef unsigned long long SQHash; /*should be the same size of a pointer*/ +#endif +typedef int SQInt32; +typedef unsigned int SQUnsignedInteger32; +#else +typedef int SQInteger; +typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/ +typedef unsigned int SQUnsignedInteger32; /*must be 32 bits(also on 64bits processors)*/ +typedef unsigned int SQUnsignedInteger; +typedef unsigned int SQHash; /*should be the same size of a pointer*/ +#endif + + +#ifdef SQUSEDOUBLE +typedef double SQFloat; +#else +typedef float SQFloat; +#endif + +#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64) +#ifdef _MSC_VER +typedef __int64 SQRawObjectVal; //must be 64bits +#else +typedef long long SQRawObjectVal; //must be 64bits +#endif +#define SQ_OBJECT_RAWINIT() { _unVal.raw = 0; } +#else +typedef SQUnsignedInteger SQRawObjectVal; //is 32 bits on 32 bits builds and 64 bits otherwise +#define SQ_OBJECT_RAWINIT() +#endif + +#ifndef SQ_ALIGNMENT // SQ_ALIGNMENT shall be less than or equal to SQ_MALLOC alignments, and its value shall be power of 2. +#if defined(SQUSEDOUBLE) || defined(_SQ64) +#define SQ_ALIGNMENT 8 +#else +#define SQ_ALIGNMENT 4 +#endif +#endif + +typedef void* SQUserPointer; +typedef SQUnsignedInteger SQBool; +typedef SQInteger SQRESULT; + +#define SQTrue (1) +#define SQFalse (0) + +struct SQVM; +struct SQTable; +struct SQArray; +struct SQString; +struct SQClosure; +struct SQGenerator; +struct SQNativeClosure; +struct SQUserData; +struct SQFunctionProto; +struct SQRefCounted; +struct SQClass; +struct SQInstance; +struct SQDelegable; +struct SQOuter; + +#ifdef _UNICODE +#define SQUNICODE +#endif + +#ifdef SQUNICODE +#if (defined(_MSC_VER) && _MSC_VER >= 1400) // 1400 = VS8 + +#if !defined(_NATIVE_WCHAR_T_DEFINED) //this is if the compiler considers wchar_t as native type +#define wchar_t unsigned short +#endif + +#else +typedef unsigned short wchar_t; +#endif + +typedef wchar_t SQChar; +#define _SC(a) L##a +#define scstrcmp wcscmp +#define scsprintf swprintf +#define scstrlen wcslen +#define scstrtod wcstod +#ifdef _SQ64 +#define scstrtol _wcstoi64 +#else +#define scstrtol wcstol +#endif +#define scatoi _wtoi +#define scstrtoul wcstoul +#define scvsprintf vswprintf +#define scstrstr wcsstr +#define scisspace iswspace +#define scisdigit iswdigit +#define scisxdigit iswxdigit +#define scisalpha iswalpha +#define sciscntrl iswcntrl +#define scisalnum iswalnum +#define scprintf wprintf +#define MAX_CHAR 0xFFFF +#else +typedef char SQChar; +#define _SC(a) a +#define scstrcmp strcmp +#define scsprintf sprintf +#define scstrlen strlen +#define scstrtod strtod +#ifdef _SQ64 +#ifdef _MSC_VER +#define scstrtol _strtoi64 +#else +#define scstrtol strtoll +#endif +#else +#define scstrtol strtol +#endif +#define scatoi atoi +#define scstrtoul strtoul +#define scvsprintf vsprintf +#define scstrstr strstr +#define scisspace isspace +#define scisdigit isdigit +#define scisxdigit isxdigit +#define sciscntrl iscntrl +#define scisalpha isalpha +#define scisalnum isalnum +#define scprintf printf +#define MAX_CHAR 0xFF +#endif + +#ifdef _SQ64 +#define _PRINT_INT_PREC _SC("ll") +#define _PRINT_INT_FMT _SC("%lld") +#else +#define _PRINT_INT_FMT _SC("%d") +#endif + +#define SQUIRREL_VERSION _SC("Squirrel 3.0.1 stable") +#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2011 Alberto Demichelis") +#define SQUIRREL_AUTHOR _SC("Alberto Demichelis") +#define SQUIRREL_VERSION_NUMBER 301 + +#define SQ_VMSTATE_IDLE 0 +#define SQ_VMSTATE_RUNNING 1 +#define SQ_VMSTATE_SUSPENDED 2 + +#define SQUIRREL_EOB 0 +#define SQ_BYTECODE_STREAM_TAG 0xFAFA + +#define SQOBJECT_REF_COUNTED 0x08000000 +#define SQOBJECT_NUMERIC 0x04000000 +#define SQOBJECT_DELEGABLE 0x02000000 +#define SQOBJECT_CANBEFALSE 0x01000000 + +#define SQ_MATCHTYPEMASKSTRING (-99999) + +#define _RT_MASK 0x00FFFFFF +#define _RAW_TYPE(type) (type&_RT_MASK) + +#define _RT_NULL 0x00000001 +#define _RT_INTEGER 0x00000002 +#define _RT_FLOAT 0x00000004 +#define _RT_BOOL 0x00000008 +#define _RT_STRING 0x00000010 +#define _RT_TABLE 0x00000020 +#define _RT_ARRAY 0x00000040 +#define _RT_USERDATA 0x00000080 +#define _RT_CLOSURE 0x00000100 +#define _RT_NATIVECLOSURE 0x00000200 +#define _RT_GENERATOR 0x00000400 +#define _RT_USERPOINTER 0x00000800 +#define _RT_THREAD 0x00001000 +#define _RT_FUNCPROTO 0x00002000 +#define _RT_CLASS 0x00004000 +#define _RT_INSTANCE 0x00008000 +#define _RT_WEAKREF 0x00010000 +#define _RT_OUTER 0x00020000 + +typedef enum tagSQObjectType{ + OT_NULL = (_RT_NULL|SQOBJECT_CANBEFALSE), + OT_INTEGER = (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE), + OT_FLOAT = (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE), + OT_BOOL = (_RT_BOOL|SQOBJECT_CANBEFALSE), + OT_STRING = (_RT_STRING|SQOBJECT_REF_COUNTED), + OT_TABLE = (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE), + OT_ARRAY = (_RT_ARRAY|SQOBJECT_REF_COUNTED), + OT_USERDATA = (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE), + OT_CLOSURE = (_RT_CLOSURE|SQOBJECT_REF_COUNTED), + OT_NATIVECLOSURE = (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED), + OT_GENERATOR = (_RT_GENERATOR|SQOBJECT_REF_COUNTED), + OT_USERPOINTER = _RT_USERPOINTER, + OT_THREAD = (_RT_THREAD|SQOBJECT_REF_COUNTED) , + OT_FUNCPROTO = (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only + OT_CLASS = (_RT_CLASS|SQOBJECT_REF_COUNTED), + OT_INSTANCE = (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE), + OT_WEAKREF = (_RT_WEAKREF|SQOBJECT_REF_COUNTED), + OT_OUTER = (_RT_OUTER|SQOBJECT_REF_COUNTED) //internal usage only +}SQObjectType; + +#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED) + + +typedef union tagSQObjectValue +{ + struct SQTable *pTable; + struct SQArray *pArray; + struct SQClosure *pClosure; + struct SQOuter *pOuter; + struct SQGenerator *pGenerator; + struct SQNativeClosure *pNativeClosure; + struct SQString *pString; + struct SQUserData *pUserData; + SQInteger nInteger; + SQFloat fFloat; + SQUserPointer pUserPointer; + struct SQFunctionProto *pFunctionProto; + struct SQRefCounted *pRefCounted; + struct SQDelegable *pDelegable; + struct SQVM *pThread; + struct SQClass *pClass; + struct SQInstance *pInstance; + struct SQWeakRef *pWeakRef; + SQRawObjectVal raw; +}SQObjectValue; + + +typedef struct tagSQObject +{ + SQObjectType _type; + SQObjectValue _unVal; +}SQObject; + +typedef struct tagSQMemberHandle{ + SQBool _static; + SQInteger _index; +}SQMemberHandle; + +typedef struct tagSQStackInfos{ + const SQChar* funcname; + const SQChar* source; + SQInteger line; +}SQStackInfos; + +typedef struct SQVM* HSQUIRRELVM; +typedef SQObject HSQOBJECT; +typedef SQMemberHandle HSQMEMBERHANDLE; +typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM); +typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size); +typedef void (*SQCOMPILERERROR)(HSQUIRRELVM,const SQChar * /*desc*/,const SQChar * /*source*/,SQInteger /*line*/,SQInteger /*column*/); +typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM,const SQChar * ,...); +typedef void (*SQDEBUGHOOK)(HSQUIRRELVM /*v*/, SQInteger /*type*/, const SQChar * /*sourcename*/, SQInteger /*line*/, const SQChar * /*funcname*/); +typedef SQInteger (*SQWRITEFUNC)(SQUserPointer,SQUserPointer,SQInteger); +typedef SQInteger (*SQREADFUNC)(SQUserPointer,SQUserPointer,SQInteger); + +typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer); + +typedef struct tagSQRegFunction{ + const SQChar *name; + SQFUNCTION f; + SQInteger nparamscheck; + const SQChar *typemask; +}SQRegFunction; + +typedef struct tagSQFunctionInfo { + SQUserPointer funcid; + const SQChar *name; + const SQChar *source; +}SQFunctionInfo; + +/*vm*/ +SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize); +SQUIRREL_API HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize); +SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v); +SQUIRREL_API void sq_close(HSQUIRRELVM v); +SQUIRREL_API void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p); +SQUIRREL_API SQUserPointer sq_getforeignptr(HSQUIRRELVM v); +SQUIRREL_API void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc,SQPRINTFUNCTION errfunc); +SQUIRREL_API SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v); +SQUIRREL_API SQPRINTFUNCTION sq_geterrorfunc(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool resumedret,SQBool retval,SQBool raiseerror,SQBool throwerror); +SQUIRREL_API SQInteger sq_getvmstate(HSQUIRRELVM v); + +/*compiler*/ +SQUIRREL_API SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror); +SQUIRREL_API SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror); +SQUIRREL_API void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable); +SQUIRREL_API void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable); +SQUIRREL_API void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f); + +/*stack operations*/ +SQUIRREL_API void sq_push(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API void sq_pop(HSQUIRRELVM v,SQInteger nelemstopop); +SQUIRREL_API void sq_poptop(HSQUIRRELVM v); +SQUIRREL_API void sq_remove(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQInteger sq_gettop(HSQUIRRELVM v); +SQUIRREL_API void sq_settop(HSQUIRRELVM v,SQInteger newtop); +SQUIRREL_API SQRESULT sq_reservestack(HSQUIRRELVM v,SQInteger nsize); +SQUIRREL_API SQInteger sq_cmp(HSQUIRRELVM v); +SQUIRREL_API void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx); + +/*object creation handling*/ +SQUIRREL_API SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size); +SQUIRREL_API void sq_newtable(HSQUIRRELVM v); +SQUIRREL_API void sq_newtableex(HSQUIRRELVM v,SQInteger initialcapacity); +SQUIRREL_API void sq_newarray(HSQUIRRELVM v,SQInteger size); +SQUIRREL_API void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars); +SQUIRREL_API SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask); +SQUIRREL_API SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len); +SQUIRREL_API void sq_pushfloat(HSQUIRRELVM v,SQFloat f); +SQUIRREL_API void sq_pushinteger(HSQUIRRELVM v,SQInteger n); +SQUIRREL_API void sq_pushbool(HSQUIRRELVM v,SQBool b); +SQUIRREL_API void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p); +SQUIRREL_API void sq_pushnull(HSQUIRRELVM v); +SQUIRREL_API SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQInteger sq_getsize(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQBool sq_instanceof(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_tostring(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b); +SQUIRREL_API SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c); +SQUIRREL_API SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i); +SQUIRREL_API SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f); +SQUIRREL_API SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b); +SQUIRREL_API SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread); +SQUIRREL_API SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p); +SQUIRREL_API SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag); +SQUIRREL_API SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag); +SQUIRREL_API SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag); +SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook); +SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize); +SQUIRREL_API SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger idx,SQFunctionInfo *fi); +SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars); +SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name); +SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p); +SQUIRREL_API SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag); +SQUIRREL_API SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize); +SQUIRREL_API SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase); +SQUIRREL_API SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API void sq_weakref(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t); +SQUIRREL_API SQRESULT sq_getmemberhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle); +SQUIRREL_API SQRESULT sq_getbyhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle); +SQUIRREL_API SQRESULT sq_setbyhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle); + +/*object manipulation*/ +SQUIRREL_API void sq_pushroottable(HSQUIRRELVM v); +SQUIRREL_API void sq_pushregistrytable(HSQUIRRELVM v); +SQUIRREL_API void sq_pushconsttable(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_setroottable(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_setconsttable(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic); +SQUIRREL_API SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval); +SQUIRREL_API SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval); +SQUIRREL_API SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval); +SQUIRREL_API SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize); +SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx); +SQUIRREL_API SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos); +SQUIRREL_API SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval); +SQUIRREL_API SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx); + +/*calls*/ +SQUIRREL_API SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror); +SQUIRREL_API SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror); +SQUIRREL_API const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx); +SQUIRREL_API SQRESULT sq_getcallee(HSQUIRRELVM v); +SQUIRREL_API const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval); +SQUIRREL_API SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err); +SQUIRREL_API SQRESULT sq_throwobject(HSQUIRRELVM v); +SQUIRREL_API void sq_reseterror(HSQUIRRELVM v); +SQUIRREL_API void sq_getlasterror(HSQUIRRELVM v); + +/*raw object handling*/ +SQUIRREL_API SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po); +SQUIRREL_API void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj); +SQUIRREL_API void sq_addref(HSQUIRRELVM v,HSQOBJECT *po); +SQUIRREL_API SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po); +SQUIRREL_API SQUnsignedInteger sq_getrefcount(HSQUIRRELVM v,HSQOBJECT *po); +SQUIRREL_API void sq_resetobject(HSQOBJECT *po); +SQUIRREL_API const SQChar *sq_objtostring(const HSQOBJECT *o); +SQUIRREL_API SQBool sq_objtobool(const HSQOBJECT *o); +SQUIRREL_API SQInteger sq_objtointeger(const HSQOBJECT *o); +SQUIRREL_API SQFloat sq_objtofloat(const HSQOBJECT *o); +SQUIRREL_API SQUserPointer sq_objtouserpointer(const HSQOBJECT *o); +SQUIRREL_API SQRESULT sq_getobjtypetag(const HSQOBJECT *o,SQUserPointer * typetag); + +/*GC*/ +SQUIRREL_API SQInteger sq_collectgarbage(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_resurrectunreachable(HSQUIRRELVM v); + +/*serialization*/ +SQUIRREL_API SQRESULT sq_writeclosure(HSQUIRRELVM vm,SQWRITEFUNC writef,SQUserPointer up); +SQUIRREL_API SQRESULT sq_readclosure(HSQUIRRELVM vm,SQREADFUNC readf,SQUserPointer up); + +/*mem allocation*/ +SQUIRREL_API void *sq_malloc(SQUnsignedInteger size); +SQUIRREL_API void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize); +SQUIRREL_API void sq_free(void *p,SQUnsignedInteger size); + +/*debug*/ +SQUIRREL_API SQRESULT sq_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos *si); +SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v); +SQUIRREL_API void sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook); + +/*UTILITY MACRO*/ +#define sq_isnumeric(o) ((o)._type&SQOBJECT_NUMERIC) +#define sq_istable(o) ((o)._type==OT_TABLE) +#define sq_isarray(o) ((o)._type==OT_ARRAY) +#define sq_isfunction(o) ((o)._type==OT_FUNCPROTO) +#define sq_isclosure(o) ((o)._type==OT_CLOSURE) +#define sq_isgenerator(o) ((o)._type==OT_GENERATOR) +#define sq_isnativeclosure(o) ((o)._type==OT_NATIVECLOSURE) +#define sq_isstring(o) ((o)._type==OT_STRING) +#define sq_isinteger(o) ((o)._type==OT_INTEGER) +#define sq_isfloat(o) ((o)._type==OT_FLOAT) +#define sq_isuserpointer(o) ((o)._type==OT_USERPOINTER) +#define sq_isuserdata(o) ((o)._type==OT_USERDATA) +#define sq_isthread(o) ((o)._type==OT_THREAD) +#define sq_isnull(o) ((o)._type==OT_NULL) +#define sq_isclass(o) ((o)._type==OT_CLASS) +#define sq_isinstance(o) ((o)._type==OT_INSTANCE) +#define sq_isbool(o) ((o)._type==OT_BOOL) +#define sq_isweakref(o) ((o)._type==OT_WEAKREF) +#define sq_type(o) ((o)._type) + +/* deprecated */ +#define sq_createslot(v,n) sq_newslot(v,n,SQFalse) + +#define SQ_OK (0) +#define SQ_ERROR (-1) + +#define SQ_FAILED(res) (res<0) +#define SQ_SUCCEEDED(res) (res>=0) + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*_SQUIRREL_H_*/ diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdaux.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdaux.cpp index e115770a8..804a1e4d1 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdaux.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdaux.cpp @@ -1,129 +1,129 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include - -void sqstd_printcallstack(HSQUIRRELVM v) -{ - SQPRINTFUNCTION pf = sq_geterrorfunc(v); - if(pf) { - SQStackInfos si; - SQInteger i; - SQFloat f; - const SQChar *s; - SQInteger level=1; //1 is to skip this function that is level 0 - const SQChar *name=0; - SQInteger seq=0; - pf(v,_SC("\nCALLSTACK\n")); - while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si))) - { - const SQChar *fn=_SC("unknown"); - const SQChar *src=_SC("unknown"); - if(si.funcname)fn=si.funcname; - if(si.source)src=si.source; - pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line); - level++; - } - level=0; - pf(v,_SC("\nLOCALS\n")); - - for(level=0;level<10;level++){ - seq=0; - while((name = sq_getlocal(v,level,seq))) - { - seq++; - switch(sq_gettype(v,-1)) - { - case OT_NULL: - pf(v,_SC("[%s] NULL\n"),name); - break; - case OT_INTEGER: - sq_getinteger(v,-1,&i); - pf(v,_SC("[%s] %d\n"),name,i); - break; - case OT_FLOAT: - sq_getfloat(v,-1,&f); - pf(v,_SC("[%s] %.14g\n"),name,f); - break; - case OT_USERPOINTER: - pf(v,_SC("[%s] USERPOINTER\n"),name); - break; - case OT_STRING: - sq_getstring(v,-1,&s); - pf(v,_SC("[%s] \"%s\"\n"),name,s); - break; - case OT_TABLE: - pf(v,_SC("[%s] TABLE\n"),name); - break; - case OT_ARRAY: - pf(v,_SC("[%s] ARRAY\n"),name); - break; - case OT_CLOSURE: - pf(v,_SC("[%s] CLOSURE\n"),name); - break; - case OT_NATIVECLOSURE: - pf(v,_SC("[%s] NATIVECLOSURE\n"),name); - break; - case OT_GENERATOR: - pf(v,_SC("[%s] GENERATOR\n"),name); - break; - case OT_USERDATA: - pf(v,_SC("[%s] USERDATA\n"),name); - break; - case OT_THREAD: - pf(v,_SC("[%s] THREAD\n"),name); - break; - case OT_CLASS: - pf(v,_SC("[%s] CLASS\n"),name); - break; - case OT_INSTANCE: - pf(v,_SC("[%s] INSTANCE\n"),name); - break; - case OT_WEAKREF: - pf(v,_SC("[%s] WEAKREF\n"),name); - break; - case OT_BOOL:{ - sq_getinteger(v,-1,&i); - pf(v,_SC("[%s] %s\n"),name,i?_SC("true"):_SC("false")); - } - break; - default: assert(0); break; - } - sq_pop(v,1); - } - } - } -} - -static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v) -{ - SQPRINTFUNCTION pf = sq_geterrorfunc(v); - if(pf) { - const SQChar *sErr = 0; - if(sq_gettop(v)>=1) { - if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) { - pf(v,_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr); - } - else{ - pf(v,_SC("\nAN ERROR HAS OCCURED [unknown]\n")); - } - sqstd_printcallstack(v); - } - } - return 0; -} - -void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column) -{ - SQPRINTFUNCTION pf = sq_geterrorfunc(v); - if(pf) { - pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr); - } -} - -void sqstd_seterrorhandlers(HSQUIRRELVM v) -{ - sq_setcompilererrorhandler(v,_sqstd_compiler_error); - sq_newclosure(v,_sqstd_aux_printerror,0); - sq_seterrorhandler(v); -} +/* see copyright notice in squirrel.h */ +#include +#include +#include + +void sqstd_printcallstack(HSQUIRRELVM v) +{ + SQPRINTFUNCTION pf = sq_geterrorfunc(v); + if(pf) { + SQStackInfos si; + SQInteger i; + SQFloat f; + const SQChar *s; + SQInteger level=1; //1 is to skip this function that is level 0 + const SQChar *name=0; + SQInteger seq=0; + pf(v,_SC("\nCALLSTACK\n")); + while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si))) + { + const SQChar *fn=_SC("unknown"); + const SQChar *src=_SC("unknown"); + if(si.funcname)fn=si.funcname; + if(si.source)src=si.source; + pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line); + level++; + } + level=0; + pf(v,_SC("\nLOCALS\n")); + + for(level=0;level<10;level++){ + seq=0; + while((name = sq_getlocal(v,level,seq))) + { + seq++; + switch(sq_gettype(v,-1)) + { + case OT_NULL: + pf(v,_SC("[%s] NULL\n"),name); + break; + case OT_INTEGER: + sq_getinteger(v,-1,&i); + pf(v,_SC("[%s] %d\n"),name,i); + break; + case OT_FLOAT: + sq_getfloat(v,-1,&f); + pf(v,_SC("[%s] %.14g\n"),name,f); + break; + case OT_USERPOINTER: + pf(v,_SC("[%s] USERPOINTER\n"),name); + break; + case OT_STRING: + sq_getstring(v,-1,&s); + pf(v,_SC("[%s] \"%s\"\n"),name,s); + break; + case OT_TABLE: + pf(v,_SC("[%s] TABLE\n"),name); + break; + case OT_ARRAY: + pf(v,_SC("[%s] ARRAY\n"),name); + break; + case OT_CLOSURE: + pf(v,_SC("[%s] CLOSURE\n"),name); + break; + case OT_NATIVECLOSURE: + pf(v,_SC("[%s] NATIVECLOSURE\n"),name); + break; + case OT_GENERATOR: + pf(v,_SC("[%s] GENERATOR\n"),name); + break; + case OT_USERDATA: + pf(v,_SC("[%s] USERDATA\n"),name); + break; + case OT_THREAD: + pf(v,_SC("[%s] THREAD\n"),name); + break; + case OT_CLASS: + pf(v,_SC("[%s] CLASS\n"),name); + break; + case OT_INSTANCE: + pf(v,_SC("[%s] INSTANCE\n"),name); + break; + case OT_WEAKREF: + pf(v,_SC("[%s] WEAKREF\n"),name); + break; + case OT_BOOL:{ + sq_getinteger(v,-1,&i); + pf(v,_SC("[%s] %s\n"),name,i?_SC("true"):_SC("false")); + } + break; + default: assert(0); break; + } + sq_pop(v,1); + } + } + } +} + +static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v) +{ + SQPRINTFUNCTION pf = sq_geterrorfunc(v); + if(pf) { + const SQChar *sErr = 0; + if(sq_gettop(v)>=1) { + if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) { + pf(v,_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr); + } + else{ + pf(v,_SC("\nAN ERROR HAS OCCURED [unknown]\n")); + } + sqstd_printcallstack(v); + } + } + return 0; +} + +void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column) +{ + SQPRINTFUNCTION pf = sq_geterrorfunc(v); + if(pf) { + pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr); + } +} + +void sqstd_seterrorhandlers(HSQUIRRELVM v) +{ + sq_setcompilererrorhandler(v,_sqstd_compiler_error); + sq_newclosure(v,_sqstd_aux_printerror,0); + sq_seterrorhandler(v); +} diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdblob.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdblob.cpp index 11b593306..a856db5e7 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdblob.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdblob.cpp @@ -1,275 +1,275 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include -#include -#include "sqstdstream.h" -#include "sqstdblobimpl.h" - -#define SQSTD_BLOB_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000002) - -//Blob - - -#define SETUP_BLOB(v) \ - SQBlob *self = NULL; \ - { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \ - return SQ_ERROR; } - - -static SQInteger _blob_resize(HSQUIRRELVM v) -{ - SETUP_BLOB(v); - SQInteger size; - sq_getinteger(v,2,&size); - if(!self->Resize(size)) - return sq_throwerror(v,_SC("resize failed")); - return 0; -} - -static void __swap_dword(unsigned int *n) -{ - *n=(unsigned int)(((*n&0xFF000000)>>24) | - ((*n&0x00FF0000)>>8) | - ((*n&0x0000FF00)<<8) | - ((*n&0x000000FF)<<24)); -} - -static void __swap_word(unsigned short *n) -{ - *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00); -} - -static SQInteger _blob_swap4(HSQUIRRELVM v) -{ - SETUP_BLOB(v); - SQInteger num=(self->Len()-(self->Len()%4))>>2; - unsigned int *t=(unsigned int *)self->GetBuf(); - for(SQInteger i = 0; i < num; i++) { - __swap_dword(&t[i]); - } - return 0; -} - -static SQInteger _blob_swap2(HSQUIRRELVM v) -{ - SETUP_BLOB(v); - SQInteger num=(self->Len()-(self->Len()%2))>>1; - unsigned short *t = (unsigned short *)self->GetBuf(); - for(SQInteger i = 0; i < num; i++) { - __swap_word(&t[i]); - } - return 0; -} - -static SQInteger _blob__set(HSQUIRRELVM v) -{ - SETUP_BLOB(v); - SQInteger idx,val; - sq_getinteger(v,2,&idx); - sq_getinteger(v,3,&val); - if(idx < 0 || idx >= self->Len()) - return sq_throwerror(v,_SC("index out of range")); - ((unsigned char *)self->GetBuf())[idx] = (unsigned char) val; - sq_push(v,3); - return 1; -} - -static SQInteger _blob__get(HSQUIRRELVM v) -{ - SETUP_BLOB(v); - SQInteger idx; - sq_getinteger(v,2,&idx); - if(idx < 0 || idx >= self->Len()) - return sq_throwerror(v,_SC("index out of range")); - sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]); - return 1; -} - -static SQInteger _blob__nexti(HSQUIRRELVM v) -{ - SETUP_BLOB(v); - if(sq_gettype(v,2) == OT_NULL) { - sq_pushinteger(v, 0); - return 1; - } - SQInteger idx; - if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) { - if(idx+1 < self->Len()) { - sq_pushinteger(v, idx+1); - return 1; - } - sq_pushnull(v); - return 1; - } - return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type")); -} - -static SQInteger _blob__typeof(HSQUIRRELVM v) -{ - sq_pushstring(v,_SC("blob"),-1); - return 1; -} - -static SQInteger _blob_releasehook(SQUserPointer p, SQInteger size) -{ - SQBlob *self = (SQBlob*)p; - self->~SQBlob(); - sq_free(self,sizeof(SQBlob)); - return 1; -} - -static SQInteger _blob_constructor(HSQUIRRELVM v) -{ - SQInteger nparam = sq_gettop(v); - SQInteger size = 0; - if(nparam == 2) { - sq_getinteger(v, 2, &size); - } - if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size")); - //SQBlob *b = new SQBlob(size); - - SQBlob *b = new (sq_malloc(sizeof(SQBlob)))SQBlob(size); - if(SQ_FAILED(sq_setinstanceup(v,1,b))) { - b->~SQBlob(); - sq_free(b,sizeof(SQBlob)); - return sq_throwerror(v, _SC("cannot create blob")); - } - sq_setreleasehook(v,1,_blob_releasehook); - return 0; -} - -static SQInteger _blob__cloned(HSQUIRRELVM v) -{ - SQBlob *other = NULL; - { - if(SQ_FAILED(sq_getinstanceup(v,2,(SQUserPointer*)&other,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) - return SQ_ERROR; - } - //SQBlob *thisone = new SQBlob(other->Len()); - SQBlob *thisone = new (sq_malloc(sizeof(SQBlob)))SQBlob(other->Len()); - memcpy(thisone->GetBuf(),other->GetBuf(),thisone->Len()); - if(SQ_FAILED(sq_setinstanceup(v,1,thisone))) { - thisone->~SQBlob(); - sq_free(thisone,sizeof(SQBlob)); - return sq_throwerror(v, _SC("cannot clone blob")); - } - sq_setreleasehook(v,1,_blob_releasehook); - return 0; -} - -#define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck} -static SQRegFunction _blob_methods[] = { - _DECL_BLOB_FUNC(constructor,-1,_SC("xn")), - _DECL_BLOB_FUNC(resize,2,_SC("xn")), - _DECL_BLOB_FUNC(swap2,1,_SC("x")), - _DECL_BLOB_FUNC(swap4,1,_SC("x")), - _DECL_BLOB_FUNC(_set,3,_SC("xnn")), - _DECL_BLOB_FUNC(_get,2,_SC("xn")), - _DECL_BLOB_FUNC(_typeof,1,_SC("x")), - _DECL_BLOB_FUNC(_nexti,2,_SC("x")), - _DECL_BLOB_FUNC(_cloned,2,_SC("xx")), - {0,0,0,0} -}; - - - -//GLOBAL FUNCTIONS - -static SQInteger _g_blob_casti2f(HSQUIRRELVM v) -{ - SQInteger i; - sq_getinteger(v,2,&i); - sq_pushfloat(v,*((SQFloat *)&i)); - return 1; -} - -static SQInteger _g_blob_castf2i(HSQUIRRELVM v) -{ - SQFloat f; - sq_getfloat(v,2,&f); - sq_pushinteger(v,*((SQInteger *)&f)); - return 1; -} - -static SQInteger _g_blob_swap2(HSQUIRRELVM v) -{ - SQInteger i; - sq_getinteger(v,2,&i); - short s=(short)i; - sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF)); - return 1; -} - -static SQInteger _g_blob_swap4(HSQUIRRELVM v) -{ - SQInteger i; - sq_getinteger(v,2,&i); - unsigned int t4 = (unsigned int)i; - __swap_dword(&t4); - sq_pushinteger(v,(SQInteger)t4); - return 1; -} - -static SQInteger _g_blob_swapfloat(HSQUIRRELVM v) -{ - SQFloat f; - sq_getfloat(v,2,&f); - __swap_dword((unsigned int *)&f); - sq_pushfloat(v,f); - return 1; -} - -#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck} -static SQRegFunction bloblib_funcs[]={ - _DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")), - _DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")), - _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")), - _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")), - _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")), - {0,0} -}; - -SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr) -{ - SQBlob *blob; - if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) - return -1; - *ptr = blob->GetBuf(); - return SQ_OK; -} - -SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx) -{ - SQBlob *blob; - if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) - return -1; - return blob->Len(); -} - -SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size) -{ - SQInteger top = sq_gettop(v); - sq_pushregistrytable(v); - sq_pushstring(v,_SC("std_blob"),-1); - if(SQ_SUCCEEDED(sq_get(v,-2))) { - sq_remove(v,-2); //removes the registry - sq_push(v,1); // push the this - sq_pushinteger(v,size); //size - SQBlob *blob = NULL; - if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse)) - && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) { - sq_remove(v,-2); - return blob->GetBuf(); - } - } - sq_settop(v,top); - return NULL; -} - -SQRESULT sqstd_register_bloblib(HSQUIRRELVM v) -{ - return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs); -} - +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include +#include "sqstdstream.h" +#include "sqstdblobimpl.h" + +#define SQSTD_BLOB_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000002) + +//Blob + + +#define SETUP_BLOB(v) \ + SQBlob *self = NULL; \ + { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \ + return SQ_ERROR; } + + +static SQInteger _blob_resize(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger size; + sq_getinteger(v,2,&size); + if(!self->Resize(size)) + return sq_throwerror(v,_SC("resize failed")); + return 0; +} + +static void __swap_dword(unsigned int *n) +{ + *n=(unsigned int)(((*n&0xFF000000)>>24) | + ((*n&0x00FF0000)>>8) | + ((*n&0x0000FF00)<<8) | + ((*n&0x000000FF)<<24)); +} + +static void __swap_word(unsigned short *n) +{ + *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00); +} + +static SQInteger _blob_swap4(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger num=(self->Len()-(self->Len()%4))>>2; + unsigned int *t=(unsigned int *)self->GetBuf(); + for(SQInteger i = 0; i < num; i++) { + __swap_dword(&t[i]); + } + return 0; +} + +static SQInteger _blob_swap2(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger num=(self->Len()-(self->Len()%2))>>1; + unsigned short *t = (unsigned short *)self->GetBuf(); + for(SQInteger i = 0; i < num; i++) { + __swap_word(&t[i]); + } + return 0; +} + +static SQInteger _blob__set(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger idx,val; + sq_getinteger(v,2,&idx); + sq_getinteger(v,3,&val); + if(idx < 0 || idx >= self->Len()) + return sq_throwerror(v,_SC("index out of range")); + ((unsigned char *)self->GetBuf())[idx] = (unsigned char) val; + sq_push(v,3); + return 1; +} + +static SQInteger _blob__get(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger idx; + sq_getinteger(v,2,&idx); + if(idx < 0 || idx >= self->Len()) + return sq_throwerror(v,_SC("index out of range")); + sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]); + return 1; +} + +static SQInteger _blob__nexti(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + if(sq_gettype(v,2) == OT_NULL) { + sq_pushinteger(v, 0); + return 1; + } + SQInteger idx; + if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) { + if(idx+1 < self->Len()) { + sq_pushinteger(v, idx+1); + return 1; + } + sq_pushnull(v); + return 1; + } + return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type")); +} + +static SQInteger _blob__typeof(HSQUIRRELVM v) +{ + sq_pushstring(v,_SC("blob"),-1); + return 1; +} + +static SQInteger _blob_releasehook(SQUserPointer p, SQInteger size) +{ + SQBlob *self = (SQBlob*)p; + self->~SQBlob(); + sq_free(self,sizeof(SQBlob)); + return 1; +} + +static SQInteger _blob_constructor(HSQUIRRELVM v) +{ + SQInteger nparam = sq_gettop(v); + SQInteger size = 0; + if(nparam == 2) { + sq_getinteger(v, 2, &size); + } + if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size")); + //SQBlob *b = new SQBlob(size); + + SQBlob *b = new (sq_malloc(sizeof(SQBlob)))SQBlob(size); + if(SQ_FAILED(sq_setinstanceup(v,1,b))) { + b->~SQBlob(); + sq_free(b,sizeof(SQBlob)); + return sq_throwerror(v, _SC("cannot create blob")); + } + sq_setreleasehook(v,1,_blob_releasehook); + return 0; +} + +static SQInteger _blob__cloned(HSQUIRRELVM v) +{ + SQBlob *other = NULL; + { + if(SQ_FAILED(sq_getinstanceup(v,2,(SQUserPointer*)&other,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) + return SQ_ERROR; + } + //SQBlob *thisone = new SQBlob(other->Len()); + SQBlob *thisone = new (sq_malloc(sizeof(SQBlob)))SQBlob(other->Len()); + memcpy(thisone->GetBuf(),other->GetBuf(),thisone->Len()); + if(SQ_FAILED(sq_setinstanceup(v,1,thisone))) { + thisone->~SQBlob(); + sq_free(thisone,sizeof(SQBlob)); + return sq_throwerror(v, _SC("cannot clone blob")); + } + sq_setreleasehook(v,1,_blob_releasehook); + return 0; +} + +#define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck} +static SQRegFunction _blob_methods[] = { + _DECL_BLOB_FUNC(constructor,-1,_SC("xn")), + _DECL_BLOB_FUNC(resize,2,_SC("xn")), + _DECL_BLOB_FUNC(swap2,1,_SC("x")), + _DECL_BLOB_FUNC(swap4,1,_SC("x")), + _DECL_BLOB_FUNC(_set,3,_SC("xnn")), + _DECL_BLOB_FUNC(_get,2,_SC("xn")), + _DECL_BLOB_FUNC(_typeof,1,_SC("x")), + _DECL_BLOB_FUNC(_nexti,2,_SC("x")), + _DECL_BLOB_FUNC(_cloned,2,_SC("xx")), + {0,0,0,0} +}; + + + +//GLOBAL FUNCTIONS + +static SQInteger _g_blob_casti2f(HSQUIRRELVM v) +{ + SQInteger i; + sq_getinteger(v,2,&i); + sq_pushfloat(v,*((SQFloat *)&i)); + return 1; +} + +static SQInteger _g_blob_castf2i(HSQUIRRELVM v) +{ + SQFloat f; + sq_getfloat(v,2,&f); + sq_pushinteger(v,*((SQInteger *)&f)); + return 1; +} + +static SQInteger _g_blob_swap2(HSQUIRRELVM v) +{ + SQInteger i; + sq_getinteger(v,2,&i); + short s=(short)i; + sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF)); + return 1; +} + +static SQInteger _g_blob_swap4(HSQUIRRELVM v) +{ + SQInteger i; + sq_getinteger(v,2,&i); + unsigned int t4 = (unsigned int)i; + __swap_dword(&t4); + sq_pushinteger(v,(SQInteger)t4); + return 1; +} + +static SQInteger _g_blob_swapfloat(HSQUIRRELVM v) +{ + SQFloat f; + sq_getfloat(v,2,&f); + __swap_dword((unsigned int *)&f); + sq_pushfloat(v,f); + return 1; +} + +#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck} +static SQRegFunction bloblib_funcs[]={ + _DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")), + _DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")), + _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")), + _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")), + _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")), + {0,0} +}; + +SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr) +{ + SQBlob *blob; + if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) + return -1; + *ptr = blob->GetBuf(); + return SQ_OK; +} + +SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx) +{ + SQBlob *blob; + if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) + return -1; + return blob->Len(); +} + +SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size) +{ + SQInteger top = sq_gettop(v); + sq_pushregistrytable(v); + sq_pushstring(v,_SC("std_blob"),-1); + if(SQ_SUCCEEDED(sq_get(v,-2))) { + sq_remove(v,-2); //removes the registry + sq_push(v,1); // push the this + sq_pushinteger(v,size); //size + SQBlob *blob = NULL; + if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse)) + && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) { + sq_remove(v,-2); + return blob->GetBuf(); + } + } + sq_settop(v,top); + return NULL; +} + +SQRESULT sqstd_register_bloblib(HSQUIRRELVM v) +{ + return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs); +} + diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdblobimpl.h b/squirrel_3_0_1_stable/sqstdlib/sqstdblobimpl.h index b2291b73c..9f22c0ae2 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdblobimpl.h +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdblobimpl.h @@ -1,108 +1,108 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTD_BLOBIMPL_H_ -#define _SQSTD_BLOBIMPL_H_ - -struct SQBlob : public SQStream -{ - SQBlob(SQInteger size) { - _size = size; - _allocated = size; - _buf = (unsigned char *)sq_malloc(size); - memset(_buf, 0, _size); - _ptr = 0; - _owns = true; - } - virtual ~SQBlob() { - sq_free(_buf, _allocated); - } - SQInteger Write(void *buffer, SQInteger size) { - if(!CanAdvance(size)) { - GrowBufOf(_ptr + size - _size); - } - memcpy(&_buf[_ptr], buffer, size); - _ptr += size; - return size; - } - SQInteger Read(void *buffer,SQInteger size) { - SQInteger n = size; - if(!CanAdvance(size)) { - if((_size - _ptr) > 0) - n = _size - _ptr; - else return 0; - } - memcpy(buffer, &_buf[_ptr], n); - _ptr += n; - return n; - } - bool Resize(SQInteger n) { - if(!_owns) return false; - if(n != _allocated) { - unsigned char *newbuf = (unsigned char *)sq_malloc(n); - memset(newbuf,0,n); - if(_size > n) - memcpy(newbuf,_buf,n); - else - memcpy(newbuf,_buf,_size); - sq_free(_buf,_allocated); - _buf=newbuf; - _allocated = n; - if(_size > _allocated) - _size = _allocated; - if(_ptr > _allocated) - _ptr = _allocated; - } - return true; - } - bool GrowBufOf(SQInteger n) - { - bool ret = true; - if(_size + n > _allocated) { - if(_size + n > _size * 2) - ret = Resize(_size + n); - else - ret = Resize(_size * 2); - } - _size = _size + n; - return ret; - } - bool CanAdvance(SQInteger n) { - if(_ptr+n>_size)return false; - return true; - } - SQInteger Seek(SQInteger offset, SQInteger origin) { - switch(origin) { - case SQ_SEEK_SET: - if(offset > _size || offset < 0) return -1; - _ptr = offset; - break; - case SQ_SEEK_CUR: - if(_ptr + offset > _size || _ptr + offset < 0) return -1; - _ptr += offset; - break; - case SQ_SEEK_END: - if(_size + offset > _size || _size + offset < 0) return -1; - _ptr = _size + offset; - break; - default: return -1; - } - return 0; - } - bool IsValid() { - return _buf?true:false; - } - bool EOS() { - return _ptr == _size; - } - SQInteger Flush() { return 0; } - SQInteger Tell() { return _ptr; } - SQInteger Len() { return _size; } - SQUserPointer GetBuf(){ return _buf; } -private: - SQInteger _size; - SQInteger _allocated; - SQInteger _ptr; - unsigned char *_buf; - bool _owns; -}; - -#endif //_SQSTD_BLOBIMPL_H_ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_BLOBIMPL_H_ +#define _SQSTD_BLOBIMPL_H_ + +struct SQBlob : public SQStream +{ + SQBlob(SQInteger size) { + _size = size; + _allocated = size; + _buf = (unsigned char *)sq_malloc(size); + memset(_buf, 0, _size); + _ptr = 0; + _owns = true; + } + virtual ~SQBlob() { + sq_free(_buf, _allocated); + } + SQInteger Write(void *buffer, SQInteger size) { + if(!CanAdvance(size)) { + GrowBufOf(_ptr + size - _size); + } + memcpy(&_buf[_ptr], buffer, size); + _ptr += size; + return size; + } + SQInteger Read(void *buffer,SQInteger size) { + SQInteger n = size; + if(!CanAdvance(size)) { + if((_size - _ptr) > 0) + n = _size - _ptr; + else return 0; + } + memcpy(buffer, &_buf[_ptr], n); + _ptr += n; + return n; + } + bool Resize(SQInteger n) { + if(!_owns) return false; + if(n != _allocated) { + unsigned char *newbuf = (unsigned char *)sq_malloc(n); + memset(newbuf,0,n); + if(_size > n) + memcpy(newbuf,_buf,n); + else + memcpy(newbuf,_buf,_size); + sq_free(_buf,_allocated); + _buf=newbuf; + _allocated = n; + if(_size > _allocated) + _size = _allocated; + if(_ptr > _allocated) + _ptr = _allocated; + } + return true; + } + bool GrowBufOf(SQInteger n) + { + bool ret = true; + if(_size + n > _allocated) { + if(_size + n > _size * 2) + ret = Resize(_size + n); + else + ret = Resize(_size * 2); + } + _size = _size + n; + return ret; + } + bool CanAdvance(SQInteger n) { + if(_ptr+n>_size)return false; + return true; + } + SQInteger Seek(SQInteger offset, SQInteger origin) { + switch(origin) { + case SQ_SEEK_SET: + if(offset > _size || offset < 0) return -1; + _ptr = offset; + break; + case SQ_SEEK_CUR: + if(_ptr + offset > _size || _ptr + offset < 0) return -1; + _ptr += offset; + break; + case SQ_SEEK_END: + if(_size + offset > _size || _size + offset < 0) return -1; + _ptr = _size + offset; + break; + default: return -1; + } + return 0; + } + bool IsValid() { + return _buf?true:false; + } + bool EOS() { + return _ptr == _size; + } + SQInteger Flush() { return 0; } + SQInteger Tell() { return _ptr; } + SQInteger Len() { return _size; } + SQUserPointer GetBuf(){ return _buf; } +private: + SQInteger _size; + SQInteger _allocated; + SQInteger _ptr; + unsigned char *_buf; + bool _owns; +}; + +#endif //_SQSTD_BLOBIMPL_H_ diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdio.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdio.cpp index 241864bb2..cd88bb0b7 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdio.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdio.cpp @@ -1,419 +1,419 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include -#include "sqstdstream.h" - -#define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001) -//basic API -SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode) -{ -#ifndef SQUNICODE - return (SQFILE)fopen(filename,mode); -#else - return (SQFILE)_wfopen(filename,mode); -#endif -} - -SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file) -{ - return (SQInteger)fread(buffer,size,count,(FILE *)file); -} - -SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file) -{ - return (SQInteger)fwrite(buffer,size,count,(FILE *)file); -} - -SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin) -{ - SQInteger realorigin; - switch(origin) { - case SQ_SEEK_CUR: realorigin = SEEK_CUR; break; - case SQ_SEEK_END: realorigin = SEEK_END; break; - case SQ_SEEK_SET: realorigin = SEEK_SET; break; - default: return -1; //failed - } - return fseek((FILE *)file,(long)offset,(int)realorigin); -} - -SQInteger sqstd_ftell(SQFILE file) -{ - return ftell((FILE *)file); -} - -SQInteger sqstd_fflush(SQFILE file) -{ - return fflush((FILE *)file); -} - -SQInteger sqstd_fclose(SQFILE file) -{ - return fclose((FILE *)file); -} - -SQInteger sqstd_feof(SQFILE file) -{ - return feof((FILE *)file); -} - -//File -struct SQFile : public SQStream { - SQFile() { _handle = NULL; _owns = false;} - SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;} - virtual ~SQFile() { Close(); } - bool Open(const SQChar *filename ,const SQChar *mode) { - Close(); - if( (_handle = sqstd_fopen(filename,mode)) ) { - _owns = true; - return true; - } - return false; - } - void Close() { - if(_handle && _owns) { - sqstd_fclose(_handle); - _handle = NULL; - _owns = false; - } - } - SQInteger Read(void *buffer,SQInteger size) { - return sqstd_fread(buffer,1,size,_handle); - } - SQInteger Write(void *buffer,SQInteger size) { - return sqstd_fwrite(buffer,1,size,_handle); - } - SQInteger Flush() { - return sqstd_fflush(_handle); - } - SQInteger Tell() { - return sqstd_ftell(_handle); - } - SQInteger Len() { - SQInteger prevpos=Tell(); - Seek(0,SQ_SEEK_END); - SQInteger size=Tell(); - Seek(prevpos,SQ_SEEK_SET); - return size; - } - SQInteger Seek(SQInteger offset, SQInteger origin) { - return sqstd_fseek(_handle,offset,origin); - } - bool IsValid() { return _handle?true:false; } - bool EOS() { return Tell()==Len()?true:false;} - SQFILE GetHandle() {return _handle;} -private: - SQFILE _handle; - bool _owns; -}; - -static SQInteger _file__typeof(HSQUIRRELVM v) -{ - sq_pushstring(v,_SC("file"),-1); - return 1; -} - -static SQInteger _file_releasehook(SQUserPointer p, SQInteger size) -{ - SQFile *self = (SQFile*)p; - self->~SQFile(); - sq_free(self,sizeof(SQFile)); - return 1; -} - -static SQInteger _file_constructor(HSQUIRRELVM v) -{ - const SQChar *filename,*mode; - bool owns = true; - SQFile *f; - SQFILE newf; - if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) { - sq_getstring(v, 2, &filename); - sq_getstring(v, 3, &mode); - newf = sqstd_fopen(filename, mode); - if(!newf) return sq_throwerror(v, _SC("cannot open file")); - } else if(sq_gettype(v,2) == OT_USERPOINTER) { - owns = !(sq_gettype(v,3) == OT_NULL); - sq_getuserpointer(v,2,&newf); - } else { - return sq_throwerror(v,_SC("wrong parameter")); - } - - f = new (sq_malloc(sizeof(SQFile)))SQFile(newf,owns); - if(SQ_FAILED(sq_setinstanceup(v,1,f))) { - f->~SQFile(); - sq_free(f,sizeof(SQFile)); - return sq_throwerror(v, _SC("cannot create blob with negative size")); - } - sq_setreleasehook(v,1,_file_releasehook); - return 0; -} - -//bindings -#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck} -static SQRegFunction _file_methods[] = { - _DECL_FILE_FUNC(constructor,3,_SC("x")), - _DECL_FILE_FUNC(_typeof,1,_SC("x")), - {0,0,0,0}, -}; - - - -SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own) -{ - SQInteger top = sq_gettop(v); - sq_pushregistrytable(v); - sq_pushstring(v,_SC("std_file"),-1); - if(SQ_SUCCEEDED(sq_get(v,-2))) { - sq_remove(v,-2); //removes the registry - sq_pushroottable(v); // push the this - sq_pushuserpointer(v,file); //file - if(own){ - sq_pushinteger(v,1); //true - } - else{ - sq_pushnull(v); //false - } - if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) { - sq_remove(v,-2); - return SQ_OK; - } - } - sq_settop(v,top); - return SQ_OK; -} - -SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file) -{ - SQFile *fileobj = NULL; - if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) { - *file = fileobj->GetHandle(); - return SQ_OK; - } - return sq_throwerror(v,_SC("not a file")); -} - - - -static SQInteger _io_file_lexfeed_PLAIN(SQUserPointer file) -{ - SQInteger ret; - char c; - if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) - return c; - return 0; -} - -#ifdef SQUNICODE -static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file) -{ -#define READ() \ - if(sqstd_fread(&inchar,sizeof(inchar),1,(FILE *)file) != 1) \ - return 0; - - static const SQInteger utf8_lengths[16] = - { - 1,1,1,1,1,1,1,1, /* 0000 to 0111 : 1 byte (plain ASCII) */ - 0,0,0,0, /* 1000 to 1011 : not valid */ - 2,2, /* 1100, 1101 : 2 bytes */ - 3, /* 1110 : 3 bytes */ - 4 /* 1111 :4 bytes */ - }; - static unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07}; - unsigned char inchar; - SQInteger c = 0; - READ(); - c = inchar; - // - if(c >= 0x80) { - SQInteger tmp; - SQInteger codelen = utf8_lengths[c>>4]; - if(codelen == 0) - return 0; - //"invalid UTF-8 stream"; - tmp = c&byte_masks[codelen]; - for(SQInteger n = 0; n < codelen-1; n++) { - tmp<<=6; - READ(); - tmp |= inchar & 0x3F; - } - c = tmp; - } - return c; -} -#endif - -static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer file) -{ - SQInteger ret; - wchar_t c; - if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) - return (SQChar)c; - return 0; -} - -static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer file) -{ - SQInteger ret; - unsigned short c; - if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) { - c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00); - return (SQChar)c; - } - return 0; -} - -SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size) -{ - SQInteger ret; - if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret; - return -1; -} - -SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size) -{ - return sqstd_fwrite(p,1,size,(SQFILE)file); -} - -SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror) -{ - SQFILE file = sqstd_fopen(filename,_SC("rb")); - SQInteger ret; - unsigned short us; - unsigned char uc; - SQLEXREADFUNC func = _io_file_lexfeed_PLAIN; - if(file){ - ret = sqstd_fread(&us,1,2,file); - if(ret != 2) { - //probably an empty file - us = 0; - } - if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE - sqstd_fseek(file,0,SQ_SEEK_SET); - if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) { - sqstd_fclose(file); - return SQ_OK; - } - } - else { //SCRIPT - switch(us) - { - //gotta swap the next 2 lines on BIG endian machines - case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian; - case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian; - case 0xBBEF: - if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) { - sqstd_fclose(file); - return sq_throwerror(v,_SC("io error")); - } - if(uc != 0xBF) { - sqstd_fclose(file); - return sq_throwerror(v,_SC("Unrecognozed ecoding")); - } -#ifdef SQUNICODE - func = _io_file_lexfeed_UTF8; -#else - func = _io_file_lexfeed_PLAIN; -#endif - break;//UTF-8 ; - default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii - } - - if(SQ_SUCCEEDED(sq_compile(v,func,file,filename,printerror))){ - sqstd_fclose(file); - return SQ_OK; - } - } - sqstd_fclose(file); - return SQ_ERROR; - } - return sq_throwerror(v,_SC("cannot open the file")); -} - -SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror) -{ - if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) { - sq_push(v,-2); - if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) { - sq_remove(v,retval?-2:-1); //removes the closure - return 1; - } - sq_pop(v,1); //removes the closure - } - return SQ_ERROR; -} - -SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename) -{ - SQFILE file = sqstd_fopen(filename,_SC("wb+")); - if(!file) return sq_throwerror(v,_SC("cannot open the file")); - if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) { - sqstd_fclose(file); - return SQ_OK; - } - sqstd_fclose(file); - return SQ_ERROR; //forward the error -} - -SQInteger _g_io_loadfile(HSQUIRRELVM v) -{ - const SQChar *filename; - SQBool printerror = SQFalse; - sq_getstring(v,2,&filename); - if(sq_gettop(v) >= 3) { - sq_getbool(v,3,&printerror); - } - if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) - return 1; - return SQ_ERROR; //propagates the error -} - -SQInteger _g_io_writeclosuretofile(HSQUIRRELVM v) -{ - const SQChar *filename; - sq_getstring(v,2,&filename); - if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename))) - return 1; - return SQ_ERROR; //propagates the error -} - -SQInteger _g_io_dofile(HSQUIRRELVM v) -{ - const SQChar *filename; - SQBool printerror = SQFalse; - sq_getstring(v,2,&filename); - if(sq_gettop(v) >= 3) { - sq_getbool(v,3,&printerror); - } - sq_push(v,1); //repush the this - if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror))) - return 1; - return SQ_ERROR; //propagates the error -} - -#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck} -static SQRegFunction iolib_funcs[]={ - _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")), - _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")), - _DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")), - {0,0} -}; - -SQRESULT sqstd_register_iolib(HSQUIRRELVM v) -{ - SQInteger top = sq_gettop(v); - //create delegate - declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs); - sq_pushstring(v,_SC("stdout"),-1); - sqstd_createfile(v,stdout,SQFalse); - sq_newslot(v,-3,SQFalse); - sq_pushstring(v,_SC("stdin"),-1); - sqstd_createfile(v,stdin,SQFalse); - sq_newslot(v,-3,SQFalse); - sq_pushstring(v,_SC("stderr"),-1); - sqstd_createfile(v,stderr,SQFalse); - sq_newslot(v,-3,SQFalse); - sq_settop(v,top); - return SQ_OK; -} +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include "sqstdstream.h" + +#define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001) +//basic API +SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode) +{ +#ifndef SQUNICODE + return (SQFILE)fopen(filename,mode); +#else + return (SQFILE)_wfopen(filename,mode); +#endif +} + +SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file) +{ + return (SQInteger)fread(buffer,size,count,(FILE *)file); +} + +SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file) +{ + return (SQInteger)fwrite(buffer,size,count,(FILE *)file); +} + +SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin) +{ + SQInteger realorigin; + switch(origin) { + case SQ_SEEK_CUR: realorigin = SEEK_CUR; break; + case SQ_SEEK_END: realorigin = SEEK_END; break; + case SQ_SEEK_SET: realorigin = SEEK_SET; break; + default: return -1; //failed + } + return fseek((FILE *)file,(long)offset,(int)realorigin); +} + +SQInteger sqstd_ftell(SQFILE file) +{ + return ftell((FILE *)file); +} + +SQInteger sqstd_fflush(SQFILE file) +{ + return fflush((FILE *)file); +} + +SQInteger sqstd_fclose(SQFILE file) +{ + return fclose((FILE *)file); +} + +SQInteger sqstd_feof(SQFILE file) +{ + return feof((FILE *)file); +} + +//File +struct SQFile : public SQStream { + SQFile() { _handle = NULL; _owns = false;} + SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;} + virtual ~SQFile() { Close(); } + bool Open(const SQChar *filename ,const SQChar *mode) { + Close(); + if( (_handle = sqstd_fopen(filename,mode)) ) { + _owns = true; + return true; + } + return false; + } + void Close() { + if(_handle && _owns) { + sqstd_fclose(_handle); + _handle = NULL; + _owns = false; + } + } + SQInteger Read(void *buffer,SQInteger size) { + return sqstd_fread(buffer,1,size,_handle); + } + SQInteger Write(void *buffer,SQInteger size) { + return sqstd_fwrite(buffer,1,size,_handle); + } + SQInteger Flush() { + return sqstd_fflush(_handle); + } + SQInteger Tell() { + return sqstd_ftell(_handle); + } + SQInteger Len() { + SQInteger prevpos=Tell(); + Seek(0,SQ_SEEK_END); + SQInteger size=Tell(); + Seek(prevpos,SQ_SEEK_SET); + return size; + } + SQInteger Seek(SQInteger offset, SQInteger origin) { + return sqstd_fseek(_handle,offset,origin); + } + bool IsValid() { return _handle?true:false; } + bool EOS() { return Tell()==Len()?true:false;} + SQFILE GetHandle() {return _handle;} +private: + SQFILE _handle; + bool _owns; +}; + +static SQInteger _file__typeof(HSQUIRRELVM v) +{ + sq_pushstring(v,_SC("file"),-1); + return 1; +} + +static SQInteger _file_releasehook(SQUserPointer p, SQInteger size) +{ + SQFile *self = (SQFile*)p; + self->~SQFile(); + sq_free(self,sizeof(SQFile)); + return 1; +} + +static SQInteger _file_constructor(HSQUIRRELVM v) +{ + const SQChar *filename,*mode; + bool owns = true; + SQFile *f; + SQFILE newf; + if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) { + sq_getstring(v, 2, &filename); + sq_getstring(v, 3, &mode); + newf = sqstd_fopen(filename, mode); + if(!newf) return sq_throwerror(v, _SC("cannot open file")); + } else if(sq_gettype(v,2) == OT_USERPOINTER) { + owns = !(sq_gettype(v,3) == OT_NULL); + sq_getuserpointer(v,2,&newf); + } else { + return sq_throwerror(v,_SC("wrong parameter")); + } + + f = new (sq_malloc(sizeof(SQFile)))SQFile(newf,owns); + if(SQ_FAILED(sq_setinstanceup(v,1,f))) { + f->~SQFile(); + sq_free(f,sizeof(SQFile)); + return sq_throwerror(v, _SC("cannot create blob with negative size")); + } + sq_setreleasehook(v,1,_file_releasehook); + return 0; +} + +//bindings +#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck} +static SQRegFunction _file_methods[] = { + _DECL_FILE_FUNC(constructor,3,_SC("x")), + _DECL_FILE_FUNC(_typeof,1,_SC("x")), + {0,0,0,0}, +}; + + + +SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own) +{ + SQInteger top = sq_gettop(v); + sq_pushregistrytable(v); + sq_pushstring(v,_SC("std_file"),-1); + if(SQ_SUCCEEDED(sq_get(v,-2))) { + sq_remove(v,-2); //removes the registry + sq_pushroottable(v); // push the this + sq_pushuserpointer(v,file); //file + if(own){ + sq_pushinteger(v,1); //true + } + else{ + sq_pushnull(v); //false + } + if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) { + sq_remove(v,-2); + return SQ_OK; + } + } + sq_settop(v,top); + return SQ_OK; +} + +SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file) +{ + SQFile *fileobj = NULL; + if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) { + *file = fileobj->GetHandle(); + return SQ_OK; + } + return sq_throwerror(v,_SC("not a file")); +} + + + +static SQInteger _io_file_lexfeed_PLAIN(SQUserPointer file) +{ + SQInteger ret; + char c; + if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) + return c; + return 0; +} + +#ifdef SQUNICODE +static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file) +{ +#define READ() \ + if(sqstd_fread(&inchar,sizeof(inchar),1,(FILE *)file) != 1) \ + return 0; + + static const SQInteger utf8_lengths[16] = + { + 1,1,1,1,1,1,1,1, /* 0000 to 0111 : 1 byte (plain ASCII) */ + 0,0,0,0, /* 1000 to 1011 : not valid */ + 2,2, /* 1100, 1101 : 2 bytes */ + 3, /* 1110 : 3 bytes */ + 4 /* 1111 :4 bytes */ + }; + static unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07}; + unsigned char inchar; + SQInteger c = 0; + READ(); + c = inchar; + // + if(c >= 0x80) { + SQInteger tmp; + SQInteger codelen = utf8_lengths[c>>4]; + if(codelen == 0) + return 0; + //"invalid UTF-8 stream"; + tmp = c&byte_masks[codelen]; + for(SQInteger n = 0; n < codelen-1; n++) { + tmp<<=6; + READ(); + tmp |= inchar & 0x3F; + } + c = tmp; + } + return c; +} +#endif + +static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer file) +{ + SQInteger ret; + wchar_t c; + if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) + return (SQChar)c; + return 0; +} + +static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer file) +{ + SQInteger ret; + unsigned short c; + if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) { + c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00); + return (SQChar)c; + } + return 0; +} + +SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size) +{ + SQInteger ret; + if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret; + return -1; +} + +SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size) +{ + return sqstd_fwrite(p,1,size,(SQFILE)file); +} + +SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror) +{ + SQFILE file = sqstd_fopen(filename,_SC("rb")); + SQInteger ret; + unsigned short us; + unsigned char uc; + SQLEXREADFUNC func = _io_file_lexfeed_PLAIN; + if(file){ + ret = sqstd_fread(&us,1,2,file); + if(ret != 2) { + //probably an empty file + us = 0; + } + if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE + sqstd_fseek(file,0,SQ_SEEK_SET); + if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) { + sqstd_fclose(file); + return SQ_OK; + } + } + else { //SCRIPT + switch(us) + { + //gotta swap the next 2 lines on BIG endian machines + case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian; + case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian; + case 0xBBEF: + if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) { + sqstd_fclose(file); + return sq_throwerror(v,_SC("io error")); + } + if(uc != 0xBF) { + sqstd_fclose(file); + return sq_throwerror(v,_SC("Unrecognozed ecoding")); + } +#ifdef SQUNICODE + func = _io_file_lexfeed_UTF8; +#else + func = _io_file_lexfeed_PLAIN; +#endif + break;//UTF-8 ; + default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii + } + + if(SQ_SUCCEEDED(sq_compile(v,func,file,filename,printerror))){ + sqstd_fclose(file); + return SQ_OK; + } + } + sqstd_fclose(file); + return SQ_ERROR; + } + return sq_throwerror(v,_SC("cannot open the file")); +} + +SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror) +{ + if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) { + sq_push(v,-2); + if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) { + sq_remove(v,retval?-2:-1); //removes the closure + return 1; + } + sq_pop(v,1); //removes the closure + } + return SQ_ERROR; +} + +SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename) +{ + SQFILE file = sqstd_fopen(filename,_SC("wb+")); + if(!file) return sq_throwerror(v,_SC("cannot open the file")); + if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) { + sqstd_fclose(file); + return SQ_OK; + } + sqstd_fclose(file); + return SQ_ERROR; //forward the error +} + +SQInteger _g_io_loadfile(HSQUIRRELVM v) +{ + const SQChar *filename; + SQBool printerror = SQFalse; + sq_getstring(v,2,&filename); + if(sq_gettop(v) >= 3) { + sq_getbool(v,3,&printerror); + } + if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) + return 1; + return SQ_ERROR; //propagates the error +} + +SQInteger _g_io_writeclosuretofile(HSQUIRRELVM v) +{ + const SQChar *filename; + sq_getstring(v,2,&filename); + if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename))) + return 1; + return SQ_ERROR; //propagates the error +} + +SQInteger _g_io_dofile(HSQUIRRELVM v) +{ + const SQChar *filename; + SQBool printerror = SQFalse; + sq_getstring(v,2,&filename); + if(sq_gettop(v) >= 3) { + sq_getbool(v,3,&printerror); + } + sq_push(v,1); //repush the this + if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror))) + return 1; + return SQ_ERROR; //propagates the error +} + +#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck} +static SQRegFunction iolib_funcs[]={ + _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")), + _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")), + _DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")), + {0,0} +}; + +SQRESULT sqstd_register_iolib(HSQUIRRELVM v) +{ + SQInteger top = sq_gettop(v); + //create delegate + declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs); + sq_pushstring(v,_SC("stdout"),-1); + sqstd_createfile(v,stdout,SQFalse); + sq_newslot(v,-3,SQFalse); + sq_pushstring(v,_SC("stdin"),-1); + sqstd_createfile(v,stdin,SQFalse); + sq_newslot(v,-3,SQFalse); + sq_pushstring(v,_SC("stderr"),-1); + sqstd_createfile(v,stderr,SQFalse); + sq_newslot(v,-3,SQFalse); + sq_settop(v,top); + return SQ_OK; +} diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdmath.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdmath.cpp index ef50359bd..8d8a1917b 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdmath.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdmath.cpp @@ -1,107 +1,107 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include - -#define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \ - SQFloat f; \ - sq_getfloat(v,2,&f); \ - sq_pushfloat(v,(SQFloat)_funcname(f)); \ - return 1; \ -} - -#define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \ - SQFloat p1,p2; \ - sq_getfloat(v,2,&p1); \ - sq_getfloat(v,3,&p2); \ - sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \ - return 1; \ -} - -static SQInteger math_srand(HSQUIRRELVM v) -{ - SQInteger i; - if(SQ_FAILED(sq_getinteger(v,2,&i))) - return sq_throwerror(v,_SC("invalid param")); - srand((unsigned int)i); - return 0; -} - -static SQInteger math_rand(HSQUIRRELVM v) -{ - sq_pushinteger(v,rand()); - return 1; -} - -static SQInteger math_abs(HSQUIRRELVM v) -{ - SQInteger n; - sq_getinteger(v,2,&n); - sq_pushinteger(v,(SQInteger)abs((int)n)); - return 1; -} - -SINGLE_ARG_FUNC(sqrt) -SINGLE_ARG_FUNC(fabs) -SINGLE_ARG_FUNC(sin) -SINGLE_ARG_FUNC(cos) -SINGLE_ARG_FUNC(asin) -SINGLE_ARG_FUNC(acos) -SINGLE_ARG_FUNC(log) -SINGLE_ARG_FUNC(log10) -SINGLE_ARG_FUNC(tan) -SINGLE_ARG_FUNC(atan) -TWO_ARGS_FUNC(atan2) -TWO_ARGS_FUNC(pow) -SINGLE_ARG_FUNC(floor) -SINGLE_ARG_FUNC(ceil) -SINGLE_ARG_FUNC(exp) - -#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck} -static SQRegFunction mathlib_funcs[] = { - _DECL_FUNC(sqrt,2,_SC(".n")), - _DECL_FUNC(sin,2,_SC(".n")), - _DECL_FUNC(cos,2,_SC(".n")), - _DECL_FUNC(asin,2,_SC(".n")), - _DECL_FUNC(acos,2,_SC(".n")), - _DECL_FUNC(log,2,_SC(".n")), - _DECL_FUNC(log10,2,_SC(".n")), - _DECL_FUNC(tan,2,_SC(".n")), - _DECL_FUNC(atan,2,_SC(".n")), - _DECL_FUNC(atan2,3,_SC(".nn")), - _DECL_FUNC(pow,3,_SC(".nn")), - _DECL_FUNC(floor,2,_SC(".n")), - _DECL_FUNC(ceil,2,_SC(".n")), - _DECL_FUNC(exp,2,_SC(".n")), - _DECL_FUNC(srand,2,_SC(".n")), - _DECL_FUNC(rand,1,NULL), - _DECL_FUNC(fabs,2,_SC(".n")), - _DECL_FUNC(abs,2,_SC(".n")), - {0,0}, -}; -#undef _DECL_FUNC - -#ifndef M_PI -#define M_PI (3.14159265358979323846) -#endif - -SQRESULT sqstd_register_mathlib(HSQUIRRELVM v) -{ - SQInteger i=0; - while(mathlib_funcs[i].name!=0) { - sq_pushstring(v,mathlib_funcs[i].name,-1); - sq_newclosure(v,mathlib_funcs[i].f,0); - sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask); - sq_setnativeclosurename(v,-1,mathlib_funcs[i].name); - sq_newslot(v,-3,SQFalse); - i++; - } - sq_pushstring(v,_SC("RAND_MAX"),-1); - sq_pushinteger(v,RAND_MAX); - sq_newslot(v,-3,SQFalse); - sq_pushstring(v,_SC("PI"),-1); - sq_pushfloat(v,(SQFloat)M_PI); - sq_newslot(v,-3,SQFalse); - return SQ_OK; -} +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include + +#define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \ + SQFloat f; \ + sq_getfloat(v,2,&f); \ + sq_pushfloat(v,(SQFloat)_funcname(f)); \ + return 1; \ +} + +#define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \ + SQFloat p1,p2; \ + sq_getfloat(v,2,&p1); \ + sq_getfloat(v,3,&p2); \ + sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \ + return 1; \ +} + +static SQInteger math_srand(HSQUIRRELVM v) +{ + SQInteger i; + if(SQ_FAILED(sq_getinteger(v,2,&i))) + return sq_throwerror(v,_SC("invalid param")); + srand((unsigned int)i); + return 0; +} + +static SQInteger math_rand(HSQUIRRELVM v) +{ + sq_pushinteger(v,rand()); + return 1; +} + +static SQInteger math_abs(HSQUIRRELVM v) +{ + SQInteger n; + sq_getinteger(v,2,&n); + sq_pushinteger(v,(SQInteger)abs((int)n)); + return 1; +} + +SINGLE_ARG_FUNC(sqrt) +SINGLE_ARG_FUNC(fabs) +SINGLE_ARG_FUNC(sin) +SINGLE_ARG_FUNC(cos) +SINGLE_ARG_FUNC(asin) +SINGLE_ARG_FUNC(acos) +SINGLE_ARG_FUNC(log) +SINGLE_ARG_FUNC(log10) +SINGLE_ARG_FUNC(tan) +SINGLE_ARG_FUNC(atan) +TWO_ARGS_FUNC(atan2) +TWO_ARGS_FUNC(pow) +SINGLE_ARG_FUNC(floor) +SINGLE_ARG_FUNC(ceil) +SINGLE_ARG_FUNC(exp) + +#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck} +static SQRegFunction mathlib_funcs[] = { + _DECL_FUNC(sqrt,2,_SC(".n")), + _DECL_FUNC(sin,2,_SC(".n")), + _DECL_FUNC(cos,2,_SC(".n")), + _DECL_FUNC(asin,2,_SC(".n")), + _DECL_FUNC(acos,2,_SC(".n")), + _DECL_FUNC(log,2,_SC(".n")), + _DECL_FUNC(log10,2,_SC(".n")), + _DECL_FUNC(tan,2,_SC(".n")), + _DECL_FUNC(atan,2,_SC(".n")), + _DECL_FUNC(atan2,3,_SC(".nn")), + _DECL_FUNC(pow,3,_SC(".nn")), + _DECL_FUNC(floor,2,_SC(".n")), + _DECL_FUNC(ceil,2,_SC(".n")), + _DECL_FUNC(exp,2,_SC(".n")), + _DECL_FUNC(srand,2,_SC(".n")), + _DECL_FUNC(rand,1,NULL), + _DECL_FUNC(fabs,2,_SC(".n")), + _DECL_FUNC(abs,2,_SC(".n")), + {0,0}, +}; +#undef _DECL_FUNC + +#ifndef M_PI +#define M_PI (3.14159265358979323846) +#endif + +SQRESULT sqstd_register_mathlib(HSQUIRRELVM v) +{ + SQInteger i=0; + while(mathlib_funcs[i].name!=0) { + sq_pushstring(v,mathlib_funcs[i].name,-1); + sq_newclosure(v,mathlib_funcs[i].f,0); + sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask); + sq_setnativeclosurename(v,-1,mathlib_funcs[i].name); + sq_newslot(v,-3,SQFalse); + i++; + } + sq_pushstring(v,_SC("RAND_MAX"),-1); + sq_pushinteger(v,RAND_MAX); + sq_newslot(v,-3,SQFalse); + sq_pushstring(v,_SC("PI"),-1); + sq_pushfloat(v,(SQFloat)M_PI); + sq_newslot(v,-3,SQFalse); + return SQ_OK; +} diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdrex.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdrex.cpp index 921597fed..a044d19dc 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdrex.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdrex.cpp @@ -1,638 +1,638 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include -#include - -#ifdef _UINCODE -#define scisprint iswprint -#else -#define scisprint isprint -#endif - -#ifdef _DEBUG -#include - -static const SQChar *g_nnames[] = -{ - _SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"), - _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"), - _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"), - _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB") -}; - -#endif - -#define OP_GREEDY (MAX_CHAR+1) // * + ? {n} -#define OP_OR (MAX_CHAR+2) -#define OP_EXPR (MAX_CHAR+3) //parentesis () -#define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:) -#define OP_DOT (MAX_CHAR+5) -#define OP_CLASS (MAX_CHAR+6) -#define OP_CCLASS (MAX_CHAR+7) -#define OP_NCLASS (MAX_CHAR+8) //negates class the [^ -#define OP_RANGE (MAX_CHAR+9) -#define OP_CHAR (MAX_CHAR+10) -#define OP_EOL (MAX_CHAR+11) -#define OP_BOL (MAX_CHAR+12) -#define OP_WB (MAX_CHAR+13) - -#define SQREX_SYMBOL_ANY_CHAR ('.') -#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE ('+') -#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*') -#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?') -#define SQREX_SYMBOL_BRANCH ('|') -#define SQREX_SYMBOL_END_OF_STRING ('$') -#define SQREX_SYMBOL_BEGINNING_OF_STRING ('^') -#define SQREX_SYMBOL_ESCAPE_CHAR ('\\') - - -typedef int SQRexNodeType; - -typedef struct tagSQRexNode{ - SQRexNodeType type; - SQInteger left; - SQInteger right; - SQInteger next; -}SQRexNode; - -struct SQRex{ - const SQChar *_eol; - const SQChar *_bol; - const SQChar *_p; - SQInteger _first; - SQInteger _op; - SQRexNode *_nodes; - SQInteger _nallocated; - SQInteger _nsize; - SQInteger _nsubexpr; - SQRexMatch *_matches; - SQInteger _currsubexp; - void *_jmpbuf; - const SQChar **_error; -}; - -static SQInteger sqstd_rex_list(SQRex *exp); - -static SQInteger sqstd_rex_newnode(SQRex *exp, SQRexNodeType type) -{ - SQRexNode n; - n.type = type; - n.next = n.right = n.left = -1; - if(type == OP_EXPR) - n.right = exp->_nsubexpr++; - if(exp->_nallocated < (exp->_nsize + 1)) { - SQInteger oldsize = exp->_nallocated; - exp->_nallocated *= 2; - exp->_nodes = (SQRexNode *)sq_realloc(exp->_nodes, oldsize * sizeof(SQRexNode) ,exp->_nallocated * sizeof(SQRexNode)); - } - exp->_nodes[exp->_nsize++] = n; - SQInteger newid = exp->_nsize - 1; - return (SQInteger)newid; -} - -static void sqstd_rex_error(SQRex *exp,const SQChar *error) -{ - if(exp->_error) *exp->_error = error; - longjmp(*((jmp_buf*)exp->_jmpbuf),-1); -} - -static void sqstd_rex_expect(SQRex *exp, SQInteger n){ - if((*exp->_p) != n) - sqstd_rex_error(exp, _SC("expected paren")); - exp->_p++; -} - -static SQChar sqstd_rex_escapechar(SQRex *exp) -{ - if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR){ - exp->_p++; - switch(*exp->_p) { - case 'v': exp->_p++; return '\v'; - case 'n': exp->_p++; return '\n'; - case 't': exp->_p++; return '\t'; - case 'r': exp->_p++; return '\r'; - case 'f': exp->_p++; return '\f'; - default: return (*exp->_p++); - } - } else if(!scisprint(*exp->_p)) sqstd_rex_error(exp,_SC("letter expected")); - return (*exp->_p++); -} - -static SQInteger sqstd_rex_charclass(SQRex *exp,SQInteger classid) -{ - SQInteger n = sqstd_rex_newnode(exp,OP_CCLASS); - exp->_nodes[n].left = classid; - return n; -} - -static SQInteger sqstd_rex_charnode(SQRex *exp,SQBool isclass) -{ - SQChar t; - if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR) { - exp->_p++; - switch(*exp->_p) { - case 'n': exp->_p++; return sqstd_rex_newnode(exp,'\n'); - case 't': exp->_p++; return sqstd_rex_newnode(exp,'\t'); - case 'r': exp->_p++; return sqstd_rex_newnode(exp,'\r'); - case 'f': exp->_p++; return sqstd_rex_newnode(exp,'\f'); - case 'v': exp->_p++; return sqstd_rex_newnode(exp,'\v'); - case 'a': case 'A': case 'w': case 'W': case 's': case 'S': - case 'd': case 'D': case 'x': case 'X': case 'c': case 'C': - case 'p': case 'P': case 'l': case 'u': - { - t = *exp->_p; exp->_p++; - return sqstd_rex_charclass(exp,t); - } - case 'b': - case 'B': - if(!isclass) { - SQInteger node = sqstd_rex_newnode(exp,OP_WB); - exp->_nodes[node].left = *exp->_p; - exp->_p++; - return node; - } //else default - default: - t = *exp->_p; exp->_p++; - return sqstd_rex_newnode(exp,t); - } - } - else if(!scisprint(*exp->_p)) { - - sqstd_rex_error(exp,_SC("letter expected")); - } - t = *exp->_p; exp->_p++; - return sqstd_rex_newnode(exp,t); -} -static SQInteger sqstd_rex_class(SQRex *exp) -{ - SQInteger ret = -1; - SQInteger first = -1,chain; - if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING){ - ret = sqstd_rex_newnode(exp,OP_NCLASS); - exp->_p++; - }else ret = sqstd_rex_newnode(exp,OP_CLASS); - - if(*exp->_p == ']') sqstd_rex_error(exp,_SC("empty class")); - chain = ret; - while(*exp->_p != ']' && exp->_p != exp->_eol) { - if(*exp->_p == '-' && first != -1){ - SQInteger r; - if(*exp->_p++ == ']') sqstd_rex_error(exp,_SC("unfinished range")); - r = sqstd_rex_newnode(exp,OP_RANGE); - if(exp->_nodes[first].type>*exp->_p) sqstd_rex_error(exp,_SC("invalid range")); - if(exp->_nodes[first].type == OP_CCLASS) sqstd_rex_error(exp,_SC("cannot use character classes in ranges")); - exp->_nodes[r].left = exp->_nodes[first].type; - SQInteger t = sqstd_rex_escapechar(exp); - exp->_nodes[r].right = t; - exp->_nodes[chain].next = r; - chain = r; - first = -1; - } - else{ - if(first!=-1){ - SQInteger c = first; - exp->_nodes[chain].next = c; - chain = c; - first = sqstd_rex_charnode(exp,SQTrue); - } - else{ - first = sqstd_rex_charnode(exp,SQTrue); - } - } - } - if(first!=-1){ - SQInteger c = first; - exp->_nodes[chain].next = c; - chain = c; - first = -1; - } - /* hack? */ - exp->_nodes[ret].left = exp->_nodes[ret].next; - exp->_nodes[ret].next = -1; - return ret; -} - -static SQInteger sqstd_rex_parsenumber(SQRex *exp) -{ - SQInteger ret = *exp->_p-'0'; - SQInteger positions = 10; - exp->_p++; - while(isdigit(*exp->_p)) { - ret = ret*10+(*exp->_p++-'0'); - if(positions==1000000000) sqstd_rex_error(exp,_SC("overflow in numeric constant")); - positions *= 10; - }; - return ret; -} - -static SQInteger sqstd_rex_element(SQRex *exp) -{ - SQInteger ret = -1; - switch(*exp->_p) - { - case '(': { - SQInteger expr; - exp->_p++; - - - if(*exp->_p =='?') { - exp->_p++; - sqstd_rex_expect(exp,':'); - expr = sqstd_rex_newnode(exp,OP_NOCAPEXPR); - } - else - expr = sqstd_rex_newnode(exp,OP_EXPR); - SQInteger newn = sqstd_rex_list(exp); - exp->_nodes[expr].left = newn; - ret = expr; - sqstd_rex_expect(exp,')'); - } - break; - case '[': - exp->_p++; - ret = sqstd_rex_class(exp); - sqstd_rex_expect(exp,']'); - break; - case SQREX_SYMBOL_END_OF_STRING: exp->_p++; ret = sqstd_rex_newnode(exp,OP_EOL);break; - case SQREX_SYMBOL_ANY_CHAR: exp->_p++; ret = sqstd_rex_newnode(exp,OP_DOT);break; - default: - ret = sqstd_rex_charnode(exp,SQFalse); - break; - } - - - SQInteger op; - SQBool isgreedy = SQFalse; - unsigned short p0 = 0, p1 = 0; - switch(*exp->_p){ - case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break; - case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break; - case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = SQTrue; break; - case '{': - exp->_p++; - if(!isdigit(*exp->_p)) sqstd_rex_error(exp,_SC("number expected")); - p0 = (unsigned short)sqstd_rex_parsenumber(exp); - /*******************************/ - switch(*exp->_p) { - case '}': - p1 = p0; exp->_p++; - break; - case ',': - exp->_p++; - p1 = 0xFFFF; - if(isdigit(*exp->_p)){ - p1 = (unsigned short)sqstd_rex_parsenumber(exp); - } - sqstd_rex_expect(exp,'}'); - break; - default: - sqstd_rex_error(exp,_SC(", or } expected")); - } - /*******************************/ - isgreedy = SQTrue; - break; - - } - if(isgreedy) { - SQInteger nnode = sqstd_rex_newnode(exp,OP_GREEDY); - op = OP_GREEDY; - exp->_nodes[nnode].left = ret; - exp->_nodes[nnode].right = ((p0)<<16)|p1; - ret = nnode; - } - - if((*exp->_p != SQREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != SQREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != SQREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) { - SQInteger nnode = sqstd_rex_element(exp); - exp->_nodes[ret].next = nnode; - } - - return ret; -} - -static SQInteger sqstd_rex_list(SQRex *exp) -{ - SQInteger ret=-1,e; - if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING) { - exp->_p++; - ret = sqstd_rex_newnode(exp,OP_BOL); - } - e = sqstd_rex_element(exp); - if(ret != -1) { - exp->_nodes[ret].next = e; - } - else ret = e; - - if(*exp->_p == SQREX_SYMBOL_BRANCH) { - SQInteger temp,tright; - exp->_p++; - temp = sqstd_rex_newnode(exp,OP_OR); - exp->_nodes[temp].left = ret; - tright = sqstd_rex_list(exp); - exp->_nodes[temp].right = tright; - ret = temp; - } - return ret; -} - -static SQBool sqstd_rex_matchcclass(SQInteger cclass,SQChar c) -{ - switch(cclass) { - case 'a': return isalpha(c)?SQTrue:SQFalse; - case 'A': return !isalpha(c)?SQTrue:SQFalse; - case 'w': return (isalnum(c) || c == '_')?SQTrue:SQFalse; - case 'W': return (!isalnum(c) && c != '_')?SQTrue:SQFalse; - case 's': return isspace(c)?SQTrue:SQFalse; - case 'S': return !isspace(c)?SQTrue:SQFalse; - case 'd': return isdigit(c)?SQTrue:SQFalse; - case 'D': return !isdigit(c)?SQTrue:SQFalse; - case 'x': return isxdigit(c)?SQTrue:SQFalse; - case 'X': return !isxdigit(c)?SQTrue:SQFalse; - case 'c': return iscntrl(c)?SQTrue:SQFalse; - case 'C': return !iscntrl(c)?SQTrue:SQFalse; - case 'p': return ispunct(c)?SQTrue:SQFalse; - case 'P': return !ispunct(c)?SQTrue:SQFalse; - case 'l': return islower(c)?SQTrue:SQFalse; - case 'u': return isupper(c)?SQTrue:SQFalse; - } - return SQFalse; /*cannot happen*/ -} - -static SQBool sqstd_rex_matchclass(SQRex* exp,SQRexNode *node,SQChar c) -{ - do { - switch(node->type) { - case OP_RANGE: - if(c >= node->left && c <= node->right) return SQTrue; - break; - case OP_CCLASS: - if(sqstd_rex_matchcclass(node->left,c)) return SQTrue; - break; - default: - if(c == node->type)return SQTrue; - } - } while((node->next != -1) && (node = &exp->_nodes[node->next])); - return SQFalse; -} - -static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar *str,SQRexNode *next) -{ - - SQRexNodeType type = node->type; - switch(type) { - case OP_GREEDY: { - //SQRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL; - SQRexNode *greedystop = NULL; - SQInteger p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0; - const SQChar *s=str, *good = str; - - if(node->next != -1) { - greedystop = &exp->_nodes[node->next]; - } - else { - greedystop = next; - } - - while((nmaches == 0xFFFF || nmaches < p1)) { - - const SQChar *stop; - if(!(s = sqstd_rex_matchnode(exp,&exp->_nodes[node->left],s,greedystop))) - break; - nmaches++; - good=s; - if(greedystop) { - //checks that 0 matches satisfy the expression(if so skips) - //if not would always stop(for instance if is a '?') - if(greedystop->type != OP_GREEDY || - (greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0)) - { - SQRexNode *gnext = NULL; - if(greedystop->next != -1) { - gnext = &exp->_nodes[greedystop->next]; - }else if(next && next->next != -1){ - gnext = &exp->_nodes[next->next]; - } - stop = sqstd_rex_matchnode(exp,greedystop,s,gnext); - if(stop) { - //if satisfied stop it - if(p0 == p1 && p0 == nmaches) break; - else if(nmaches >= p0 && p1 == 0xFFFF) break; - else if(nmaches >= p0 && nmaches <= p1) break; - } - } - } - - if(s >= exp->_eol) - break; - } - if(p0 == p1 && p0 == nmaches) return good; - else if(nmaches >= p0 && p1 == 0xFFFF) return good; - else if(nmaches >= p0 && nmaches <= p1) return good; - return NULL; - } - case OP_OR: { - const SQChar *asd = str; - SQRexNode *temp=&exp->_nodes[node->left]; - while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) { - if(temp->next != -1) - temp = &exp->_nodes[temp->next]; - else - return asd; - } - asd = str; - temp = &exp->_nodes[node->right]; - while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) { - if(temp->next != -1) - temp = &exp->_nodes[temp->next]; - else - return asd; - } - return NULL; - break; - } - case OP_EXPR: - case OP_NOCAPEXPR:{ - SQRexNode *n = &exp->_nodes[node->left]; - const SQChar *cur = str; - SQInteger capture = -1; - if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) { - capture = exp->_currsubexp; - exp->_matches[capture].begin = cur; - exp->_currsubexp++; - } - int tempcap = exp->_currsubexp; - do { - SQRexNode *subnext = NULL; - if(n->next != -1) { - subnext = &exp->_nodes[n->next]; - }else { - subnext = next; - } - if(!(cur = sqstd_rex_matchnode(exp,n,cur,subnext))) { - if(capture != -1){ - exp->_matches[capture].begin = 0; - exp->_matches[capture].len = 0; - } - return NULL; - } - } while((n->next != -1) && (n = &exp->_nodes[n->next])); - - exp->_currsubexp = tempcap; - if(capture != -1) - exp->_matches[capture].len = cur - exp->_matches[capture].begin; - return cur; - } - case OP_WB: - if((str == exp->_bol && !isspace(*str)) - || (str == exp->_eol && !isspace(*(str-1))) - || (!isspace(*str) && isspace(*(str+1))) - || (isspace(*str) && !isspace(*(str+1))) ) { - return (node->left == 'b')?str:NULL; - } - return (node->left == 'b')?NULL:str; - case OP_BOL: - if(str == exp->_bol) return str; - return NULL; - case OP_EOL: - if(str == exp->_eol) return str; - return NULL; - case OP_DOT:{ - *str++; - } - return str; - case OP_NCLASS: - case OP_CLASS: - if(sqstd_rex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?SQTrue:SQFalse):(type == OP_NCLASS?SQTrue:SQFalse)) { - *str++; - return str; - } - return NULL; - case OP_CCLASS: - if(sqstd_rex_matchcclass(node->left,*str)) { - *str++; - return str; - } - return NULL; - default: /* char */ - if(*str != node->type) return NULL; - *str++; - return str; - } - return NULL; -} - -/* public api */ -SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error) -{ - SQRex *exp = (SQRex *)sq_malloc(sizeof(SQRex)); - exp->_eol = exp->_bol = NULL; - exp->_p = pattern; - exp->_nallocated = (SQInteger)scstrlen(pattern) * sizeof(SQChar); - exp->_nodes = (SQRexNode *)sq_malloc(exp->_nallocated * sizeof(SQRexNode)); - exp->_nsize = 0; - exp->_matches = 0; - exp->_nsubexpr = 0; - exp->_first = sqstd_rex_newnode(exp,OP_EXPR); - exp->_error = error; - exp->_jmpbuf = sq_malloc(sizeof(jmp_buf)); - if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) { - SQInteger res = sqstd_rex_list(exp); - exp->_nodes[exp->_first].left = res; - if(*exp->_p!='\0') - sqstd_rex_error(exp,_SC("unexpected character")); -#ifdef _DEBUG - { - SQInteger nsize,i; - SQRexNode *t; - nsize = exp->_nsize; - t = &exp->_nodes[0]; - scprintf(_SC("\n")); - for(i = 0;i < nsize; i++) { - if(exp->_nodes[i].type>MAX_CHAR) - scprintf(_SC("[%02d] %10s "),i,g_nnames[exp->_nodes[i].type-MAX_CHAR]); - else - scprintf(_SC("[%02d] %10c "),i,exp->_nodes[i].type); - scprintf(_SC("left %02d right %02d next %02d\n"),exp->_nodes[i].left,exp->_nodes[i].right,exp->_nodes[i].next); - } - scprintf(_SC("\n")); - } -#endif - exp->_matches = (SQRexMatch *) sq_malloc(exp->_nsubexpr * sizeof(SQRexMatch)); - memset(exp->_matches,0,exp->_nsubexpr * sizeof(SQRexMatch)); - } - else{ - sqstd_rex_free(exp); - return NULL; - } - return exp; -} - -void sqstd_rex_free(SQRex *exp) -{ - if(exp) { - if(exp->_nodes) sq_free(exp->_nodes,exp->_nallocated * sizeof(SQRexNode)); - if(exp->_jmpbuf) sq_free(exp->_jmpbuf,sizeof(jmp_buf)); - if(exp->_matches) sq_free(exp->_matches,exp->_nsubexpr * sizeof(SQRexMatch)); - sq_free(exp,sizeof(SQRex)); - } -} - -SQBool sqstd_rex_match(SQRex* exp,const SQChar* text) -{ - const SQChar* res = NULL; - exp->_bol = text; - exp->_eol = text + scstrlen(text); - exp->_currsubexp = 0; - res = sqstd_rex_matchnode(exp,exp->_nodes,text,NULL); - if(res == NULL || res != exp->_eol) - return SQFalse; - return SQTrue; -} - -SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end) -{ - const SQChar *cur = NULL; - SQInteger node = exp->_first; - if(text_begin >= text_end) return SQFalse; - exp->_bol = text_begin; - exp->_eol = text_end; - do { - cur = text_begin; - while(node != -1) { - exp->_currsubexp = 0; - cur = sqstd_rex_matchnode(exp,&exp->_nodes[node],cur,NULL); - if(!cur) - break; - node = exp->_nodes[node].next; - } - *text_begin++; - } while(cur == NULL && text_begin != text_end); - - if(cur == NULL) - return SQFalse; - - --text_begin; - - if(out_begin) *out_begin = text_begin; - if(out_end) *out_end = cur; - return SQTrue; -} - -SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end) -{ - return sqstd_rex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end); -} - -SQInteger sqstd_rex_getsubexpcount(SQRex* exp) -{ - return exp->_nsubexpr; -} - -SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp) -{ - if( n<0 || n >= exp->_nsubexpr) return SQFalse; - *subexp = exp->_matches[n]; - return SQTrue; -} - +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include + +#ifdef _UINCODE +#define scisprint iswprint +#else +#define scisprint isprint +#endif + +#ifdef _DEBUG +#include + +static const SQChar *g_nnames[] = +{ + _SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"), + _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"), + _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"), + _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB") +}; + +#endif + +#define OP_GREEDY (MAX_CHAR+1) // * + ? {n} +#define OP_OR (MAX_CHAR+2) +#define OP_EXPR (MAX_CHAR+3) //parentesis () +#define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:) +#define OP_DOT (MAX_CHAR+5) +#define OP_CLASS (MAX_CHAR+6) +#define OP_CCLASS (MAX_CHAR+7) +#define OP_NCLASS (MAX_CHAR+8) //negates class the [^ +#define OP_RANGE (MAX_CHAR+9) +#define OP_CHAR (MAX_CHAR+10) +#define OP_EOL (MAX_CHAR+11) +#define OP_BOL (MAX_CHAR+12) +#define OP_WB (MAX_CHAR+13) + +#define SQREX_SYMBOL_ANY_CHAR ('.') +#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE ('+') +#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*') +#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?') +#define SQREX_SYMBOL_BRANCH ('|') +#define SQREX_SYMBOL_END_OF_STRING ('$') +#define SQREX_SYMBOL_BEGINNING_OF_STRING ('^') +#define SQREX_SYMBOL_ESCAPE_CHAR ('\\') + + +typedef int SQRexNodeType; + +typedef struct tagSQRexNode{ + SQRexNodeType type; + SQInteger left; + SQInteger right; + SQInteger next; +}SQRexNode; + +struct SQRex{ + const SQChar *_eol; + const SQChar *_bol; + const SQChar *_p; + SQInteger _first; + SQInteger _op; + SQRexNode *_nodes; + SQInteger _nallocated; + SQInteger _nsize; + SQInteger _nsubexpr; + SQRexMatch *_matches; + SQInteger _currsubexp; + void *_jmpbuf; + const SQChar **_error; +}; + +static SQInteger sqstd_rex_list(SQRex *exp); + +static SQInteger sqstd_rex_newnode(SQRex *exp, SQRexNodeType type) +{ + SQRexNode n; + n.type = type; + n.next = n.right = n.left = -1; + if(type == OP_EXPR) + n.right = exp->_nsubexpr++; + if(exp->_nallocated < (exp->_nsize + 1)) { + SQInteger oldsize = exp->_nallocated; + exp->_nallocated *= 2; + exp->_nodes = (SQRexNode *)sq_realloc(exp->_nodes, oldsize * sizeof(SQRexNode) ,exp->_nallocated * sizeof(SQRexNode)); + } + exp->_nodes[exp->_nsize++] = n; + SQInteger newid = exp->_nsize - 1; + return (SQInteger)newid; +} + +static void sqstd_rex_error(SQRex *exp,const SQChar *error) +{ + if(exp->_error) *exp->_error = error; + longjmp(*((jmp_buf*)exp->_jmpbuf),-1); +} + +static void sqstd_rex_expect(SQRex *exp, SQInteger n){ + if((*exp->_p) != n) + sqstd_rex_error(exp, _SC("expected paren")); + exp->_p++; +} + +static SQChar sqstd_rex_escapechar(SQRex *exp) +{ + if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR){ + exp->_p++; + switch(*exp->_p) { + case 'v': exp->_p++; return '\v'; + case 'n': exp->_p++; return '\n'; + case 't': exp->_p++; return '\t'; + case 'r': exp->_p++; return '\r'; + case 'f': exp->_p++; return '\f'; + default: return (*exp->_p++); + } + } else if(!scisprint(*exp->_p)) sqstd_rex_error(exp,_SC("letter expected")); + return (*exp->_p++); +} + +static SQInteger sqstd_rex_charclass(SQRex *exp,SQInteger classid) +{ + SQInteger n = sqstd_rex_newnode(exp,OP_CCLASS); + exp->_nodes[n].left = classid; + return n; +} + +static SQInteger sqstd_rex_charnode(SQRex *exp,SQBool isclass) +{ + SQChar t; + if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR) { + exp->_p++; + switch(*exp->_p) { + case 'n': exp->_p++; return sqstd_rex_newnode(exp,'\n'); + case 't': exp->_p++; return sqstd_rex_newnode(exp,'\t'); + case 'r': exp->_p++; return sqstd_rex_newnode(exp,'\r'); + case 'f': exp->_p++; return sqstd_rex_newnode(exp,'\f'); + case 'v': exp->_p++; return sqstd_rex_newnode(exp,'\v'); + case 'a': case 'A': case 'w': case 'W': case 's': case 'S': + case 'd': case 'D': case 'x': case 'X': case 'c': case 'C': + case 'p': case 'P': case 'l': case 'u': + { + t = *exp->_p; exp->_p++; + return sqstd_rex_charclass(exp,t); + } + case 'b': + case 'B': + if(!isclass) { + SQInteger node = sqstd_rex_newnode(exp,OP_WB); + exp->_nodes[node].left = *exp->_p; + exp->_p++; + return node; + } //else default + default: + t = *exp->_p; exp->_p++; + return sqstd_rex_newnode(exp,t); + } + } + else if(!scisprint(*exp->_p)) { + + sqstd_rex_error(exp,_SC("letter expected")); + } + t = *exp->_p; exp->_p++; + return sqstd_rex_newnode(exp,t); +} +static SQInteger sqstd_rex_class(SQRex *exp) +{ + SQInteger ret = -1; + SQInteger first = -1,chain; + if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING){ + ret = sqstd_rex_newnode(exp,OP_NCLASS); + exp->_p++; + }else ret = sqstd_rex_newnode(exp,OP_CLASS); + + if(*exp->_p == ']') sqstd_rex_error(exp,_SC("empty class")); + chain = ret; + while(*exp->_p != ']' && exp->_p != exp->_eol) { + if(*exp->_p == '-' && first != -1){ + SQInteger r; + if(*exp->_p++ == ']') sqstd_rex_error(exp,_SC("unfinished range")); + r = sqstd_rex_newnode(exp,OP_RANGE); + if(exp->_nodes[first].type>*exp->_p) sqstd_rex_error(exp,_SC("invalid range")); + if(exp->_nodes[first].type == OP_CCLASS) sqstd_rex_error(exp,_SC("cannot use character classes in ranges")); + exp->_nodes[r].left = exp->_nodes[first].type; + SQInteger t = sqstd_rex_escapechar(exp); + exp->_nodes[r].right = t; + exp->_nodes[chain].next = r; + chain = r; + first = -1; + } + else{ + if(first!=-1){ + SQInteger c = first; + exp->_nodes[chain].next = c; + chain = c; + first = sqstd_rex_charnode(exp,SQTrue); + } + else{ + first = sqstd_rex_charnode(exp,SQTrue); + } + } + } + if(first!=-1){ + SQInteger c = first; + exp->_nodes[chain].next = c; + chain = c; + first = -1; + } + /* hack? */ + exp->_nodes[ret].left = exp->_nodes[ret].next; + exp->_nodes[ret].next = -1; + return ret; +} + +static SQInteger sqstd_rex_parsenumber(SQRex *exp) +{ + SQInteger ret = *exp->_p-'0'; + SQInteger positions = 10; + exp->_p++; + while(isdigit(*exp->_p)) { + ret = ret*10+(*exp->_p++-'0'); + if(positions==1000000000) sqstd_rex_error(exp,_SC("overflow in numeric constant")); + positions *= 10; + }; + return ret; +} + +static SQInteger sqstd_rex_element(SQRex *exp) +{ + SQInteger ret = -1; + switch(*exp->_p) + { + case '(': { + SQInteger expr; + exp->_p++; + + + if(*exp->_p =='?') { + exp->_p++; + sqstd_rex_expect(exp,':'); + expr = sqstd_rex_newnode(exp,OP_NOCAPEXPR); + } + else + expr = sqstd_rex_newnode(exp,OP_EXPR); + SQInteger newn = sqstd_rex_list(exp); + exp->_nodes[expr].left = newn; + ret = expr; + sqstd_rex_expect(exp,')'); + } + break; + case '[': + exp->_p++; + ret = sqstd_rex_class(exp); + sqstd_rex_expect(exp,']'); + break; + case SQREX_SYMBOL_END_OF_STRING: exp->_p++; ret = sqstd_rex_newnode(exp,OP_EOL);break; + case SQREX_SYMBOL_ANY_CHAR: exp->_p++; ret = sqstd_rex_newnode(exp,OP_DOT);break; + default: + ret = sqstd_rex_charnode(exp,SQFalse); + break; + } + + + SQInteger op; + SQBool isgreedy = SQFalse; + unsigned short p0 = 0, p1 = 0; + switch(*exp->_p){ + case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break; + case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break; + case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = SQTrue; break; + case '{': + exp->_p++; + if(!isdigit(*exp->_p)) sqstd_rex_error(exp,_SC("number expected")); + p0 = (unsigned short)sqstd_rex_parsenumber(exp); + /*******************************/ + switch(*exp->_p) { + case '}': + p1 = p0; exp->_p++; + break; + case ',': + exp->_p++; + p1 = 0xFFFF; + if(isdigit(*exp->_p)){ + p1 = (unsigned short)sqstd_rex_parsenumber(exp); + } + sqstd_rex_expect(exp,'}'); + break; + default: + sqstd_rex_error(exp,_SC(", or } expected")); + } + /*******************************/ + isgreedy = SQTrue; + break; + + } + if(isgreedy) { + SQInteger nnode = sqstd_rex_newnode(exp,OP_GREEDY); + op = OP_GREEDY; + exp->_nodes[nnode].left = ret; + exp->_nodes[nnode].right = ((p0)<<16)|p1; + ret = nnode; + } + + if((*exp->_p != SQREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != SQREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != SQREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) { + SQInteger nnode = sqstd_rex_element(exp); + exp->_nodes[ret].next = nnode; + } + + return ret; +} + +static SQInteger sqstd_rex_list(SQRex *exp) +{ + SQInteger ret=-1,e; + if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING) { + exp->_p++; + ret = sqstd_rex_newnode(exp,OP_BOL); + } + e = sqstd_rex_element(exp); + if(ret != -1) { + exp->_nodes[ret].next = e; + } + else ret = e; + + if(*exp->_p == SQREX_SYMBOL_BRANCH) { + SQInteger temp,tright; + exp->_p++; + temp = sqstd_rex_newnode(exp,OP_OR); + exp->_nodes[temp].left = ret; + tright = sqstd_rex_list(exp); + exp->_nodes[temp].right = tright; + ret = temp; + } + return ret; +} + +static SQBool sqstd_rex_matchcclass(SQInteger cclass,SQChar c) +{ + switch(cclass) { + case 'a': return isalpha(c)?SQTrue:SQFalse; + case 'A': return !isalpha(c)?SQTrue:SQFalse; + case 'w': return (isalnum(c) || c == '_')?SQTrue:SQFalse; + case 'W': return (!isalnum(c) && c != '_')?SQTrue:SQFalse; + case 's': return isspace(c)?SQTrue:SQFalse; + case 'S': return !isspace(c)?SQTrue:SQFalse; + case 'd': return isdigit(c)?SQTrue:SQFalse; + case 'D': return !isdigit(c)?SQTrue:SQFalse; + case 'x': return isxdigit(c)?SQTrue:SQFalse; + case 'X': return !isxdigit(c)?SQTrue:SQFalse; + case 'c': return iscntrl(c)?SQTrue:SQFalse; + case 'C': return !iscntrl(c)?SQTrue:SQFalse; + case 'p': return ispunct(c)?SQTrue:SQFalse; + case 'P': return !ispunct(c)?SQTrue:SQFalse; + case 'l': return islower(c)?SQTrue:SQFalse; + case 'u': return isupper(c)?SQTrue:SQFalse; + } + return SQFalse; /*cannot happen*/ +} + +static SQBool sqstd_rex_matchclass(SQRex* exp,SQRexNode *node,SQChar c) +{ + do { + switch(node->type) { + case OP_RANGE: + if(c >= node->left && c <= node->right) return SQTrue; + break; + case OP_CCLASS: + if(sqstd_rex_matchcclass(node->left,c)) return SQTrue; + break; + default: + if(c == node->type)return SQTrue; + } + } while((node->next != -1) && (node = &exp->_nodes[node->next])); + return SQFalse; +} + +static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar *str,SQRexNode *next) +{ + + SQRexNodeType type = node->type; + switch(type) { + case OP_GREEDY: { + //SQRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL; + SQRexNode *greedystop = NULL; + SQInteger p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0; + const SQChar *s=str, *good = str; + + if(node->next != -1) { + greedystop = &exp->_nodes[node->next]; + } + else { + greedystop = next; + } + + while((nmaches == 0xFFFF || nmaches < p1)) { + + const SQChar *stop; + if(!(s = sqstd_rex_matchnode(exp,&exp->_nodes[node->left],s,greedystop))) + break; + nmaches++; + good=s; + if(greedystop) { + //checks that 0 matches satisfy the expression(if so skips) + //if not would always stop(for instance if is a '?') + if(greedystop->type != OP_GREEDY || + (greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0)) + { + SQRexNode *gnext = NULL; + if(greedystop->next != -1) { + gnext = &exp->_nodes[greedystop->next]; + }else if(next && next->next != -1){ + gnext = &exp->_nodes[next->next]; + } + stop = sqstd_rex_matchnode(exp,greedystop,s,gnext); + if(stop) { + //if satisfied stop it + if(p0 == p1 && p0 == nmaches) break; + else if(nmaches >= p0 && p1 == 0xFFFF) break; + else if(nmaches >= p0 && nmaches <= p1) break; + } + } + } + + if(s >= exp->_eol) + break; + } + if(p0 == p1 && p0 == nmaches) return good; + else if(nmaches >= p0 && p1 == 0xFFFF) return good; + else if(nmaches >= p0 && nmaches <= p1) return good; + return NULL; + } + case OP_OR: { + const SQChar *asd = str; + SQRexNode *temp=&exp->_nodes[node->left]; + while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) { + if(temp->next != -1) + temp = &exp->_nodes[temp->next]; + else + return asd; + } + asd = str; + temp = &exp->_nodes[node->right]; + while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) { + if(temp->next != -1) + temp = &exp->_nodes[temp->next]; + else + return asd; + } + return NULL; + break; + } + case OP_EXPR: + case OP_NOCAPEXPR:{ + SQRexNode *n = &exp->_nodes[node->left]; + const SQChar *cur = str; + SQInteger capture = -1; + if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) { + capture = exp->_currsubexp; + exp->_matches[capture].begin = cur; + exp->_currsubexp++; + } + int tempcap = exp->_currsubexp; + do { + SQRexNode *subnext = NULL; + if(n->next != -1) { + subnext = &exp->_nodes[n->next]; + }else { + subnext = next; + } + if(!(cur = sqstd_rex_matchnode(exp,n,cur,subnext))) { + if(capture != -1){ + exp->_matches[capture].begin = 0; + exp->_matches[capture].len = 0; + } + return NULL; + } + } while((n->next != -1) && (n = &exp->_nodes[n->next])); + + exp->_currsubexp = tempcap; + if(capture != -1) + exp->_matches[capture].len = cur - exp->_matches[capture].begin; + return cur; + } + case OP_WB: + if((str == exp->_bol && !isspace(*str)) + || (str == exp->_eol && !isspace(*(str-1))) + || (!isspace(*str) && isspace(*(str+1))) + || (isspace(*str) && !isspace(*(str+1))) ) { + return (node->left == 'b')?str:NULL; + } + return (node->left == 'b')?NULL:str; + case OP_BOL: + if(str == exp->_bol) return str; + return NULL; + case OP_EOL: + if(str == exp->_eol) return str; + return NULL; + case OP_DOT:{ + *str++; + } + return str; + case OP_NCLASS: + case OP_CLASS: + if(sqstd_rex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?SQTrue:SQFalse):(type == OP_NCLASS?SQTrue:SQFalse)) { + *str++; + return str; + } + return NULL; + case OP_CCLASS: + if(sqstd_rex_matchcclass(node->left,*str)) { + *str++; + return str; + } + return NULL; + default: /* char */ + if(*str != node->type) return NULL; + *str++; + return str; + } + return NULL; +} + +/* public api */ +SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error) +{ + SQRex *exp = (SQRex *)sq_malloc(sizeof(SQRex)); + exp->_eol = exp->_bol = NULL; + exp->_p = pattern; + exp->_nallocated = (SQInteger)scstrlen(pattern) * sizeof(SQChar); + exp->_nodes = (SQRexNode *)sq_malloc(exp->_nallocated * sizeof(SQRexNode)); + exp->_nsize = 0; + exp->_matches = 0; + exp->_nsubexpr = 0; + exp->_first = sqstd_rex_newnode(exp,OP_EXPR); + exp->_error = error; + exp->_jmpbuf = sq_malloc(sizeof(jmp_buf)); + if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) { + SQInteger res = sqstd_rex_list(exp); + exp->_nodes[exp->_first].left = res; + if(*exp->_p!='\0') + sqstd_rex_error(exp,_SC("unexpected character")); +#ifdef _DEBUG + { + SQInteger nsize,i; + SQRexNode *t; + nsize = exp->_nsize; + t = &exp->_nodes[0]; + scprintf(_SC("\n")); + for(i = 0;i < nsize; i++) { + if(exp->_nodes[i].type>MAX_CHAR) + scprintf(_SC("[%02d] %10s "),i,g_nnames[exp->_nodes[i].type-MAX_CHAR]); + else + scprintf(_SC("[%02d] %10c "),i,exp->_nodes[i].type); + scprintf(_SC("left %02d right %02d next %02d\n"),exp->_nodes[i].left,exp->_nodes[i].right,exp->_nodes[i].next); + } + scprintf(_SC("\n")); + } +#endif + exp->_matches = (SQRexMatch *) sq_malloc(exp->_nsubexpr * sizeof(SQRexMatch)); + memset(exp->_matches,0,exp->_nsubexpr * sizeof(SQRexMatch)); + } + else{ + sqstd_rex_free(exp); + return NULL; + } + return exp; +} + +void sqstd_rex_free(SQRex *exp) +{ + if(exp) { + if(exp->_nodes) sq_free(exp->_nodes,exp->_nallocated * sizeof(SQRexNode)); + if(exp->_jmpbuf) sq_free(exp->_jmpbuf,sizeof(jmp_buf)); + if(exp->_matches) sq_free(exp->_matches,exp->_nsubexpr * sizeof(SQRexMatch)); + sq_free(exp,sizeof(SQRex)); + } +} + +SQBool sqstd_rex_match(SQRex* exp,const SQChar* text) +{ + const SQChar* res = NULL; + exp->_bol = text; + exp->_eol = text + scstrlen(text); + exp->_currsubexp = 0; + res = sqstd_rex_matchnode(exp,exp->_nodes,text,NULL); + if(res == NULL || res != exp->_eol) + return SQFalse; + return SQTrue; +} + +SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end) +{ + const SQChar *cur = NULL; + SQInteger node = exp->_first; + if(text_begin >= text_end) return SQFalse; + exp->_bol = text_begin; + exp->_eol = text_end; + do { + cur = text_begin; + while(node != -1) { + exp->_currsubexp = 0; + cur = sqstd_rex_matchnode(exp,&exp->_nodes[node],cur,NULL); + if(!cur) + break; + node = exp->_nodes[node].next; + } + *text_begin++; + } while(cur == NULL && text_begin != text_end); + + if(cur == NULL) + return SQFalse; + + --text_begin; + + if(out_begin) *out_begin = text_begin; + if(out_end) *out_end = cur; + return SQTrue; +} + +SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end) +{ + return sqstd_rex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end); +} + +SQInteger sqstd_rex_getsubexpcount(SQRex* exp) +{ + return exp->_nsubexpr; +} + +SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp) +{ + if( n<0 || n >= exp->_nsubexpr) return SQFalse; + *subexp = exp->_matches[n]; + return SQTrue; +} + diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdstream.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdstream.cpp index 29fbdd601..56140f6ad 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdstream.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdstream.cpp @@ -1,336 +1,336 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include -#include -#include -#include -#include "sqstdstream.h" -#include "sqstdblobimpl.h" - -#define SETUP_STREAM(v) \ - SQStream *self = NULL; \ - if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \ - return sq_throwerror(v,_SC("invalid type tag")); \ - if(!self->IsValid()) \ - return sq_throwerror(v,_SC("the stream is invalid")); - -SQInteger _stream_readblob(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - SQUserPointer data,blobp; - SQInteger size,res; - sq_getinteger(v,2,&size); - if(size > self->Len()) { - size = self->Len(); - } - data = sq_getscratchpad(v,size); - res = self->Read(data,size); - if(res <= 0) - return sq_throwerror(v,_SC("no data left to read")); - blobp = sqstd_createblob(v,res); - memcpy(blobp,data,res); - return 1; -} - -#define SAFE_READN(ptr,len) { \ - if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \ - } -SQInteger _stream_readn(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - SQInteger format; - sq_getinteger(v, 2, &format); - switch(format) { - case 'l': { - SQInteger i; - SAFE_READN(&i, sizeof(i)); - sq_pushinteger(v, i); - } - break; - case 'i': { - SQInt32 i; - SAFE_READN(&i, sizeof(i)); - sq_pushinteger(v, i); - } - break; - case 's': { - short s; - SAFE_READN(&s, sizeof(short)); - sq_pushinteger(v, s); - } - break; - case 'w': { - unsigned short w; - SAFE_READN(&w, sizeof(unsigned short)); - sq_pushinteger(v, w); - } - break; - case 'c': { - char c; - SAFE_READN(&c, sizeof(char)); - sq_pushinteger(v, c); - } - break; - case 'b': { - unsigned char c; - SAFE_READN(&c, sizeof(unsigned char)); - sq_pushinteger(v, c); - } - break; - case 'f': { - float f; - SAFE_READN(&f, sizeof(float)); - sq_pushfloat(v, f); - } - break; - case 'd': { - double d; - SAFE_READN(&d, sizeof(double)); - sq_pushfloat(v, (SQFloat)d); - } - break; - default: - return sq_throwerror(v, _SC("invalid format")); - } - return 1; -} - -SQInteger _stream_writeblob(HSQUIRRELVM v) -{ - SQUserPointer data; - SQInteger size; - SETUP_STREAM(v); - if(SQ_FAILED(sqstd_getblob(v,2,&data))) - return sq_throwerror(v,_SC("invalid parameter")); - size = sqstd_getblobsize(v,2); - if(self->Write(data,size) != size) - return sq_throwerror(v,_SC("io error")); - sq_pushinteger(v,size); - return 1; -} - -SQInteger _stream_writen(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - SQInteger format, ti; - SQFloat tf; - sq_getinteger(v, 3, &format); - switch(format) { - case 'l': { - SQInteger i; - sq_getinteger(v, 2, &ti); - i = ti; - self->Write(&i, sizeof(SQInteger)); - } - break; - case 'i': { - SQInt32 i; - sq_getinteger(v, 2, &ti); - i = (SQInt32)ti; - self->Write(&i, sizeof(SQInt32)); - } - break; - case 's': { - short s; - sq_getinteger(v, 2, &ti); - s = (short)ti; - self->Write(&s, sizeof(short)); - } - break; - case 'w': { - unsigned short w; - sq_getinteger(v, 2, &ti); - w = (unsigned short)ti; - self->Write(&w, sizeof(unsigned short)); - } - break; - case 'c': { - char c; - sq_getinteger(v, 2, &ti); - c = (char)ti; - self->Write(&c, sizeof(char)); - } - break; - case 'b': { - unsigned char b; - sq_getinteger(v, 2, &ti); - b = (unsigned char)ti; - self->Write(&b, sizeof(unsigned char)); - } - break; - case 'f': { - float f; - sq_getfloat(v, 2, &tf); - f = (float)tf; - self->Write(&f, sizeof(float)); - } - break; - case 'd': { - double d; - sq_getfloat(v, 2, &tf); - d = tf; - self->Write(&d, sizeof(double)); - } - break; - default: - return sq_throwerror(v, _SC("invalid format")); - } - return 0; -} - -SQInteger _stream_seek(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - SQInteger offset, origin = SQ_SEEK_SET; - sq_getinteger(v, 2, &offset); - if(sq_gettop(v) > 2) { - SQInteger t; - sq_getinteger(v, 3, &t); - switch(t) { - case 'b': origin = SQ_SEEK_SET; break; - case 'c': origin = SQ_SEEK_CUR; break; - case 'e': origin = SQ_SEEK_END; break; - default: return sq_throwerror(v,_SC("invalid origin")); - } - } - sq_pushinteger(v, self->Seek(offset, origin)); - return 1; -} - -SQInteger _stream_tell(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - sq_pushinteger(v, self->Tell()); - return 1; -} - -SQInteger _stream_len(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - sq_pushinteger(v, self->Len()); - return 1; -} - -SQInteger _stream_flush(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - if(!self->Flush()) - sq_pushinteger(v, 1); - else - sq_pushnull(v); - return 1; -} - -SQInteger _stream_eos(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - if(self->EOS()) - sq_pushinteger(v, 1); - else - sq_pushnull(v); - return 1; -} - - SQInteger _stream__cloned(HSQUIRRELVM v) - { - return sq_throwerror(v,_SC("this object cannot be cloned")); - } - -static SQRegFunction _stream_methods[] = { - _DECL_STREAM_FUNC(readblob,2,_SC("xn")), - _DECL_STREAM_FUNC(readn,2,_SC("xn")), - _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")), - _DECL_STREAM_FUNC(writen,3,_SC("xnn")), - _DECL_STREAM_FUNC(seek,-2,_SC("xnn")), - _DECL_STREAM_FUNC(tell,1,_SC("x")), - _DECL_STREAM_FUNC(len,1,_SC("x")), - _DECL_STREAM_FUNC(eos,1,_SC("x")), - _DECL_STREAM_FUNC(flush,1,_SC("x")), - _DECL_STREAM_FUNC(_cloned,0,NULL), - {0,0} -}; - -void init_streamclass(HSQUIRRELVM v) -{ - sq_pushregistrytable(v); - sq_pushstring(v,_SC("std_stream"),-1); - if(SQ_FAILED(sq_get(v,-2))) { - sq_pushstring(v,_SC("std_stream"),-1); - sq_newclass(v,SQFalse); - sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG); - SQInteger i = 0; - while(_stream_methods[i].name != 0) { - SQRegFunction &f = _stream_methods[i]; - sq_pushstring(v,f.name,-1); - sq_newclosure(v,f.f,0); - sq_setparamscheck(v,f.nparamscheck,f.typemask); - sq_newslot(v,-3,SQFalse); - i++; - } - sq_newslot(v,-3,SQFalse); - sq_pushroottable(v); - sq_pushstring(v,_SC("stream"),-1); - sq_pushstring(v,_SC("std_stream"),-1); - sq_get(v,-4); - sq_newslot(v,-3,SQFalse); - sq_pop(v,1); - } - else { - sq_pop(v,1); //result - } - sq_pop(v,1); -} - -SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals) -{ - if(sq_gettype(v,-1) != OT_TABLE) - return sq_throwerror(v,_SC("table expected")); - SQInteger top = sq_gettop(v); - //create delegate - init_streamclass(v); - sq_pushregistrytable(v); - sq_pushstring(v,reg_name,-1); - sq_pushstring(v,_SC("std_stream"),-1); - if(SQ_SUCCEEDED(sq_get(v,-3))) { - sq_newclass(v,SQTrue); - sq_settypetag(v,-1,typetag); - SQInteger i = 0; - while(methods[i].name != 0) { - SQRegFunction &f = methods[i]; - sq_pushstring(v,f.name,-1); - sq_newclosure(v,f.f,0); - sq_setparamscheck(v,f.nparamscheck,f.typemask); - sq_setnativeclosurename(v,-1,f.name); - sq_newslot(v,-3,SQFalse); - i++; - } - sq_newslot(v,-3,SQFalse); - sq_pop(v,1); - - i = 0; - while(globals[i].name!=0) - { - SQRegFunction &f = globals[i]; - sq_pushstring(v,f.name,-1); - sq_newclosure(v,f.f,0); - sq_setparamscheck(v,f.nparamscheck,f.typemask); - sq_setnativeclosurename(v,-1,f.name); - sq_newslot(v,-3,SQFalse); - i++; - } - //register the class in the target table - sq_pushstring(v,name,-1); - sq_pushregistrytable(v); - sq_pushstring(v,reg_name,-1); - sq_get(v,-2); - sq_remove(v,-2); - sq_newslot(v,-3,SQFalse); - - sq_settop(v,top); - return SQ_OK; - } - sq_settop(v,top); - return SQ_ERROR; -} +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include +#include +#include +#include "sqstdstream.h" +#include "sqstdblobimpl.h" + +#define SETUP_STREAM(v) \ + SQStream *self = NULL; \ + if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \ + return sq_throwerror(v,_SC("invalid type tag")); \ + if(!self->IsValid()) \ + return sq_throwerror(v,_SC("the stream is invalid")); + +SQInteger _stream_readblob(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + SQUserPointer data,blobp; + SQInteger size,res; + sq_getinteger(v,2,&size); + if(size > self->Len()) { + size = self->Len(); + } + data = sq_getscratchpad(v,size); + res = self->Read(data,size); + if(res <= 0) + return sq_throwerror(v,_SC("no data left to read")); + blobp = sqstd_createblob(v,res); + memcpy(blobp,data,res); + return 1; +} + +#define SAFE_READN(ptr,len) { \ + if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \ + } +SQInteger _stream_readn(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + SQInteger format; + sq_getinteger(v, 2, &format); + switch(format) { + case 'l': { + SQInteger i; + SAFE_READN(&i, sizeof(i)); + sq_pushinteger(v, i); + } + break; + case 'i': { + SQInt32 i; + SAFE_READN(&i, sizeof(i)); + sq_pushinteger(v, i); + } + break; + case 's': { + short s; + SAFE_READN(&s, sizeof(short)); + sq_pushinteger(v, s); + } + break; + case 'w': { + unsigned short w; + SAFE_READN(&w, sizeof(unsigned short)); + sq_pushinteger(v, w); + } + break; + case 'c': { + char c; + SAFE_READN(&c, sizeof(char)); + sq_pushinteger(v, c); + } + break; + case 'b': { + unsigned char c; + SAFE_READN(&c, sizeof(unsigned char)); + sq_pushinteger(v, c); + } + break; + case 'f': { + float f; + SAFE_READN(&f, sizeof(float)); + sq_pushfloat(v, f); + } + break; + case 'd': { + double d; + SAFE_READN(&d, sizeof(double)); + sq_pushfloat(v, (SQFloat)d); + } + break; + default: + return sq_throwerror(v, _SC("invalid format")); + } + return 1; +} + +SQInteger _stream_writeblob(HSQUIRRELVM v) +{ + SQUserPointer data; + SQInteger size; + SETUP_STREAM(v); + if(SQ_FAILED(sqstd_getblob(v,2,&data))) + return sq_throwerror(v,_SC("invalid parameter")); + size = sqstd_getblobsize(v,2); + if(self->Write(data,size) != size) + return sq_throwerror(v,_SC("io error")); + sq_pushinteger(v,size); + return 1; +} + +SQInteger _stream_writen(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + SQInteger format, ti; + SQFloat tf; + sq_getinteger(v, 3, &format); + switch(format) { + case 'l': { + SQInteger i; + sq_getinteger(v, 2, &ti); + i = ti; + self->Write(&i, sizeof(SQInteger)); + } + break; + case 'i': { + SQInt32 i; + sq_getinteger(v, 2, &ti); + i = (SQInt32)ti; + self->Write(&i, sizeof(SQInt32)); + } + break; + case 's': { + short s; + sq_getinteger(v, 2, &ti); + s = (short)ti; + self->Write(&s, sizeof(short)); + } + break; + case 'w': { + unsigned short w; + sq_getinteger(v, 2, &ti); + w = (unsigned short)ti; + self->Write(&w, sizeof(unsigned short)); + } + break; + case 'c': { + char c; + sq_getinteger(v, 2, &ti); + c = (char)ti; + self->Write(&c, sizeof(char)); + } + break; + case 'b': { + unsigned char b; + sq_getinteger(v, 2, &ti); + b = (unsigned char)ti; + self->Write(&b, sizeof(unsigned char)); + } + break; + case 'f': { + float f; + sq_getfloat(v, 2, &tf); + f = (float)tf; + self->Write(&f, sizeof(float)); + } + break; + case 'd': { + double d; + sq_getfloat(v, 2, &tf); + d = tf; + self->Write(&d, sizeof(double)); + } + break; + default: + return sq_throwerror(v, _SC("invalid format")); + } + return 0; +} + +SQInteger _stream_seek(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + SQInteger offset, origin = SQ_SEEK_SET; + sq_getinteger(v, 2, &offset); + if(sq_gettop(v) > 2) { + SQInteger t; + sq_getinteger(v, 3, &t); + switch(t) { + case 'b': origin = SQ_SEEK_SET; break; + case 'c': origin = SQ_SEEK_CUR; break; + case 'e': origin = SQ_SEEK_END; break; + default: return sq_throwerror(v,_SC("invalid origin")); + } + } + sq_pushinteger(v, self->Seek(offset, origin)); + return 1; +} + +SQInteger _stream_tell(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + sq_pushinteger(v, self->Tell()); + return 1; +} + +SQInteger _stream_len(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + sq_pushinteger(v, self->Len()); + return 1; +} + +SQInteger _stream_flush(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + if(!self->Flush()) + sq_pushinteger(v, 1); + else + sq_pushnull(v); + return 1; +} + +SQInteger _stream_eos(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + if(self->EOS()) + sq_pushinteger(v, 1); + else + sq_pushnull(v); + return 1; +} + + SQInteger _stream__cloned(HSQUIRRELVM v) + { + return sq_throwerror(v,_SC("this object cannot be cloned")); + } + +static SQRegFunction _stream_methods[] = { + _DECL_STREAM_FUNC(readblob,2,_SC("xn")), + _DECL_STREAM_FUNC(readn,2,_SC("xn")), + _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")), + _DECL_STREAM_FUNC(writen,3,_SC("xnn")), + _DECL_STREAM_FUNC(seek,-2,_SC("xnn")), + _DECL_STREAM_FUNC(tell,1,_SC("x")), + _DECL_STREAM_FUNC(len,1,_SC("x")), + _DECL_STREAM_FUNC(eos,1,_SC("x")), + _DECL_STREAM_FUNC(flush,1,_SC("x")), + _DECL_STREAM_FUNC(_cloned,0,NULL), + {0,0} +}; + +void init_streamclass(HSQUIRRELVM v) +{ + sq_pushregistrytable(v); + sq_pushstring(v,_SC("std_stream"),-1); + if(SQ_FAILED(sq_get(v,-2))) { + sq_pushstring(v,_SC("std_stream"),-1); + sq_newclass(v,SQFalse); + sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG); + SQInteger i = 0; + while(_stream_methods[i].name != 0) { + SQRegFunction &f = _stream_methods[i]; + sq_pushstring(v,f.name,-1); + sq_newclosure(v,f.f,0); + sq_setparamscheck(v,f.nparamscheck,f.typemask); + sq_newslot(v,-3,SQFalse); + i++; + } + sq_newslot(v,-3,SQFalse); + sq_pushroottable(v); + sq_pushstring(v,_SC("stream"),-1); + sq_pushstring(v,_SC("std_stream"),-1); + sq_get(v,-4); + sq_newslot(v,-3,SQFalse); + sq_pop(v,1); + } + else { + sq_pop(v,1); //result + } + sq_pop(v,1); +} + +SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals) +{ + if(sq_gettype(v,-1) != OT_TABLE) + return sq_throwerror(v,_SC("table expected")); + SQInteger top = sq_gettop(v); + //create delegate + init_streamclass(v); + sq_pushregistrytable(v); + sq_pushstring(v,reg_name,-1); + sq_pushstring(v,_SC("std_stream"),-1); + if(SQ_SUCCEEDED(sq_get(v,-3))) { + sq_newclass(v,SQTrue); + sq_settypetag(v,-1,typetag); + SQInteger i = 0; + while(methods[i].name != 0) { + SQRegFunction &f = methods[i]; + sq_pushstring(v,f.name,-1); + sq_newclosure(v,f.f,0); + sq_setparamscheck(v,f.nparamscheck,f.typemask); + sq_setnativeclosurename(v,-1,f.name); + sq_newslot(v,-3,SQFalse); + i++; + } + sq_newslot(v,-3,SQFalse); + sq_pop(v,1); + + i = 0; + while(globals[i].name!=0) + { + SQRegFunction &f = globals[i]; + sq_pushstring(v,f.name,-1); + sq_newclosure(v,f.f,0); + sq_setparamscheck(v,f.nparamscheck,f.typemask); + sq_setnativeclosurename(v,-1,f.name); + sq_newslot(v,-3,SQFalse); + i++; + } + //register the class in the target table + sq_pushstring(v,name,-1); + sq_pushregistrytable(v); + sq_pushstring(v,reg_name,-1); + sq_get(v,-2); + sq_remove(v,-2); + sq_newslot(v,-3,SQFalse); + + sq_settop(v,top); + return SQ_OK; + } + sq_settop(v,top); + return SQ_ERROR; +} diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdstream.h b/squirrel_3_0_1_stable/sqstdlib/sqstdstream.h index 1595251e7..4dcc00054 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdstream.h +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdstream.h @@ -1,18 +1,18 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTD_STREAM_H_ -#define _SQSTD_STREAM_H_ - -SQInteger _stream_readblob(HSQUIRRELVM v); -SQInteger _stream_readline(HSQUIRRELVM v); -SQInteger _stream_readn(HSQUIRRELVM v); -SQInteger _stream_writeblob(HSQUIRRELVM v); -SQInteger _stream_writen(HSQUIRRELVM v); -SQInteger _stream_seek(HSQUIRRELVM v); -SQInteger _stream_tell(HSQUIRRELVM v); -SQInteger _stream_len(HSQUIRRELVM v); -SQInteger _stream_eos(HSQUIRRELVM v); -SQInteger _stream_flush(HSQUIRRELVM v); - -#define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck} -SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals); -#endif /*_SQSTD_STREAM_H_*/ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_STREAM_H_ +#define _SQSTD_STREAM_H_ + +SQInteger _stream_readblob(HSQUIRRELVM v); +SQInteger _stream_readline(HSQUIRRELVM v); +SQInteger _stream_readn(HSQUIRRELVM v); +SQInteger _stream_writeblob(HSQUIRRELVM v); +SQInteger _stream_writen(HSQUIRRELVM v); +SQInteger _stream_seek(HSQUIRRELVM v); +SQInteger _stream_tell(HSQUIRRELVM v); +SQInteger _stream_len(HSQUIRRELVM v); +SQInteger _stream_eos(HSQUIRRELVM v); +SQInteger _stream_flush(HSQUIRRELVM v); + +#define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck} +SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals); +#endif /*_SQSTD_STREAM_H_*/ diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdstring.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdstring.cpp index aaa37dfde..2a4e2a1fd 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdstring.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdstring.cpp @@ -1,378 +1,378 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include -#include -#include -#include - -#ifdef SQUNICODE -#define scstrchr wcschr -#define scsnprintf wsnprintf -#define scatoi _wtoi -#define scstrtok wcstok -#else -#define scstrchr strchr -#define scsnprintf snprintf -#define scatoi atoi -#define scstrtok strtok -#endif -#define MAX_FORMAT_LEN 20 -#define MAX_WFORMAT_LEN 3 -#define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar)) - -static SQInteger validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src, SQInteger n,SQInteger &width) -{ - SQChar swidth[MAX_WFORMAT_LEN]; - SQInteger wc = 0; - SQInteger start = n; - fmt[0] = '%'; - while (scstrchr(_SC("-+ #0"), src[n])) n++; - while (scisdigit(src[n])) { - swidth[wc] = src[n]; - n++; - wc++; - if(wc>=MAX_WFORMAT_LEN) - return sq_throwerror(v,_SC("width format too long")); - } - swidth[wc] = '\0'; - if(wc > 0) { - width = scatoi(swidth); - } - else - width = 0; - if (src[n] == '.') { - n++; - - wc = 0; - while (scisdigit(src[n])) { - swidth[wc] = src[n]; - n++; - wc++; - if(wc>=MAX_WFORMAT_LEN) - return sq_throwerror(v,_SC("precision format too long")); - } - swidth[wc] = '\0'; - if(wc > 0) { - width += scatoi(swidth); - } - } - if (n-start > MAX_FORMAT_LEN ) - return sq_throwerror(v,_SC("format too long")); - memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar)); - fmt[(n-start)+2] = '\0'; - return n; -} - -SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output) -{ - const SQChar *format; - SQChar *dest; - SQChar fmt[MAX_FORMAT_LEN]; - sq_getstring(v,nformatstringidx,&format); - SQInteger allocated = (sq_getsize(v,nformatstringidx)+2)*sizeof(SQChar); - dest = sq_getscratchpad(v,allocated); - SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0; - while(format[n] != '\0') { - if(format[n] != '%') { - assert(i < allocated); - dest[i++] = format[n]; - n++; - } - else if(format[n+1] == '%') { //handles %% - dest[i++] = '%'; - n += 2; - } - else { - n++; - if( nparam > sq_gettop(v) ) - return sq_throwerror(v,_SC("not enough paramters for the given format string")); - n = validate_format(v,fmt,format,n,w); - if(n < 0) return -1; - SQInteger addlen = 0; - SQInteger valtype = 0; - const SQChar *ts; - SQInteger ti; - SQFloat tf; - switch(format[n]) { - case 's': - if(SQ_FAILED(sq_getstring(v,nparam,&ts))) - return sq_throwerror(v,_SC("string expected for the specified format")); - addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar)); - valtype = 's'; - break; - case 'i': case 'd': case 'o': case 'u': case 'x': case 'X': -#ifdef _SQ64 - { - size_t flen = scstrlen(fmt); - SQInteger fpos = flen - 1; - SQChar f = fmt[fpos]; - SQChar *prec = (SQChar *)_PRINT_INT_PREC; - while(*prec != _SC('\0')) { - fmt[fpos++] = *prec++; - } - fmt[fpos++] = f; - fmt[fpos++] = _SC('\0'); - } -#endif - case 'c': - if(SQ_FAILED(sq_getinteger(v,nparam,&ti))) - return sq_throwerror(v,_SC("integer expected for the specified format")); - addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar)); - valtype = 'i'; - break; - case 'f': case 'g': case 'G': case 'e': case 'E': - if(SQ_FAILED(sq_getfloat(v,nparam,&tf))) - return sq_throwerror(v,_SC("float expected for the specified format")); - addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar)); - valtype = 'f'; - break; - default: - return sq_throwerror(v,_SC("invalid format")); - } - n++; - allocated += addlen + sizeof(SQChar); - dest = sq_getscratchpad(v,allocated); - switch(valtype) { - case 's': i += scsprintf(&dest[i],fmt,ts); break; - case 'i': i += scsprintf(&dest[i],fmt,ti); break; - case 'f': i += scsprintf(&dest[i],fmt,tf); break; - }; - nparam ++; - } - } - *outlen = i; - dest[i] = '\0'; - *output = dest; - return SQ_OK; -} - -static SQInteger _string_format(HSQUIRRELVM v) -{ - SQChar *dest = NULL; - SQInteger length = 0; - if(SQ_FAILED(sqstd_format(v,2,&length,&dest))) - return -1; - sq_pushstring(v,dest,length); - return 1; -} - -static void __strip_l(const SQChar *str,const SQChar **start) -{ - const SQChar *t = str; - while(((*t) != '\0') && scisspace(*t)){ t++; } - *start = t; -} - -static void __strip_r(const SQChar *str,SQInteger len,const SQChar **end) -{ - if(len == 0) { - *end = str; - return; - } - const SQChar *t = &str[len-1]; - while(t != str && scisspace(*t)) { t--; } - *end = t+1; -} - -static SQInteger _string_strip(HSQUIRRELVM v) -{ - const SQChar *str,*start,*end; - sq_getstring(v,2,&str); - SQInteger len = sq_getsize(v,2); - __strip_l(str,&start); - __strip_r(str,len,&end); - sq_pushstring(v,start,end - start); - return 1; -} - -static SQInteger _string_lstrip(HSQUIRRELVM v) -{ - const SQChar *str,*start; - sq_getstring(v,2,&str); - __strip_l(str,&start); - sq_pushstring(v,start,-1); - return 1; -} - -static SQInteger _string_rstrip(HSQUIRRELVM v) -{ - const SQChar *str,*end; - sq_getstring(v,2,&str); - SQInteger len = sq_getsize(v,2); - __strip_r(str,len,&end); - sq_pushstring(v,str,end - str); - return 1; -} - -static SQInteger _string_split(HSQUIRRELVM v) -{ - const SQChar *str,*seps; - SQChar *stemp,*tok; - sq_getstring(v,2,&str); - sq_getstring(v,3,&seps); - if(sq_getsize(v,3) == 0) return sq_throwerror(v,_SC("empty separators string")); - SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar); - stemp = sq_getscratchpad(v,memsize); - memcpy(stemp,str,memsize); - tok = scstrtok(stemp,seps); - sq_newarray(v,0); - while( tok != NULL ) { - sq_pushstring(v,tok,-1); - sq_arrayappend(v,-2); - tok = scstrtok( NULL, seps ); - } - return 1; -} - -#define SETUP_REX(v) \ - SQRex *self = NULL; \ - sq_getinstanceup(v,1,(SQUserPointer *)&self,0); - -static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger size) -{ - SQRex *self = ((SQRex *)p); - sqstd_rex_free(self); - return 1; -} - -static SQInteger _regexp_match(HSQUIRRELVM v) -{ - SETUP_REX(v); - const SQChar *str; - sq_getstring(v,2,&str); - if(sqstd_rex_match(self,str) == SQTrue) - { - sq_pushbool(v,SQTrue); - return 1; - } - sq_pushbool(v,SQFalse); - return 1; -} - -static void _addrexmatch(HSQUIRRELVM v,const SQChar *str,const SQChar *begin,const SQChar *end) -{ - sq_newtable(v); - sq_pushstring(v,_SC("begin"),-1); - sq_pushinteger(v,begin - str); - sq_rawset(v,-3); - sq_pushstring(v,_SC("end"),-1); - sq_pushinteger(v,end - str); - sq_rawset(v,-3); -} - -static SQInteger _regexp_search(HSQUIRRELVM v) -{ - SETUP_REX(v); - const SQChar *str,*begin,*end; - SQInteger start = 0; - sq_getstring(v,2,&str); - if(sq_gettop(v) > 2) sq_getinteger(v,3,&start); - if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) { - _addrexmatch(v,str,begin,end); - return 1; - } - return 0; -} - -static SQInteger _regexp_capture(HSQUIRRELVM v) -{ - SETUP_REX(v); - const SQChar *str,*begin,*end; - SQInteger start = 0; - sq_getstring(v,2,&str); - if(sq_gettop(v) > 2) sq_getinteger(v,3,&start); - if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) { - SQInteger n = sqstd_rex_getsubexpcount(self); - SQRexMatch match; - sq_newarray(v,0); - for(SQInteger i = 0;i < n; i++) { - sqstd_rex_getsubexp(self,i,&match); - if(match.len > 0) - _addrexmatch(v,str,match.begin,match.begin+match.len); - else - _addrexmatch(v,str,str,str); //empty match - sq_arrayappend(v,-2); - } - return 1; - } - return 0; -} - -static SQInteger _regexp_subexpcount(HSQUIRRELVM v) -{ - SETUP_REX(v); - sq_pushinteger(v,sqstd_rex_getsubexpcount(self)); - return 1; -} - -static SQInteger _regexp_constructor(HSQUIRRELVM v) -{ - const SQChar *error,*pattern; - sq_getstring(v,2,&pattern); - SQRex *rex = sqstd_rex_compile(pattern,&error); - if(!rex) return sq_throwerror(v,error); - sq_setinstanceup(v,1,rex); - sq_setreleasehook(v,1,_rexobj_releasehook); - return 0; -} - -static SQInteger _regexp__typeof(HSQUIRRELVM v) -{ - sq_pushstring(v,_SC("regexp"),-1); - return 1; -} - -#define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask} -static SQRegFunction rexobj_funcs[]={ - _DECL_REX_FUNC(constructor,2,_SC(".s")), - _DECL_REX_FUNC(search,-2,_SC("xsn")), - _DECL_REX_FUNC(match,2,_SC("xs")), - _DECL_REX_FUNC(capture,-2,_SC("xsn")), - _DECL_REX_FUNC(subexpcount,1,_SC("x")), - _DECL_REX_FUNC(_typeof,1,_SC("x")), - {0,0} -}; -#undef _DECL_REX_FUNC - -#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask} -static SQRegFunction stringlib_funcs[]={ - _DECL_FUNC(format,-2,_SC(".s")), - _DECL_FUNC(strip,2,_SC(".s")), - _DECL_FUNC(lstrip,2,_SC(".s")), - _DECL_FUNC(rstrip,2,_SC(".s")), - _DECL_FUNC(split,3,_SC(".ss")), - {0,0} -}; -#undef _DECL_FUNC - - -SQInteger sqstd_register_stringlib(HSQUIRRELVM v) -{ - sq_pushstring(v,_SC("regexp"),-1); - sq_newclass(v,SQFalse); - SQInteger i = 0; - while(rexobj_funcs[i].name != 0) { - SQRegFunction &f = rexobj_funcs[i]; - sq_pushstring(v,f.name,-1); - sq_newclosure(v,f.f,0); - sq_setparamscheck(v,f.nparamscheck,f.typemask); - sq_setnativeclosurename(v,-1,f.name); - sq_newslot(v,-3,SQFalse); - i++; - } - sq_newslot(v,-3,SQFalse); - - i = 0; - while(stringlib_funcs[i].name!=0) - { - sq_pushstring(v,stringlib_funcs[i].name,-1); - sq_newclosure(v,stringlib_funcs[i].f,0); - sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask); - sq_setnativeclosurename(v,-1,stringlib_funcs[i].name); - sq_newslot(v,-3,SQFalse); - i++; - } - return 1; -} +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include +#include +#include + +#ifdef SQUNICODE +#define scstrchr wcschr +#define scsnprintf wsnprintf +#define scatoi _wtoi +#define scstrtok wcstok +#else +#define scstrchr strchr +#define scsnprintf snprintf +#define scatoi atoi +#define scstrtok strtok +#endif +#define MAX_FORMAT_LEN 20 +#define MAX_WFORMAT_LEN 3 +#define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar)) + +static SQInteger validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src, SQInteger n,SQInteger &width) +{ + SQChar swidth[MAX_WFORMAT_LEN]; + SQInteger wc = 0; + SQInteger start = n; + fmt[0] = '%'; + while (scstrchr(_SC("-+ #0"), src[n])) n++; + while (scisdigit(src[n])) { + swidth[wc] = src[n]; + n++; + wc++; + if(wc>=MAX_WFORMAT_LEN) + return sq_throwerror(v,_SC("width format too long")); + } + swidth[wc] = '\0'; + if(wc > 0) { + width = scatoi(swidth); + } + else + width = 0; + if (src[n] == '.') { + n++; + + wc = 0; + while (scisdigit(src[n])) { + swidth[wc] = src[n]; + n++; + wc++; + if(wc>=MAX_WFORMAT_LEN) + return sq_throwerror(v,_SC("precision format too long")); + } + swidth[wc] = '\0'; + if(wc > 0) { + width += scatoi(swidth); + } + } + if (n-start > MAX_FORMAT_LEN ) + return sq_throwerror(v,_SC("format too long")); + memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar)); + fmt[(n-start)+2] = '\0'; + return n; +} + +SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output) +{ + const SQChar *format; + SQChar *dest; + SQChar fmt[MAX_FORMAT_LEN]; + sq_getstring(v,nformatstringidx,&format); + SQInteger allocated = (sq_getsize(v,nformatstringidx)+2)*sizeof(SQChar); + dest = sq_getscratchpad(v,allocated); + SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0; + while(format[n] != '\0') { + if(format[n] != '%') { + assert(i < allocated); + dest[i++] = format[n]; + n++; + } + else if(format[n+1] == '%') { //handles %% + dest[i++] = '%'; + n += 2; + } + else { + n++; + if( nparam > sq_gettop(v) ) + return sq_throwerror(v,_SC("not enough paramters for the given format string")); + n = validate_format(v,fmt,format,n,w); + if(n < 0) return -1; + SQInteger addlen = 0; + SQInteger valtype = 0; + const SQChar *ts; + SQInteger ti; + SQFloat tf; + switch(format[n]) { + case 's': + if(SQ_FAILED(sq_getstring(v,nparam,&ts))) + return sq_throwerror(v,_SC("string expected for the specified format")); + addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar)); + valtype = 's'; + break; + case 'i': case 'd': case 'o': case 'u': case 'x': case 'X': +#ifdef _SQ64 + { + size_t flen = scstrlen(fmt); + SQInteger fpos = flen - 1; + SQChar f = fmt[fpos]; + SQChar *prec = (SQChar *)_PRINT_INT_PREC; + while(*prec != _SC('\0')) { + fmt[fpos++] = *prec++; + } + fmt[fpos++] = f; + fmt[fpos++] = _SC('\0'); + } +#endif + case 'c': + if(SQ_FAILED(sq_getinteger(v,nparam,&ti))) + return sq_throwerror(v,_SC("integer expected for the specified format")); + addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar)); + valtype = 'i'; + break; + case 'f': case 'g': case 'G': case 'e': case 'E': + if(SQ_FAILED(sq_getfloat(v,nparam,&tf))) + return sq_throwerror(v,_SC("float expected for the specified format")); + addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar)); + valtype = 'f'; + break; + default: + return sq_throwerror(v,_SC("invalid format")); + } + n++; + allocated += addlen + sizeof(SQChar); + dest = sq_getscratchpad(v,allocated); + switch(valtype) { + case 's': i += scsprintf(&dest[i],fmt,ts); break; + case 'i': i += scsprintf(&dest[i],fmt,ti); break; + case 'f': i += scsprintf(&dest[i],fmt,tf); break; + }; + nparam ++; + } + } + *outlen = i; + dest[i] = '\0'; + *output = dest; + return SQ_OK; +} + +static SQInteger _string_format(HSQUIRRELVM v) +{ + SQChar *dest = NULL; + SQInteger length = 0; + if(SQ_FAILED(sqstd_format(v,2,&length,&dest))) + return -1; + sq_pushstring(v,dest,length); + return 1; +} + +static void __strip_l(const SQChar *str,const SQChar **start) +{ + const SQChar *t = str; + while(((*t) != '\0') && scisspace(*t)){ t++; } + *start = t; +} + +static void __strip_r(const SQChar *str,SQInteger len,const SQChar **end) +{ + if(len == 0) { + *end = str; + return; + } + const SQChar *t = &str[len-1]; + while(t != str && scisspace(*t)) { t--; } + *end = t+1; +} + +static SQInteger _string_strip(HSQUIRRELVM v) +{ + const SQChar *str,*start,*end; + sq_getstring(v,2,&str); + SQInteger len = sq_getsize(v,2); + __strip_l(str,&start); + __strip_r(str,len,&end); + sq_pushstring(v,start,end - start); + return 1; +} + +static SQInteger _string_lstrip(HSQUIRRELVM v) +{ + const SQChar *str,*start; + sq_getstring(v,2,&str); + __strip_l(str,&start); + sq_pushstring(v,start,-1); + return 1; +} + +static SQInteger _string_rstrip(HSQUIRRELVM v) +{ + const SQChar *str,*end; + sq_getstring(v,2,&str); + SQInteger len = sq_getsize(v,2); + __strip_r(str,len,&end); + sq_pushstring(v,str,end - str); + return 1; +} + +static SQInteger _string_split(HSQUIRRELVM v) +{ + const SQChar *str,*seps; + SQChar *stemp,*tok; + sq_getstring(v,2,&str); + sq_getstring(v,3,&seps); + if(sq_getsize(v,3) == 0) return sq_throwerror(v,_SC("empty separators string")); + SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar); + stemp = sq_getscratchpad(v,memsize); + memcpy(stemp,str,memsize); + tok = scstrtok(stemp,seps); + sq_newarray(v,0); + while( tok != NULL ) { + sq_pushstring(v,tok,-1); + sq_arrayappend(v,-2); + tok = scstrtok( NULL, seps ); + } + return 1; +} + +#define SETUP_REX(v) \ + SQRex *self = NULL; \ + sq_getinstanceup(v,1,(SQUserPointer *)&self,0); + +static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger size) +{ + SQRex *self = ((SQRex *)p); + sqstd_rex_free(self); + return 1; +} + +static SQInteger _regexp_match(HSQUIRRELVM v) +{ + SETUP_REX(v); + const SQChar *str; + sq_getstring(v,2,&str); + if(sqstd_rex_match(self,str) == SQTrue) + { + sq_pushbool(v,SQTrue); + return 1; + } + sq_pushbool(v,SQFalse); + return 1; +} + +static void _addrexmatch(HSQUIRRELVM v,const SQChar *str,const SQChar *begin,const SQChar *end) +{ + sq_newtable(v); + sq_pushstring(v,_SC("begin"),-1); + sq_pushinteger(v,begin - str); + sq_rawset(v,-3); + sq_pushstring(v,_SC("end"),-1); + sq_pushinteger(v,end - str); + sq_rawset(v,-3); +} + +static SQInteger _regexp_search(HSQUIRRELVM v) +{ + SETUP_REX(v); + const SQChar *str,*begin,*end; + SQInteger start = 0; + sq_getstring(v,2,&str); + if(sq_gettop(v) > 2) sq_getinteger(v,3,&start); + if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) { + _addrexmatch(v,str,begin,end); + return 1; + } + return 0; +} + +static SQInteger _regexp_capture(HSQUIRRELVM v) +{ + SETUP_REX(v); + const SQChar *str,*begin,*end; + SQInteger start = 0; + sq_getstring(v,2,&str); + if(sq_gettop(v) > 2) sq_getinteger(v,3,&start); + if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) { + SQInteger n = sqstd_rex_getsubexpcount(self); + SQRexMatch match; + sq_newarray(v,0); + for(SQInteger i = 0;i < n; i++) { + sqstd_rex_getsubexp(self,i,&match); + if(match.len > 0) + _addrexmatch(v,str,match.begin,match.begin+match.len); + else + _addrexmatch(v,str,str,str); //empty match + sq_arrayappend(v,-2); + } + return 1; + } + return 0; +} + +static SQInteger _regexp_subexpcount(HSQUIRRELVM v) +{ + SETUP_REX(v); + sq_pushinteger(v,sqstd_rex_getsubexpcount(self)); + return 1; +} + +static SQInteger _regexp_constructor(HSQUIRRELVM v) +{ + const SQChar *error,*pattern; + sq_getstring(v,2,&pattern); + SQRex *rex = sqstd_rex_compile(pattern,&error); + if(!rex) return sq_throwerror(v,error); + sq_setinstanceup(v,1,rex); + sq_setreleasehook(v,1,_rexobj_releasehook); + return 0; +} + +static SQInteger _regexp__typeof(HSQUIRRELVM v) +{ + sq_pushstring(v,_SC("regexp"),-1); + return 1; +} + +#define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask} +static SQRegFunction rexobj_funcs[]={ + _DECL_REX_FUNC(constructor,2,_SC(".s")), + _DECL_REX_FUNC(search,-2,_SC("xsn")), + _DECL_REX_FUNC(match,2,_SC("xs")), + _DECL_REX_FUNC(capture,-2,_SC("xsn")), + _DECL_REX_FUNC(subexpcount,1,_SC("x")), + _DECL_REX_FUNC(_typeof,1,_SC("x")), + {0,0} +}; +#undef _DECL_REX_FUNC + +#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask} +static SQRegFunction stringlib_funcs[]={ + _DECL_FUNC(format,-2,_SC(".s")), + _DECL_FUNC(strip,2,_SC(".s")), + _DECL_FUNC(lstrip,2,_SC(".s")), + _DECL_FUNC(rstrip,2,_SC(".s")), + _DECL_FUNC(split,3,_SC(".ss")), + {0,0} +}; +#undef _DECL_FUNC + + +SQInteger sqstd_register_stringlib(HSQUIRRELVM v) +{ + sq_pushstring(v,_SC("regexp"),-1); + sq_newclass(v,SQFalse); + SQInteger i = 0; + while(rexobj_funcs[i].name != 0) { + SQRegFunction &f = rexobj_funcs[i]; + sq_pushstring(v,f.name,-1); + sq_newclosure(v,f.f,0); + sq_setparamscheck(v,f.nparamscheck,f.typemask); + sq_setnativeclosurename(v,-1,f.name); + sq_newslot(v,-3,SQFalse); + i++; + } + sq_newslot(v,-3,SQFalse); + + i = 0; + while(stringlib_funcs[i].name!=0) + { + sq_pushstring(v,stringlib_funcs[i].name,-1); + sq_newclosure(v,stringlib_funcs[i].f,0); + sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask); + sq_setnativeclosurename(v,-1,stringlib_funcs[i].name); + sq_newslot(v,-3,SQFalse); + i++; + } + return 1; +} diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdsystem.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdsystem.cpp index 40f78d785..309139fec 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdsystem.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdsystem.cpp @@ -1,147 +1,147 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include -#include - -#ifdef SQUNICODE -#include -#define scgetenv _wgetenv -#define scsystem _wsystem -#define scasctime _wasctime -#define scremove _wremove -#define screname _wrename -#else -#define scgetenv getenv -#define scsystem system -#define scasctime asctime -#define scremove remove -#define screname rename -#endif - -static SQInteger _system_getenv(HSQUIRRELVM v) -{ - const SQChar *s; - if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){ - sq_pushstring(v,scgetenv(s),-1); - return 1; - } - return 0; -} - - -static SQInteger _system_system(HSQUIRRELVM v) -{ - const SQChar *s; - if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){ - sq_pushinteger(v,scsystem(s)); - return 1; - } - return sq_throwerror(v,_SC("wrong param")); -} - - -static SQInteger _system_clock(HSQUIRRELVM v) -{ - sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC); - return 1; -} - -static SQInteger _system_time(HSQUIRRELVM v) -{ - time_t t; - time(&t); - sq_pushinteger(v,*((SQInteger *)&t)); - return 1; -} - -static SQInteger _system_remove(HSQUIRRELVM v) -{ - const SQChar *s; - sq_getstring(v,2,&s); - if(scremove(s)==-1) - return sq_throwerror(v,_SC("remove() failed")); - return 0; -} - -static SQInteger _system_rename(HSQUIRRELVM v) -{ - const SQChar *oldn,*newn; - sq_getstring(v,2,&oldn); - sq_getstring(v,3,&newn); - if(screname(oldn,newn)==-1) - return sq_throwerror(v,_SC("rename() failed")); - return 0; -} - -static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val) -{ - sq_pushstring(v,name,-1); - sq_pushinteger(v,val); - sq_rawset(v,-3); -} - -static SQInteger _system_date(HSQUIRRELVM v) -{ - time_t t; - SQInteger it; - SQInteger format = 'l'; - if(sq_gettop(v) > 1) { - sq_getinteger(v,2,&it); - t = it; - if(sq_gettop(v) > 2) { - sq_getinteger(v,3,(SQInteger*)&format); - } - } - else { - time(&t); - } - tm *date; - if(format == 'u') - date = gmtime(&t); - else - date = localtime(&t); - if(!date) - return sq_throwerror(v,_SC("crt api failure")); - sq_newtable(v); - _set_integer_slot(v, _SC("sec"), date->tm_sec); - _set_integer_slot(v, _SC("min"), date->tm_min); - _set_integer_slot(v, _SC("hour"), date->tm_hour); - _set_integer_slot(v, _SC("day"), date->tm_mday); - _set_integer_slot(v, _SC("month"), date->tm_mon); - _set_integer_slot(v, _SC("year"), date->tm_year+1900); - _set_integer_slot(v, _SC("wday"), date->tm_wday); - _set_integer_slot(v, _SC("yday"), date->tm_yday); - return 1; -} - - - -#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask} -static SQRegFunction systemlib_funcs[]={ - _DECL_FUNC(getenv,2,_SC(".s")), - _DECL_FUNC(system,2,_SC(".s")), - _DECL_FUNC(clock,0,NULL), - _DECL_FUNC(time,1,NULL), - _DECL_FUNC(date,-1,_SC(".nn")), - _DECL_FUNC(remove,2,_SC(".s")), - _DECL_FUNC(rename,3,_SC(".ss")), - {0,0} -}; -#undef _DECL_FUNC - -SQInteger sqstd_register_systemlib(HSQUIRRELVM v) -{ - SQInteger i=0; - while(systemlib_funcs[i].name!=0) - { - sq_pushstring(v,systemlib_funcs[i].name,-1); - sq_newclosure(v,systemlib_funcs[i].f,0); - sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask); - sq_setnativeclosurename(v,-1,systemlib_funcs[i].name); - sq_newslot(v,-3,SQFalse); - i++; - } - return 1; -} +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include + +#ifdef SQUNICODE +#include +#define scgetenv _wgetenv +#define scsystem _wsystem +#define scasctime _wasctime +#define scremove _wremove +#define screname _wrename +#else +#define scgetenv getenv +#define scsystem system +#define scasctime asctime +#define scremove remove +#define screname rename +#endif + +static SQInteger _system_getenv(HSQUIRRELVM v) +{ + const SQChar *s; + if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){ + sq_pushstring(v,scgetenv(s),-1); + return 1; + } + return 0; +} + + +static SQInteger _system_system(HSQUIRRELVM v) +{ + const SQChar *s; + if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){ + sq_pushinteger(v,scsystem(s)); + return 1; + } + return sq_throwerror(v,_SC("wrong param")); +} + + +static SQInteger _system_clock(HSQUIRRELVM v) +{ + sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC); + return 1; +} + +static SQInteger _system_time(HSQUIRRELVM v) +{ + time_t t; + time(&t); + sq_pushinteger(v,*((SQInteger *)&t)); + return 1; +} + +static SQInteger _system_remove(HSQUIRRELVM v) +{ + const SQChar *s; + sq_getstring(v,2,&s); + if(scremove(s)==-1) + return sq_throwerror(v,_SC("remove() failed")); + return 0; +} + +static SQInteger _system_rename(HSQUIRRELVM v) +{ + const SQChar *oldn,*newn; + sq_getstring(v,2,&oldn); + sq_getstring(v,3,&newn); + if(screname(oldn,newn)==-1) + return sq_throwerror(v,_SC("rename() failed")); + return 0; +} + +static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val) +{ + sq_pushstring(v,name,-1); + sq_pushinteger(v,val); + sq_rawset(v,-3); +} + +static SQInteger _system_date(HSQUIRRELVM v) +{ + time_t t; + SQInteger it; + SQInteger format = 'l'; + if(sq_gettop(v) > 1) { + sq_getinteger(v,2,&it); + t = it; + if(sq_gettop(v) > 2) { + sq_getinteger(v,3,(SQInteger*)&format); + } + } + else { + time(&t); + } + tm *date; + if(format == 'u') + date = gmtime(&t); + else + date = localtime(&t); + if(!date) + return sq_throwerror(v,_SC("crt api failure")); + sq_newtable(v); + _set_integer_slot(v, _SC("sec"), date->tm_sec); + _set_integer_slot(v, _SC("min"), date->tm_min); + _set_integer_slot(v, _SC("hour"), date->tm_hour); + _set_integer_slot(v, _SC("day"), date->tm_mday); + _set_integer_slot(v, _SC("month"), date->tm_mon); + _set_integer_slot(v, _SC("year"), date->tm_year+1900); + _set_integer_slot(v, _SC("wday"), date->tm_wday); + _set_integer_slot(v, _SC("yday"), date->tm_yday); + return 1; +} + + + +#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask} +static SQRegFunction systemlib_funcs[]={ + _DECL_FUNC(getenv,2,_SC(".s")), + _DECL_FUNC(system,2,_SC(".s")), + _DECL_FUNC(clock,0,NULL), + _DECL_FUNC(time,1,NULL), + _DECL_FUNC(date,-1,_SC(".nn")), + _DECL_FUNC(remove,2,_SC(".s")), + _DECL_FUNC(rename,3,_SC(".ss")), + {0,0} +}; +#undef _DECL_FUNC + +SQInteger sqstd_register_systemlib(HSQUIRRELVM v) +{ + SQInteger i=0; + while(systemlib_funcs[i].name!=0) + { + sq_pushstring(v,systemlib_funcs[i].name,-1); + sq_newclosure(v,systemlib_funcs[i].f,0); + sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask); + sq_setnativeclosurename(v,-1,systemlib_funcs[i].name); + sq_newslot(v,-3,SQFalse); + i++; + } + return 1; +} diff --git a/squirrel_3_0_1_stable/squirrel/sqapi.cpp b/squirrel_3_0_1_stable/squirrel/sqapi.cpp index 05338ce23..4c9b4c706 100644 --- a/squirrel_3_0_1_stable/squirrel/sqapi.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqapi.cpp @@ -1,1456 +1,1456 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#include "sqvm.h" -#include "sqstring.h" -#include "sqtable.h" -#include "sqarray.h" -#include "sqfuncproto.h" -#include "sqclosure.h" -#include "squserdata.h" -#include "sqcompiler.h" -#include "sqfuncstate.h" -#include "sqclass.h" - -bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr **o) -{ - *o = &stack_get(v,idx); - if(type(**o) != type){ - SQObjectPtr oval = v->PrintObjVal(**o); - v->Raise_Error(_SC("wrong argument type, expected '%s' got '%.50s'"),IdType2Name(type),_stringval(oval)); - return false; - } - return true; -} - -#define _GETSAFE_OBJ(v,idx,type,o) { if(!sq_aux_gettypedarg(v,idx,type,&o)) return SQ_ERROR; } - -#define sq_aux_paramscheck(v,count) \ -{ \ - if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\ -} - - -SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type) -{ - scsprintf(_ss(v)->GetScratchPad(100), _SC("unexpected type %s"), IdType2Name(type)); - return sq_throwerror(v, _ss(v)->GetScratchPad(-1)); -} - -HSQUIRRELVM sq_open(SQInteger initialstacksize) -{ - SQSharedState *ss; - SQVM *v; - sq_new(ss, SQSharedState); - ss->Init(); - v = (SQVM *)SQ_MALLOC(sizeof(SQVM)); - new (v) SQVM(ss); - ss->_root_vm = v; - if(v->Init(NULL, initialstacksize)) { - return v; - } else { - sq_delete(v, SQVM); - return NULL; - } - return v; -} - -HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize) -{ - SQSharedState *ss; - SQVM *v; - ss=_ss(friendvm); - - v= (SQVM *)SQ_MALLOC(sizeof(SQVM)); - new (v) SQVM(ss); - - if(v->Init(friendvm, initialstacksize)) { - friendvm->Push(v); - return v; - } else { - sq_delete(v, SQVM); - return NULL; - } -} - -SQInteger sq_getvmstate(HSQUIRRELVM v) -{ - if(v->_suspended) - return SQ_VMSTATE_SUSPENDED; - else { - if(v->_callsstacksize != 0) return SQ_VMSTATE_RUNNING; - else return SQ_VMSTATE_IDLE; - } -} - -void sq_seterrorhandler(HSQUIRRELVM v) -{ - SQObject o = stack_get(v, -1); - if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) { - v->_errorhandler = o; - v->Pop(); - } -} - -void sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook) -{ - v->_debughook_native = hook; - v->_debughook_closure.Null(); - v->_debughook = hook?true:false; -} - -void sq_setdebughook(HSQUIRRELVM v) -{ - SQObject o = stack_get(v,-1); - if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) { - v->_debughook_closure = o; - v->_debughook_native = NULL; - v->_debughook = !sq_isnull(o); - v->Pop(); - } -} - -void sq_close(HSQUIRRELVM v) -{ - SQSharedState *ss = _ss(v); - _thread(ss->_root_vm)->Finalize(); - sq_delete(ss, SQSharedState); -} - -SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror) -{ - SQObjectPtr o; -#ifndef NO_COMPILER - if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) { - v->Push(SQClosure::Create(_ss(v), _funcproto(o))); - return SQ_OK; - } - return SQ_ERROR; -#else - return sq_throwerror(v,_SC("this is a no compiler build")); -#endif -} - -void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable) -{ - _ss(v)->_debuginfo = enable?true:false; -} - -void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable) -{ - _ss(v)->_notifyallexceptions = enable?true:false; -} - -void sq_addref(HSQUIRRELVM v,HSQOBJECT *po) -{ - if(!ISREFCOUNTED(type(*po))) return; -#ifdef NO_GARBAGE_COLLECTOR - __AddRef(po->_type,po->_unVal); -#else - _ss(v)->_refs_table.AddRef(*po); -#endif -} - -SQUnsignedInteger sq_getrefcount(HSQUIRRELVM v,HSQOBJECT *po) -{ - if(!ISREFCOUNTED(type(*po))) return 0; -#ifdef NO_GARBAGE_COLLECTOR - return po->_unVal.pRefCounted->_uiRef; -#else - return _ss(v)->_refs_table.GetRefCount(*po); -#endif -} - -SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po) -{ - if(!ISREFCOUNTED(type(*po))) return SQTrue; -#ifdef NO_GARBAGE_COLLECTOR - bool ret = (po->_unVal.pRefCounted->_uiRef <= 1) ? SQTrue : SQFalse; - __Release(po->_type,po->_unVal); - return ret; //the ret val doesn't work(and cannot be fixed) -#else - return _ss(v)->_refs_table.Release(*po); -#endif -} - -const SQChar *sq_objtostring(const HSQOBJECT *o) -{ - if(sq_type(*o) == OT_STRING) { - return _stringval(*o); - } - return NULL; -} - -SQInteger sq_objtointeger(const HSQOBJECT *o) -{ - if(sq_isnumeric(*o)) { - return tointeger(*o); - } - return 0; -} - -SQFloat sq_objtofloat(const HSQOBJECT *o) -{ - if(sq_isnumeric(*o)) { - return tofloat(*o); - } - return 0; -} - -SQBool sq_objtobool(const HSQOBJECT *o) -{ - if(sq_isbool(*o)) { - return _integer(*o); - } - return SQFalse; -} - -SQUserPointer sq_objtouserpointer(const HSQOBJECT *o) -{ - if(sq_isuserpointer(*o)) { - return _userpointer(*o); - } - return 0; -} - -void sq_pushnull(HSQUIRRELVM v) -{ - v->PushNull(); -} - -void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len) -{ - if(s) - v->Push(SQObjectPtr(SQString::Create(_ss(v), s, len))); - else v->PushNull(); -} - -void sq_pushinteger(HSQUIRRELVM v,SQInteger n) -{ - v->Push(n); -} - -void sq_pushbool(HSQUIRRELVM v,SQBool b) -{ - v->Push(b?true:false); -} - -void sq_pushfloat(HSQUIRRELVM v,SQFloat n) -{ - v->Push(n); -} - -void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p) -{ - v->Push(p); -} - -SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size) -{ - SQUserData *ud = SQUserData::Create(_ss(v), size); - v->Push(ud); - return (SQUserPointer)sq_aligning(ud + 1); -} - -void sq_newtable(HSQUIRRELVM v) -{ - v->Push(SQTable::Create(_ss(v), 0)); -} - -void sq_newtableex(HSQUIRRELVM v,SQInteger initialcapacity) -{ - v->Push(SQTable::Create(_ss(v), initialcapacity)); -} - -void sq_newarray(HSQUIRRELVM v,SQInteger size) -{ - v->Push(SQArray::Create(_ss(v), size)); -} - -SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase) -{ - SQClass *baseclass = NULL; - if(hasbase) { - SQObjectPtr &base = stack_get(v,-1); - if(type(base) != OT_CLASS) - return sq_throwerror(v,_SC("invalid base type")); - baseclass = _class(base); - } - SQClass *newclass = SQClass::Create(_ss(v), baseclass); - if(baseclass) v->Pop(); - v->Push(newclass); - return SQ_OK; -} - -SQBool sq_instanceof(HSQUIRRELVM v) -{ - SQObjectPtr &inst = stack_get(v,-1); - SQObjectPtr &cl = stack_get(v,-2); - if(type(inst) != OT_INSTANCE || type(cl) != OT_CLASS) - return sq_throwerror(v,_SC("invalid param type")); - return _instance(inst)->InstanceOf(_class(cl))?SQTrue:SQFalse; -} - -SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx) -{ - sq_aux_paramscheck(v,2); - SQObjectPtr *arr; - _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); - _array(*arr)->Append(v->GetUp(-1)); - v->Pop(); - return SQ_OK; -} - -SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval) -{ - sq_aux_paramscheck(v, 1); - SQObjectPtr *arr; - _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); - if(_array(*arr)->Size() > 0) { - if(pushval != 0){ v->Push(_array(*arr)->Top()); } - _array(*arr)->Pop(); - return SQ_OK; - } - return sq_throwerror(v, _SC("empty array")); -} - -SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize) -{ - sq_aux_paramscheck(v,1); - SQObjectPtr *arr; - _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); - if(newsize >= 0) { - _array(*arr)->Resize(newsize); - return SQ_OK; - } - return sq_throwerror(v,_SC("negative size")); -} - - -SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx) -{ - sq_aux_paramscheck(v, 1); - SQObjectPtr *o; - _GETSAFE_OBJ(v, idx, OT_ARRAY,o); - SQArray *arr = _array(*o); - if(arr->Size() > 0) { - SQObjectPtr t; - SQInteger size = arr->Size(); - SQInteger n = size >> 1; size -= 1; - for(SQInteger i = 0; i < n; i++) { - t = arr->_values[i]; - arr->_values[i] = arr->_values[size-i]; - arr->_values[size-i] = t; - } - return SQ_OK; - } - return SQ_OK; -} - -SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx) -{ - sq_aux_paramscheck(v, 1); - SQObjectPtr *arr; - _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); - return _array(*arr)->Remove(itemidx) ? SQ_OK : sq_throwerror(v,_SC("index out of range")); -} - -SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos) -{ - sq_aux_paramscheck(v, 1); - SQObjectPtr *arr; - _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); - SQRESULT ret = _array(*arr)->Insert(destpos, v->GetUp(-1)) ? SQ_OK : sq_throwerror(v,_SC("index out of range")); - v->Pop(); - return ret; -} - -void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars) -{ - SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func,nfreevars); - nc->_nparamscheck = 0; - for(SQUnsignedInteger i = 0; i < nfreevars; i++) { - nc->_outervalues[i] = v->Top(); - v->Pop(); - } - v->Push(SQObjectPtr(nc)); -} - -SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars) -{ - SQObject o = stack_get(v, idx); - if(type(o) == OT_CLOSURE) { - SQClosure *c = _closure(o); - SQFunctionProto *proto = c->_function; - *nparams = (SQUnsignedInteger)proto->_nparameters; - *nfreevars = (SQUnsignedInteger)proto->_noutervalues; - return SQ_OK; - } - else if(type(o) == OT_NATIVECLOSURE) - { - SQNativeClosure *c = _nativeclosure(o); - *nparams = (SQUnsignedInteger)c->_nparamscheck; - *nfreevars = c->_noutervalues; - return SQ_OK; - } - return sq_throwerror(v,_SC("the object is not a closure")); -} - -SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name) -{ - SQObject o = stack_get(v, idx); - if(sq_isnativeclosure(o)) { - SQNativeClosure *nc = _nativeclosure(o); - nc->_name = SQString::Create(_ss(v),name); - return SQ_OK; - } - return sq_throwerror(v,_SC("the object is not a nativeclosure")); -} - -SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask) -{ - SQObject o = stack_get(v, -1); - if(!sq_isnativeclosure(o)) - return sq_throwerror(v, _SC("native closure expected")); - SQNativeClosure *nc = _nativeclosure(o); - nc->_nparamscheck = nparamscheck; - if(typemask) { - SQIntVec res; - if(!CompileTypemask(res, typemask)) - return sq_throwerror(v, _SC("invalid typemask")); - nc->_typecheck.copy(res); - } - else { - nc->_typecheck.resize(0); - } - if(nparamscheck == SQ_MATCHTYPEMASKSTRING) { - nc->_nparamscheck = nc->_typecheck.size(); - } - return SQ_OK; -} - -SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &o = stack_get(v,idx); - if(!sq_isnativeclosure(o) && - !sq_isclosure(o)) - return sq_throwerror(v,_SC("the target is not a closure")); - SQObjectPtr &env = stack_get(v,-1); - if(!sq_istable(env) && - !sq_isclass(env) && - !sq_isinstance(env)) - return sq_throwerror(v,_SC("invalid environment")); - SQWeakRef *w = _refcounted(env)->GetWeakRef(type(env)); - SQObjectPtr ret; - if(sq_isclosure(o)) { - SQClosure *c = _closure(o)->Clone(); - __ObjRelease(c->_env); - c->_env = w; - __ObjAddRef(c->_env); - if(_closure(o)->_base) { - c->_base = _closure(o)->_base; - __ObjAddRef(c->_base); - } - ret = c; - } - else { //then must be a native closure - SQNativeClosure *c = _nativeclosure(o)->Clone(); - __ObjRelease(c->_env); - c->_env = w; - __ObjAddRef(c->_env); - ret = c; - } - v->Pop(); - v->Push(ret); - return SQ_OK; -} - -SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx) -{ - SQObject &o=stack_get(v,idx); - switch(type(o)) { - case OT_TABLE: _table(o)->Clear(); break; - case OT_ARRAY: _array(o)->Resize(0); break; - default: - return sq_throwerror(v, _SC("clear only works on table and array")); - break; - - } - return SQ_OK; -} - -void sq_pushroottable(HSQUIRRELVM v) -{ - v->Push(v->_roottable); -} - -void sq_pushregistrytable(HSQUIRRELVM v) -{ - v->Push(_ss(v)->_registry); -} - -void sq_pushconsttable(HSQUIRRELVM v) -{ - v->Push(_ss(v)->_consts); -} - -SQRESULT sq_setroottable(HSQUIRRELVM v) -{ - SQObject o = stack_get(v, -1); - if(sq_istable(o) || sq_isnull(o)) { - v->_roottable = o; - v->Pop(); - return SQ_OK; - } - return sq_throwerror(v, _SC("ivalid type")); -} - -SQRESULT sq_setconsttable(HSQUIRRELVM v) -{ - SQObject o = stack_get(v, -1); - if(sq_istable(o)) { - _ss(v)->_consts = o; - v->Pop(); - return SQ_OK; - } - return sq_throwerror(v, _SC("ivalid type, expected table")); -} - -void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p) -{ - v->_foreignptr = p; -} - -SQUserPointer sq_getforeignptr(HSQUIRRELVM v) -{ - return v->_foreignptr; -} - -void sq_push(HSQUIRRELVM v,SQInteger idx) -{ - v->Push(stack_get(v, idx)); -} - -SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx) -{ - return type(stack_get(v, idx)); -} - - -SQRESULT sq_tostring(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &o = stack_get(v, idx); - SQObjectPtr res; - if(!v->ToString(o,res)) { - return SQ_ERROR; - } - v->Push(res); - return SQ_OK; -} - -void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b) -{ - SQObjectPtr &o = stack_get(v, idx); - *b = SQVM::IsFalse(o)?SQFalse:SQTrue; -} - -SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i) -{ - SQObjectPtr &o = stack_get(v, idx); - if(sq_isnumeric(o)) { - *i = tointeger(o); - return SQ_OK; - } - return SQ_ERROR; -} - -SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f) -{ - SQObjectPtr &o = stack_get(v, idx); - if(sq_isnumeric(o)) { - *f = tofloat(o); - return SQ_OK; - } - return SQ_ERROR; -} - -SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b) -{ - SQObjectPtr &o = stack_get(v, idx); - if(sq_isbool(o)) { - *b = _integer(o); - return SQ_OK; - } - return SQ_ERROR; -} - -SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_STRING,o); - *c = _stringval(*o); - return SQ_OK; -} - -SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_THREAD,o); - *thread = _thread(*o); - return SQ_OK; -} - -SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &o = stack_get(v,idx); - v->PushNull(); - if(!v->Clone(o, stack_get(v, -1))){ - v->Pop(); - return SQ_ERROR; - } - return SQ_OK; -} - -SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx) -{ - SQObjectPtr &o = stack_get(v, idx); - SQObjectType type = type(o); - switch(type) { - case OT_STRING: return _string(o)->_len; - case OT_TABLE: return _table(o)->CountUsed(); - case OT_ARRAY: return _array(o)->Size(); - case OT_USERDATA: return _userdata(o)->_size; - case OT_INSTANCE: return _instance(o)->_class->_udsize; - case OT_CLASS: return _class(o)->_udsize; - default: - return sq_aux_invalidtype(v, type); - } -} - -SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_USERDATA,o); - (*p) = _userdataval(*o); - if(typetag) *typetag = _userdata(*o)->_typetag; - return SQ_OK; -} - -SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag) -{ - SQObjectPtr &o = stack_get(v,idx); - switch(type(o)) { - case OT_USERDATA: _userdata(o)->_typetag = typetag; break; - case OT_CLASS: _class(o)->_typetag = typetag; break; - default: return sq_throwerror(v,_SC("invalid object type")); - } - return SQ_OK; -} - -SQRESULT sq_getobjtypetag(const HSQOBJECT *o,SQUserPointer * typetag) -{ - switch(type(*o)) { - case OT_INSTANCE: *typetag = _instance(*o)->_class->_typetag; break; - case OT_USERDATA: *typetag = _userdata(*o)->_typetag; break; - case OT_CLASS: *typetag = _class(*o)->_typetag; break; - default: return SQ_ERROR; - } - return SQ_OK; -} - -SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag) -{ - SQObjectPtr &o = stack_get(v,idx); - if(SQ_FAILED(sq_getobjtypetag(&o,typetag))) - return sq_throwerror(v,_SC("invalid object type")); - return SQ_OK; -} - -SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_USERPOINTER,o); - (*p) = _userpointer(*o); - return SQ_OK; -} - -SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p) -{ - SQObjectPtr &o = stack_get(v,idx); - if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance")); - _instance(o)->_userpointer = p; - return SQ_OK; -} - -SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize) -{ - SQObjectPtr &o = stack_get(v,idx); - if(type(o) != OT_CLASS) return sq_throwerror(v,_SC("the object is not a class")); - if(_class(o)->_locked) return sq_throwerror(v,_SC("the class is locked")); - _class(o)->_udsize = udsize; - return SQ_OK; -} - - -SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag) -{ - SQObjectPtr &o = stack_get(v,idx); - if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance")); - (*p) = _instance(o)->_userpointer; - if(typetag != 0) { - SQClass *cl = _instance(o)->_class; - do{ - if(cl->_typetag == typetag) - return SQ_OK; - cl = cl->_base; - }while(cl != NULL); - return sq_throwerror(v,_SC("invalid type tag")); - } - return SQ_OK; -} - -SQInteger sq_gettop(HSQUIRRELVM v) -{ - return (v->_top) - v->_stackbase; -} - -void sq_settop(HSQUIRRELVM v, SQInteger newtop) -{ - SQInteger top = sq_gettop(v); - if(top > newtop) - sq_pop(v, top - newtop); - else - while(top++ < newtop) sq_pushnull(v); -} - -void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop) -{ - assert(v->_top >= nelemstopop); - v->Pop(nelemstopop); -} - -void sq_poptop(HSQUIRRELVM v) -{ - assert(v->_top >= 1); - v->Pop(); -} - - -void sq_remove(HSQUIRRELVM v, SQInteger idx) -{ - v->Remove(idx); -} - -SQInteger sq_cmp(HSQUIRRELVM v) -{ - SQInteger res; - v->ObjCmp(stack_get(v, -1), stack_get(v, -2),res); - return res; -} - -SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic) -{ - sq_aux_paramscheck(v, 3); - SQObjectPtr &self = stack_get(v, idx); - if(type(self) == OT_TABLE || type(self) == OT_CLASS) { - SQObjectPtr &key = v->GetUp(-2); - if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key")); - v->NewSlot(self, key, v->GetUp(-1),bstatic?true:false); - v->Pop(2); - } - return SQ_OK; -} - -SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval) -{ - sq_aux_paramscheck(v, 2); - SQObjectPtr *self; - _GETSAFE_OBJ(v, idx, OT_TABLE,self); - SQObjectPtr &key = v->GetUp(-1); - if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key")); - SQObjectPtr res; - if(!v->DeleteSlot(*self, key, res)){ - return SQ_ERROR; - } - if(pushval) v->GetUp(-1) = res; - else v->Pop(); - return SQ_OK; -} - -SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &self = stack_get(v, idx); - if(v->Set(self, v->GetUp(-2), v->GetUp(-1),DONT_FALL_BACK)) { - v->Pop(2); - return SQ_OK; - } - return SQ_ERROR; -} - -SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &self = stack_get(v, idx); - if(type(v->GetUp(-2)) == OT_NULL) return sq_throwerror(v, _SC("null key")); - switch(type(self)) { - case OT_TABLE: - _table(self)->NewSlot(v->GetUp(-2), v->GetUp(-1)); - v->Pop(2); - return SQ_OK; - break; - case OT_CLASS: - _class(self)->NewSlot(_ss(v), v->GetUp(-2), v->GetUp(-1),false); - v->Pop(2); - return SQ_OK; - break; - case OT_INSTANCE: - if(_instance(self)->Set(v->GetUp(-2), v->GetUp(-1))) { - v->Pop(2); - return SQ_OK; - } - break; - case OT_ARRAY: - if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) { - v->Pop(2); - return SQ_OK; - } - break; - default: - v->Pop(2); - return sq_throwerror(v, _SC("rawset works only on array/table/class and instance")); - } - v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR; -} - -SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &self = stack_get(v, idx); - SQObjectPtr &mt = v->GetUp(-1); - SQObjectType type = type(self); - switch(type) { - case OT_TABLE: - if(type(mt) == OT_TABLE) { - if(!_table(self)->SetDelegate(_table(mt))) return sq_throwerror(v, _SC("delagate cycle")); v->Pop();} - else if(type(mt)==OT_NULL) { - _table(self)->SetDelegate(NULL); v->Pop(); } - else return sq_aux_invalidtype(v,type); - break; - case OT_USERDATA: - if(type(mt)==OT_TABLE) { - _userdata(self)->SetDelegate(_table(mt)); v->Pop(); } - else if(type(mt)==OT_NULL) { - _userdata(self)->SetDelegate(NULL); v->Pop(); } - else return sq_aux_invalidtype(v, type); - break; - default: - return sq_aux_invalidtype(v, type); - break; - } - return SQ_OK; -} - -SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval) -{ - sq_aux_paramscheck(v, 2); - SQObjectPtr *self; - _GETSAFE_OBJ(v, idx, OT_TABLE,self); - SQObjectPtr &key = v->GetUp(-1); - SQObjectPtr t; - if(_table(*self)->Get(key,t)) { - _table(*self)->Remove(key); - } - if(pushval != 0) - v->GetUp(-1) = t; - else - v->Pop(); - return SQ_OK; -} - -SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &self=stack_get(v,idx); - switch(type(self)){ - case OT_TABLE: - case OT_USERDATA: - if(!_delegable(self)->_delegate){ - v->PushNull(); - break; - } - v->Push(SQObjectPtr(_delegable(self)->_delegate)); - break; - default: return sq_throwerror(v,_SC("wrong type")); break; - } - return SQ_OK; - -} - -SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &self=stack_get(v,idx); - if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,DONT_FALL_BACK)) - return SQ_OK; - v->Pop(); - return SQ_ERROR; -} - -SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &self=stack_get(v,idx); - switch(type(self)) { - case OT_TABLE: - if(_table(self)->Get(v->GetUp(-1),v->GetUp(-1))) - return SQ_OK; - break; - case OT_CLASS: - if(_class(self)->Get(v->GetUp(-1),v->GetUp(-1))) - return SQ_OK; - break; - case OT_INSTANCE: - if(_instance(self)->Get(v->GetUp(-1),v->GetUp(-1))) - return SQ_OK; - break; - case OT_ARRAY:{ - SQObjectPtr& key = v->GetUp(-1); - if(sq_isnumeric(key)){ - if(_array(self)->Get(tointeger(key),v->GetUp(-1))) { - return SQ_OK; - } - } - else { - v->Pop(); - return sq_throwerror(v,_SC("invalid index type for an array")); - } - } - break; - default: - v->Pop(); - return sq_throwerror(v,_SC("rawget works only on array/table/instance and class")); - } - v->Pop(); - return sq_throwerror(v,_SC("the index doesn't exist")); -} - -SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po) -{ - *po=stack_get(v,idx); - return SQ_OK; -} - -const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx) -{ - SQUnsignedInteger cstksize=v->_callsstacksize; - SQUnsignedInteger lvl=(cstksize-level)-1; - SQInteger stackbase=v->_stackbase; - if(lvl_callsstack[(cstksize-i)-1]; - stackbase-=ci._prevstkbase; - } - SQVM::CallInfo &ci=v->_callsstack[lvl]; - if(type(ci._closure)!=OT_CLOSURE) - return NULL; - SQClosure *c=_closure(ci._closure); - SQFunctionProto *func=c->_function; - if(func->_noutervalues > (SQInteger)idx) { - v->Push(*_outer(c->_outervalues[idx])->_valptr); - return _stringval(func->_outervalues[idx]._name); - } - idx -= func->_noutervalues; - return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions)-1); - } - return NULL; -} - -void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj) -{ - v->Push(SQObjectPtr(obj)); -} - -void sq_resetobject(HSQOBJECT *po) -{ - po->_unVal.pUserPointer=NULL;po->_type=OT_NULL; -} - -SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err) -{ - v->_lasterror=SQString::Create(_ss(v),err); - return SQ_ERROR; -} - -SQRESULT sq_throwobject(HSQUIRRELVM v) -{ - v->_lasterror = v->GetUp(-1); - v->Pop(); - return SQ_ERROR; -} - - -void sq_reseterror(HSQUIRRELVM v) -{ - v->_lasterror.Null(); -} - -void sq_getlasterror(HSQUIRRELVM v) -{ - v->Push(v->_lasterror); -} - -SQRESULT sq_reservestack(HSQUIRRELVM v,SQInteger nsize) -{ - if (((SQUnsignedInteger)v->_top + nsize) > v->_stack.size()) { - if(v->_nmetamethodscall) { - return sq_throwerror(v,_SC("cannot resize stack while in a metamethod")); - } - v->_stack.resize(v->_stack.size() + ((v->_top + nsize) - v->_stack.size())); - } - return SQ_OK; -} - -SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror) -{ - if(type(v->GetUp(-1))==OT_GENERATOR){ - v->PushNull(); //retval - if(!v->Execute(v->GetUp(-2),0,v->_top,v->GetUp(-1),raiseerror,SQVM::ET_RESUME_GENERATOR)) - {v->Raise_Error(v->_lasterror); return SQ_ERROR;} - if(!retval) - v->Pop(); - return SQ_OK; - } - return sq_throwerror(v,_SC("only generators can be resumed")); -} - -SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror) -{ - SQObjectPtr res; - if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){ - - if(!v->_suspended) { - v->Pop(params);//pop closure and args - } - if(retval){ - v->Push(res); return SQ_OK; - } - return SQ_OK; - } - else { - v->Pop(params); - return SQ_ERROR; - } - if(!v->_suspended) - v->Pop(params); - return sq_throwerror(v,_SC("call failed")); -} - -SQRESULT sq_suspendvm(HSQUIRRELVM v) -{ - return v->Suspend(); -} - -SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror,SQBool throwerror) -{ - SQObjectPtr ret; - if(!v->_suspended) - return sq_throwerror(v,_SC("cannot resume a vm that is not running any code")); - SQInteger target = v->_suspended_target; - if(wakeupret) { - if(target != -1) { - v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval - } - v->Pop(); - } else if(target != -1) { v->GetAt(v->_stackbase+v->_suspended_target).Null(); } - SQObjectPtr dummy; - if(!v->Execute(dummy,-1,-1,ret,raiseerror,throwerror?SQVM::ET_RESUME_THROW_VM : SQVM::ET_RESUME_VM)) { - return SQ_ERROR; - } - if(retval) - v->Push(ret); - return SQ_OK; -} - -void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook) -{ - if(sq_gettop(v) >= 1){ - SQObjectPtr &ud=stack_get(v,idx); - switch( type(ud) ) { - case OT_USERDATA: _userdata(ud)->_hook = hook; break; - case OT_INSTANCE: _instance(ud)->_hook = hook; break; - case OT_CLASS: _class(ud)->_hook = hook; break; - default: break; //shutup compiler - } - } -} - -void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f) -{ - _ss(v)->_compilererrorhandler = f; -} - -SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, -1, OT_CLOSURE,o); - unsigned short tag = SQ_BYTECODE_STREAM_TAG; - if(w(up,&tag,2) != 2) - return sq_throwerror(v,_SC("io error")); - if(!_closure(*o)->Save(v,up,w)) - return SQ_ERROR; - return SQ_OK; -} - -SQRESULT sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up) -{ - SQObjectPtr closure; - - unsigned short tag; - if(r(up,&tag,2) != 2) - return sq_throwerror(v,_SC("io error")); - if(tag != SQ_BYTECODE_STREAM_TAG) - return sq_throwerror(v,_SC("invalid stream")); - if(!SQClosure::Load(v,up,r,closure)) - return SQ_ERROR; - v->Push(closure); - return SQ_OK; -} - -SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize) -{ - return _ss(v)->GetScratchPad(minsize); -} - -SQRESULT sq_resurrectunreachable(HSQUIRRELVM v) -{ -#ifndef NO_GARBAGE_COLLECTOR - _ss(v)->ResurrectUnreachable(v); - return SQ_OK; -#else - return sq_throwerror(v,_SC("sq_resurrectunreachable requires a garbage collector build")); -#endif -} - -SQInteger sq_collectgarbage(HSQUIRRELVM v) -{ -#ifndef NO_GARBAGE_COLLECTOR - return _ss(v)->CollectGarbage(v); -#else - return -1; -#endif -} - -SQRESULT sq_getcallee(HSQUIRRELVM v) -{ - if(v->_callsstacksize > 1) - { - v->Push(v->_callsstack[v->_callsstacksize - 2]._closure); - return SQ_OK; - } - return sq_throwerror(v,_SC("no closure in the calls stack")); -} - -const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval) -{ - SQObjectPtr &self=stack_get(v,idx); - const SQChar *name = NULL; - switch(type(self)) - { - case OT_CLOSURE:{ - SQClosure *clo = _closure(self); - SQFunctionProto *fp = clo->_function; - if(((SQUnsignedInteger)fp->_noutervalues) > nval) { - v->Push(*(_outer(clo->_outervalues[nval])->_valptr)); - SQOuterVar &ov = fp->_outervalues[nval]; - name = _stringval(ov._name); - } - } - break; - case OT_NATIVECLOSURE:{ - SQNativeClosure *clo = _nativeclosure(self); - if(clo->_noutervalues > nval) { - v->Push(clo->_outervalues[nval]); - name = _SC("@NATIVE"); - } - } - break; - default: break; //shutup compiler - } - return name; -} - -SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval) -{ - SQObjectPtr &self=stack_get(v,idx); - switch(type(self)) - { - case OT_CLOSURE:{ - SQFunctionProto *fp = _closure(self)->_function; - if(((SQUnsignedInteger)fp->_noutervalues) > nval){ - *(_outer(_closure(self)->_outervalues[nval])->_valptr) = stack_get(v,-1); - } - else return sq_throwerror(v,_SC("invalid free var index")); - } - break; - case OT_NATIVECLOSURE: - if(_nativeclosure(self)->_noutervalues > nval){ - _nativeclosure(self)->_outervalues[nval] = stack_get(v,-1); - } - else return sq_throwerror(v,_SC("invalid free var index")); - break; - default: - return sq_aux_invalidtype(v,type(self)); - } - v->Pop(); - return SQ_OK; -} - -SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_CLASS,o); - SQObjectPtr &key = stack_get(v,-2); - SQObjectPtr &val = stack_get(v,-1); - SQObjectPtr attrs; - if(type(key) == OT_NULL) { - attrs = _class(*o)->_attributes; - _class(*o)->_attributes = val; - v->Pop(2); - v->Push(attrs); - return SQ_OK; - }else if(_class(*o)->GetAttributes(key,attrs)) { - _class(*o)->SetAttributes(key,val); - v->Pop(2); - v->Push(attrs); - return SQ_OK; - } - return sq_throwerror(v,_SC("wrong index")); -} - -SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_CLASS,o); - SQObjectPtr &key = stack_get(v,-1); - SQObjectPtr attrs; - if(type(key) == OT_NULL) { - attrs = _class(*o)->_attributes; - v->Pop(); - v->Push(attrs); - return SQ_OK; - } - else if(_class(*o)->GetAttributes(key,attrs)) { - v->Pop(); - v->Push(attrs); - return SQ_OK; - } - return sq_throwerror(v,_SC("wrong index")); -} - -SQRESULT sq_getmemberhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_CLASS,o); - SQObjectPtr &key = stack_get(v,-1); - SQTable *m = _class(*o)->_members; - SQObjectPtr val; - if(m->Get(key,val)) { - handle->_static = _isfield(val) ? SQFalse : SQTrue; - handle->_index = _member_idx(val); - v->Pop(); - return SQ_OK; - } - return sq_throwerror(v,_SC("wrong index")); -} - -SQRESULT _getmemberbyhandle(HSQUIRRELVM v,SQObjectPtr &self,HSQMEMBERHANDLE *handle,SQObjectPtr *&val) -{ - switch(type(self)) { - case OT_INSTANCE: { - SQInstance *i = _instance(self); - if(handle->_static) { - SQClass *c = i->_class; - val = &c->_methods[handle->_index].val; - } - else { - val = &i->_values[handle->_index]; - - } - } - break; - case OT_CLASS: { - SQClass *c = _class(self); - if(handle->_static) { - val = &c->_methods[handle->_index].val; - } - else { - val = &c->_defaultvalues[handle->_index].val; - } - } - break; - default: - return sq_throwerror(v,_SC("wrong type(expected class or instance)")); - } - return SQ_OK; -} - -SQRESULT sq_getbyhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle) -{ - SQObjectPtr &self = stack_get(v,idx); - SQObjectPtr *val = NULL; - if(SQ_FAILED(_getmemberbyhandle(v,self,handle,val))) { - return SQ_ERROR; - } - v->Push(_realval(*val)); - return SQ_OK; -} - -SQRESULT sq_setbyhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle) -{ - SQObjectPtr &self = stack_get(v,idx); - SQObjectPtr &newval = stack_get(v,-1); - SQObjectPtr *val = NULL; - if(SQ_FAILED(_getmemberbyhandle(v,self,handle,val))) { - return SQ_ERROR; - } - *val = newval; - v->Pop(); - return SQ_OK; -} - -SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_CLASS,o); - if(_class(*o)->_base) - v->Push(SQObjectPtr(_class(*o)->_base)); - else - v->PushNull(); - return SQ_OK; -} - -SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_INSTANCE,o); - v->Push(SQObjectPtr(_instance(*o)->_class)); - return SQ_OK; -} - -SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_CLASS,o); - v->Push(_class(*o)->CreateInstance()); - return SQ_OK; -} - -void sq_weakref(HSQUIRRELVM v,SQInteger idx) -{ - SQObject &o=stack_get(v,idx); - if(ISREFCOUNTED(type(o))) { - v->Push(_refcounted(o)->GetWeakRef(type(o))); - return; - } - v->Push(o); -} - -SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &o = stack_get(v,idx); - if(type(o) != OT_WEAKREF) { - return sq_throwerror(v,_SC("the object must be a weakref")); - } - v->Push(_weakref(o)->_obj); - return SQ_OK; -} - -SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t) -{ - SQSharedState *ss = _ss(v); - switch(t) { - case OT_TABLE: v->Push(ss->_table_default_delegate); break; - case OT_ARRAY: v->Push(ss->_array_default_delegate); break; - case OT_STRING: v->Push(ss->_string_default_delegate); break; - case OT_INTEGER: case OT_FLOAT: v->Push(ss->_number_default_delegate); break; - case OT_GENERATOR: v->Push(ss->_generator_default_delegate); break; - case OT_CLOSURE: case OT_NATIVECLOSURE: v->Push(ss->_closure_default_delegate); break; - case OT_THREAD: v->Push(ss->_thread_default_delegate); break; - case OT_CLASS: v->Push(ss->_class_default_delegate); break; - case OT_INSTANCE: v->Push(ss->_instance_default_delegate); break; - case OT_WEAKREF: v->Push(ss->_weakref_default_delegate); break; - default: return sq_throwerror(v,_SC("the type doesn't have a default delegate")); - } - return SQ_OK; -} - -SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val; - if(type(o) == OT_GENERATOR) { - return sq_throwerror(v,_SC("cannot iterate a generator")); - } - int faketojump; - if(!v->FOREACH_OP(o,realkey,val,refpos,0,666,faketojump)) - return SQ_ERROR; - if(faketojump != 666) { - v->Push(realkey); - v->Push(val); - return SQ_OK; - } - return SQ_ERROR; -} - -struct BufState{ - const SQChar *buf; - SQInteger ptr; - SQInteger size; -}; - -SQInteger buf_lexfeed(SQUserPointer file) -{ - BufState *buf=(BufState*)file; - if(buf->size<(buf->ptr+1)) - return 0; - return buf->buf[buf->ptr++]; -} - -SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror) { - BufState buf; - buf.buf = s; - buf.size = size; - buf.ptr = 0; - return sq_compile(v, buf_lexfeed, &buf, sourcename, raiseerror); -} - -void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx) -{ - dest->Push(stack_get(src,idx)); -} - -void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc,SQPRINTFUNCTION errfunc) -{ - _ss(v)->_printfunc = printfunc; - _ss(v)->_errorfunc = errfunc; -} - -SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v) -{ - return _ss(v)->_printfunc; -} - -SQPRINTFUNCTION sq_geterrorfunc(HSQUIRRELVM v) -{ - return _ss(v)->_errorfunc; -} - -void *sq_malloc(SQUnsignedInteger size) -{ - return SQ_MALLOC(size); -} - -void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize) -{ - return SQ_REALLOC(p,oldsize,newsize); -} - -void sq_free(void *p,SQUnsignedInteger size) -{ - SQ_FREE(p,size); -} +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqstring.h" +#include "sqtable.h" +#include "sqarray.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "squserdata.h" +#include "sqcompiler.h" +#include "sqfuncstate.h" +#include "sqclass.h" + +bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr **o) +{ + *o = &stack_get(v,idx); + if(type(**o) != type){ + SQObjectPtr oval = v->PrintObjVal(**o); + v->Raise_Error(_SC("wrong argument type, expected '%s' got '%.50s'"),IdType2Name(type),_stringval(oval)); + return false; + } + return true; +} + +#define _GETSAFE_OBJ(v,idx,type,o) { if(!sq_aux_gettypedarg(v,idx,type,&o)) return SQ_ERROR; } + +#define sq_aux_paramscheck(v,count) \ +{ \ + if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\ +} + + +SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type) +{ + scsprintf(_ss(v)->GetScratchPad(100), _SC("unexpected type %s"), IdType2Name(type)); + return sq_throwerror(v, _ss(v)->GetScratchPad(-1)); +} + +HSQUIRRELVM sq_open(SQInteger initialstacksize) +{ + SQSharedState *ss; + SQVM *v; + sq_new(ss, SQSharedState); + ss->Init(); + v = (SQVM *)SQ_MALLOC(sizeof(SQVM)); + new (v) SQVM(ss); + ss->_root_vm = v; + if(v->Init(NULL, initialstacksize)) { + return v; + } else { + sq_delete(v, SQVM); + return NULL; + } + return v; +} + +HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize) +{ + SQSharedState *ss; + SQVM *v; + ss=_ss(friendvm); + + v= (SQVM *)SQ_MALLOC(sizeof(SQVM)); + new (v) SQVM(ss); + + if(v->Init(friendvm, initialstacksize)) { + friendvm->Push(v); + return v; + } else { + sq_delete(v, SQVM); + return NULL; + } +} + +SQInteger sq_getvmstate(HSQUIRRELVM v) +{ + if(v->_suspended) + return SQ_VMSTATE_SUSPENDED; + else { + if(v->_callsstacksize != 0) return SQ_VMSTATE_RUNNING; + else return SQ_VMSTATE_IDLE; + } +} + +void sq_seterrorhandler(HSQUIRRELVM v) +{ + SQObject o = stack_get(v, -1); + if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) { + v->_errorhandler = o; + v->Pop(); + } +} + +void sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook) +{ + v->_debughook_native = hook; + v->_debughook_closure.Null(); + v->_debughook = hook?true:false; +} + +void sq_setdebughook(HSQUIRRELVM v) +{ + SQObject o = stack_get(v,-1); + if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) { + v->_debughook_closure = o; + v->_debughook_native = NULL; + v->_debughook = !sq_isnull(o); + v->Pop(); + } +} + +void sq_close(HSQUIRRELVM v) +{ + SQSharedState *ss = _ss(v); + _thread(ss->_root_vm)->Finalize(); + sq_delete(ss, SQSharedState); +} + +SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror) +{ + SQObjectPtr o; +#ifndef NO_COMPILER + if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) { + v->Push(SQClosure::Create(_ss(v), _funcproto(o))); + return SQ_OK; + } + return SQ_ERROR; +#else + return sq_throwerror(v,_SC("this is a no compiler build")); +#endif +} + +void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable) +{ + _ss(v)->_debuginfo = enable?true:false; +} + +void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable) +{ + _ss(v)->_notifyallexceptions = enable?true:false; +} + +void sq_addref(HSQUIRRELVM v,HSQOBJECT *po) +{ + if(!ISREFCOUNTED(type(*po))) return; +#ifdef NO_GARBAGE_COLLECTOR + __AddRef(po->_type,po->_unVal); +#else + _ss(v)->_refs_table.AddRef(*po); +#endif +} + +SQUnsignedInteger sq_getrefcount(HSQUIRRELVM v,HSQOBJECT *po) +{ + if(!ISREFCOUNTED(type(*po))) return 0; +#ifdef NO_GARBAGE_COLLECTOR + return po->_unVal.pRefCounted->_uiRef; +#else + return _ss(v)->_refs_table.GetRefCount(*po); +#endif +} + +SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po) +{ + if(!ISREFCOUNTED(type(*po))) return SQTrue; +#ifdef NO_GARBAGE_COLLECTOR + bool ret = (po->_unVal.pRefCounted->_uiRef <= 1) ? SQTrue : SQFalse; + __Release(po->_type,po->_unVal); + return ret; //the ret val doesn't work(and cannot be fixed) +#else + return _ss(v)->_refs_table.Release(*po); +#endif +} + +const SQChar *sq_objtostring(const HSQOBJECT *o) +{ + if(sq_type(*o) == OT_STRING) { + return _stringval(*o); + } + return NULL; +} + +SQInteger sq_objtointeger(const HSQOBJECT *o) +{ + if(sq_isnumeric(*o)) { + return tointeger(*o); + } + return 0; +} + +SQFloat sq_objtofloat(const HSQOBJECT *o) +{ + if(sq_isnumeric(*o)) { + return tofloat(*o); + } + return 0; +} + +SQBool sq_objtobool(const HSQOBJECT *o) +{ + if(sq_isbool(*o)) { + return _integer(*o); + } + return SQFalse; +} + +SQUserPointer sq_objtouserpointer(const HSQOBJECT *o) +{ + if(sq_isuserpointer(*o)) { + return _userpointer(*o); + } + return 0; +} + +void sq_pushnull(HSQUIRRELVM v) +{ + v->PushNull(); +} + +void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len) +{ + if(s) + v->Push(SQObjectPtr(SQString::Create(_ss(v), s, len))); + else v->PushNull(); +} + +void sq_pushinteger(HSQUIRRELVM v,SQInteger n) +{ + v->Push(n); +} + +void sq_pushbool(HSQUIRRELVM v,SQBool b) +{ + v->Push(b?true:false); +} + +void sq_pushfloat(HSQUIRRELVM v,SQFloat n) +{ + v->Push(n); +} + +void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p) +{ + v->Push(p); +} + +SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size) +{ + SQUserData *ud = SQUserData::Create(_ss(v), size); + v->Push(ud); + return (SQUserPointer)sq_aligning(ud + 1); +} + +void sq_newtable(HSQUIRRELVM v) +{ + v->Push(SQTable::Create(_ss(v), 0)); +} + +void sq_newtableex(HSQUIRRELVM v,SQInteger initialcapacity) +{ + v->Push(SQTable::Create(_ss(v), initialcapacity)); +} + +void sq_newarray(HSQUIRRELVM v,SQInteger size) +{ + v->Push(SQArray::Create(_ss(v), size)); +} + +SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase) +{ + SQClass *baseclass = NULL; + if(hasbase) { + SQObjectPtr &base = stack_get(v,-1); + if(type(base) != OT_CLASS) + return sq_throwerror(v,_SC("invalid base type")); + baseclass = _class(base); + } + SQClass *newclass = SQClass::Create(_ss(v), baseclass); + if(baseclass) v->Pop(); + v->Push(newclass); + return SQ_OK; +} + +SQBool sq_instanceof(HSQUIRRELVM v) +{ + SQObjectPtr &inst = stack_get(v,-1); + SQObjectPtr &cl = stack_get(v,-2); + if(type(inst) != OT_INSTANCE || type(cl) != OT_CLASS) + return sq_throwerror(v,_SC("invalid param type")); + return _instance(inst)->InstanceOf(_class(cl))?SQTrue:SQFalse; +} + +SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx) +{ + sq_aux_paramscheck(v,2); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + _array(*arr)->Append(v->GetUp(-1)); + v->Pop(); + return SQ_OK; +} + +SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + if(_array(*arr)->Size() > 0) { + if(pushval != 0){ v->Push(_array(*arr)->Top()); } + _array(*arr)->Pop(); + return SQ_OK; + } + return sq_throwerror(v, _SC("empty array")); +} + +SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize) +{ + sq_aux_paramscheck(v,1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + if(newsize >= 0) { + _array(*arr)->Resize(newsize); + return SQ_OK; + } + return sq_throwerror(v,_SC("negative size")); +} + + +SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *o; + _GETSAFE_OBJ(v, idx, OT_ARRAY,o); + SQArray *arr = _array(*o); + if(arr->Size() > 0) { + SQObjectPtr t; + SQInteger size = arr->Size(); + SQInteger n = size >> 1; size -= 1; + for(SQInteger i = 0; i < n; i++) { + t = arr->_values[i]; + arr->_values[i] = arr->_values[size-i]; + arr->_values[size-i] = t; + } + return SQ_OK; + } + return SQ_OK; +} + +SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + return _array(*arr)->Remove(itemidx) ? SQ_OK : sq_throwerror(v,_SC("index out of range")); +} + +SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + SQRESULT ret = _array(*arr)->Insert(destpos, v->GetUp(-1)) ? SQ_OK : sq_throwerror(v,_SC("index out of range")); + v->Pop(); + return ret; +} + +void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars) +{ + SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func,nfreevars); + nc->_nparamscheck = 0; + for(SQUnsignedInteger i = 0; i < nfreevars; i++) { + nc->_outervalues[i] = v->Top(); + v->Pop(); + } + v->Push(SQObjectPtr(nc)); +} + +SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars) +{ + SQObject o = stack_get(v, idx); + if(type(o) == OT_CLOSURE) { + SQClosure *c = _closure(o); + SQFunctionProto *proto = c->_function; + *nparams = (SQUnsignedInteger)proto->_nparameters; + *nfreevars = (SQUnsignedInteger)proto->_noutervalues; + return SQ_OK; + } + else if(type(o) == OT_NATIVECLOSURE) + { + SQNativeClosure *c = _nativeclosure(o); + *nparams = (SQUnsignedInteger)c->_nparamscheck; + *nfreevars = c->_noutervalues; + return SQ_OK; + } + return sq_throwerror(v,_SC("the object is not a closure")); +} + +SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name) +{ + SQObject o = stack_get(v, idx); + if(sq_isnativeclosure(o)) { + SQNativeClosure *nc = _nativeclosure(o); + nc->_name = SQString::Create(_ss(v),name); + return SQ_OK; + } + return sq_throwerror(v,_SC("the object is not a nativeclosure")); +} + +SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask) +{ + SQObject o = stack_get(v, -1); + if(!sq_isnativeclosure(o)) + return sq_throwerror(v, _SC("native closure expected")); + SQNativeClosure *nc = _nativeclosure(o); + nc->_nparamscheck = nparamscheck; + if(typemask) { + SQIntVec res; + if(!CompileTypemask(res, typemask)) + return sq_throwerror(v, _SC("invalid typemask")); + nc->_typecheck.copy(res); + } + else { + nc->_typecheck.resize(0); + } + if(nparamscheck == SQ_MATCHTYPEMASKSTRING) { + nc->_nparamscheck = nc->_typecheck.size(); + } + return SQ_OK; +} + +SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v,idx); + if(!sq_isnativeclosure(o) && + !sq_isclosure(o)) + return sq_throwerror(v,_SC("the target is not a closure")); + SQObjectPtr &env = stack_get(v,-1); + if(!sq_istable(env) && + !sq_isclass(env) && + !sq_isinstance(env)) + return sq_throwerror(v,_SC("invalid environment")); + SQWeakRef *w = _refcounted(env)->GetWeakRef(type(env)); + SQObjectPtr ret; + if(sq_isclosure(o)) { + SQClosure *c = _closure(o)->Clone(); + __ObjRelease(c->_env); + c->_env = w; + __ObjAddRef(c->_env); + if(_closure(o)->_base) { + c->_base = _closure(o)->_base; + __ObjAddRef(c->_base); + } + ret = c; + } + else { //then must be a native closure + SQNativeClosure *c = _nativeclosure(o)->Clone(); + __ObjRelease(c->_env); + c->_env = w; + __ObjAddRef(c->_env); + ret = c; + } + v->Pop(); + v->Push(ret); + return SQ_OK; +} + +SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx) +{ + SQObject &o=stack_get(v,idx); + switch(type(o)) { + case OT_TABLE: _table(o)->Clear(); break; + case OT_ARRAY: _array(o)->Resize(0); break; + default: + return sq_throwerror(v, _SC("clear only works on table and array")); + break; + + } + return SQ_OK; +} + +void sq_pushroottable(HSQUIRRELVM v) +{ + v->Push(v->_roottable); +} + +void sq_pushregistrytable(HSQUIRRELVM v) +{ + v->Push(_ss(v)->_registry); +} + +void sq_pushconsttable(HSQUIRRELVM v) +{ + v->Push(_ss(v)->_consts); +} + +SQRESULT sq_setroottable(HSQUIRRELVM v) +{ + SQObject o = stack_get(v, -1); + if(sq_istable(o) || sq_isnull(o)) { + v->_roottable = o; + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v, _SC("ivalid type")); +} + +SQRESULT sq_setconsttable(HSQUIRRELVM v) +{ + SQObject o = stack_get(v, -1); + if(sq_istable(o)) { + _ss(v)->_consts = o; + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v, _SC("ivalid type, expected table")); +} + +void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p) +{ + v->_foreignptr = p; +} + +SQUserPointer sq_getforeignptr(HSQUIRRELVM v) +{ + return v->_foreignptr; +} + +void sq_push(HSQUIRRELVM v,SQInteger idx) +{ + v->Push(stack_get(v, idx)); +} + +SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx) +{ + return type(stack_get(v, idx)); +} + + +SQRESULT sq_tostring(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v, idx); + SQObjectPtr res; + if(!v->ToString(o,res)) { + return SQ_ERROR; + } + v->Push(res); + return SQ_OK; +} + +void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b) +{ + SQObjectPtr &o = stack_get(v, idx); + *b = SQVM::IsFalse(o)?SQFalse:SQTrue; +} + +SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i) +{ + SQObjectPtr &o = stack_get(v, idx); + if(sq_isnumeric(o)) { + *i = tointeger(o); + return SQ_OK; + } + return SQ_ERROR; +} + +SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f) +{ + SQObjectPtr &o = stack_get(v, idx); + if(sq_isnumeric(o)) { + *f = tofloat(o); + return SQ_OK; + } + return SQ_ERROR; +} + +SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b) +{ + SQObjectPtr &o = stack_get(v, idx); + if(sq_isbool(o)) { + *b = _integer(o); + return SQ_OK; + } + return SQ_ERROR; +} + +SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_STRING,o); + *c = _stringval(*o); + return SQ_OK; +} + +SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_THREAD,o); + *thread = _thread(*o); + return SQ_OK; +} + +SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v,idx); + v->PushNull(); + if(!v->Clone(o, stack_get(v, -1))){ + v->Pop(); + return SQ_ERROR; + } + return SQ_OK; +} + +SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx) +{ + SQObjectPtr &o = stack_get(v, idx); + SQObjectType type = type(o); + switch(type) { + case OT_STRING: return _string(o)->_len; + case OT_TABLE: return _table(o)->CountUsed(); + case OT_ARRAY: return _array(o)->Size(); + case OT_USERDATA: return _userdata(o)->_size; + case OT_INSTANCE: return _instance(o)->_class->_udsize; + case OT_CLASS: return _class(o)->_udsize; + default: + return sq_aux_invalidtype(v, type); + } +} + +SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_USERDATA,o); + (*p) = _userdataval(*o); + if(typetag) *typetag = _userdata(*o)->_typetag; + return SQ_OK; +} + +SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag) +{ + SQObjectPtr &o = stack_get(v,idx); + switch(type(o)) { + case OT_USERDATA: _userdata(o)->_typetag = typetag; break; + case OT_CLASS: _class(o)->_typetag = typetag; break; + default: return sq_throwerror(v,_SC("invalid object type")); + } + return SQ_OK; +} + +SQRESULT sq_getobjtypetag(const HSQOBJECT *o,SQUserPointer * typetag) +{ + switch(type(*o)) { + case OT_INSTANCE: *typetag = _instance(*o)->_class->_typetag; break; + case OT_USERDATA: *typetag = _userdata(*o)->_typetag; break; + case OT_CLASS: *typetag = _class(*o)->_typetag; break; + default: return SQ_ERROR; + } + return SQ_OK; +} + +SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag) +{ + SQObjectPtr &o = stack_get(v,idx); + if(SQ_FAILED(sq_getobjtypetag(&o,typetag))) + return sq_throwerror(v,_SC("invalid object type")); + return SQ_OK; +} + +SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_USERPOINTER,o); + (*p) = _userpointer(*o); + return SQ_OK; +} + +SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p) +{ + SQObjectPtr &o = stack_get(v,idx); + if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance")); + _instance(o)->_userpointer = p; + return SQ_OK; +} + +SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize) +{ + SQObjectPtr &o = stack_get(v,idx); + if(type(o) != OT_CLASS) return sq_throwerror(v,_SC("the object is not a class")); + if(_class(o)->_locked) return sq_throwerror(v,_SC("the class is locked")); + _class(o)->_udsize = udsize; + return SQ_OK; +} + + +SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag) +{ + SQObjectPtr &o = stack_get(v,idx); + if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance")); + (*p) = _instance(o)->_userpointer; + if(typetag != 0) { + SQClass *cl = _instance(o)->_class; + do{ + if(cl->_typetag == typetag) + return SQ_OK; + cl = cl->_base; + }while(cl != NULL); + return sq_throwerror(v,_SC("invalid type tag")); + } + return SQ_OK; +} + +SQInteger sq_gettop(HSQUIRRELVM v) +{ + return (v->_top) - v->_stackbase; +} + +void sq_settop(HSQUIRRELVM v, SQInteger newtop) +{ + SQInteger top = sq_gettop(v); + if(top > newtop) + sq_pop(v, top - newtop); + else + while(top++ < newtop) sq_pushnull(v); +} + +void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop) +{ + assert(v->_top >= nelemstopop); + v->Pop(nelemstopop); +} + +void sq_poptop(HSQUIRRELVM v) +{ + assert(v->_top >= 1); + v->Pop(); +} + + +void sq_remove(HSQUIRRELVM v, SQInteger idx) +{ + v->Remove(idx); +} + +SQInteger sq_cmp(HSQUIRRELVM v) +{ + SQInteger res; + v->ObjCmp(stack_get(v, -1), stack_get(v, -2),res); + return res; +} + +SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic) +{ + sq_aux_paramscheck(v, 3); + SQObjectPtr &self = stack_get(v, idx); + if(type(self) == OT_TABLE || type(self) == OT_CLASS) { + SQObjectPtr &key = v->GetUp(-2); + if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key")); + v->NewSlot(self, key, v->GetUp(-1),bstatic?true:false); + v->Pop(2); + } + return SQ_OK; +} + +SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval) +{ + sq_aux_paramscheck(v, 2); + SQObjectPtr *self; + _GETSAFE_OBJ(v, idx, OT_TABLE,self); + SQObjectPtr &key = v->GetUp(-1); + if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key")); + SQObjectPtr res; + if(!v->DeleteSlot(*self, key, res)){ + return SQ_ERROR; + } + if(pushval) v->GetUp(-1) = res; + else v->Pop(); + return SQ_OK; +} + +SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self = stack_get(v, idx); + if(v->Set(self, v->GetUp(-2), v->GetUp(-1),DONT_FALL_BACK)) { + v->Pop(2); + return SQ_OK; + } + return SQ_ERROR; +} + +SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self = stack_get(v, idx); + if(type(v->GetUp(-2)) == OT_NULL) return sq_throwerror(v, _SC("null key")); + switch(type(self)) { + case OT_TABLE: + _table(self)->NewSlot(v->GetUp(-2), v->GetUp(-1)); + v->Pop(2); + return SQ_OK; + break; + case OT_CLASS: + _class(self)->NewSlot(_ss(v), v->GetUp(-2), v->GetUp(-1),false); + v->Pop(2); + return SQ_OK; + break; + case OT_INSTANCE: + if(_instance(self)->Set(v->GetUp(-2), v->GetUp(-1))) { + v->Pop(2); + return SQ_OK; + } + break; + case OT_ARRAY: + if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) { + v->Pop(2); + return SQ_OK; + } + break; + default: + v->Pop(2); + return sq_throwerror(v, _SC("rawset works only on array/table/class and instance")); + } + v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR; +} + +SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self = stack_get(v, idx); + SQObjectPtr &mt = v->GetUp(-1); + SQObjectType type = type(self); + switch(type) { + case OT_TABLE: + if(type(mt) == OT_TABLE) { + if(!_table(self)->SetDelegate(_table(mt))) return sq_throwerror(v, _SC("delagate cycle")); v->Pop();} + else if(type(mt)==OT_NULL) { + _table(self)->SetDelegate(NULL); v->Pop(); } + else return sq_aux_invalidtype(v,type); + break; + case OT_USERDATA: + if(type(mt)==OT_TABLE) { + _userdata(self)->SetDelegate(_table(mt)); v->Pop(); } + else if(type(mt)==OT_NULL) { + _userdata(self)->SetDelegate(NULL); v->Pop(); } + else return sq_aux_invalidtype(v, type); + break; + default: + return sq_aux_invalidtype(v, type); + break; + } + return SQ_OK; +} + +SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval) +{ + sq_aux_paramscheck(v, 2); + SQObjectPtr *self; + _GETSAFE_OBJ(v, idx, OT_TABLE,self); + SQObjectPtr &key = v->GetUp(-1); + SQObjectPtr t; + if(_table(*self)->Get(key,t)) { + _table(*self)->Remove(key); + } + if(pushval != 0) + v->GetUp(-1) = t; + else + v->Pop(); + return SQ_OK; +} + +SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self=stack_get(v,idx); + switch(type(self)){ + case OT_TABLE: + case OT_USERDATA: + if(!_delegable(self)->_delegate){ + v->PushNull(); + break; + } + v->Push(SQObjectPtr(_delegable(self)->_delegate)); + break; + default: return sq_throwerror(v,_SC("wrong type")); break; + } + return SQ_OK; + +} + +SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self=stack_get(v,idx); + if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,DONT_FALL_BACK)) + return SQ_OK; + v->Pop(); + return SQ_ERROR; +} + +SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self=stack_get(v,idx); + switch(type(self)) { + case OT_TABLE: + if(_table(self)->Get(v->GetUp(-1),v->GetUp(-1))) + return SQ_OK; + break; + case OT_CLASS: + if(_class(self)->Get(v->GetUp(-1),v->GetUp(-1))) + return SQ_OK; + break; + case OT_INSTANCE: + if(_instance(self)->Get(v->GetUp(-1),v->GetUp(-1))) + return SQ_OK; + break; + case OT_ARRAY:{ + SQObjectPtr& key = v->GetUp(-1); + if(sq_isnumeric(key)){ + if(_array(self)->Get(tointeger(key),v->GetUp(-1))) { + return SQ_OK; + } + } + else { + v->Pop(); + return sq_throwerror(v,_SC("invalid index type for an array")); + } + } + break; + default: + v->Pop(); + return sq_throwerror(v,_SC("rawget works only on array/table/instance and class")); + } + v->Pop(); + return sq_throwerror(v,_SC("the index doesn't exist")); +} + +SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po) +{ + *po=stack_get(v,idx); + return SQ_OK; +} + +const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx) +{ + SQUnsignedInteger cstksize=v->_callsstacksize; + SQUnsignedInteger lvl=(cstksize-level)-1; + SQInteger stackbase=v->_stackbase; + if(lvl_callsstack[(cstksize-i)-1]; + stackbase-=ci._prevstkbase; + } + SQVM::CallInfo &ci=v->_callsstack[lvl]; + if(type(ci._closure)!=OT_CLOSURE) + return NULL; + SQClosure *c=_closure(ci._closure); + SQFunctionProto *func=c->_function; + if(func->_noutervalues > (SQInteger)idx) { + v->Push(*_outer(c->_outervalues[idx])->_valptr); + return _stringval(func->_outervalues[idx]._name); + } + idx -= func->_noutervalues; + return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions)-1); + } + return NULL; +} + +void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj) +{ + v->Push(SQObjectPtr(obj)); +} + +void sq_resetobject(HSQOBJECT *po) +{ + po->_unVal.pUserPointer=NULL;po->_type=OT_NULL; +} + +SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err) +{ + v->_lasterror=SQString::Create(_ss(v),err); + return SQ_ERROR; +} + +SQRESULT sq_throwobject(HSQUIRRELVM v) +{ + v->_lasterror = v->GetUp(-1); + v->Pop(); + return SQ_ERROR; +} + + +void sq_reseterror(HSQUIRRELVM v) +{ + v->_lasterror.Null(); +} + +void sq_getlasterror(HSQUIRRELVM v) +{ + v->Push(v->_lasterror); +} + +SQRESULT sq_reservestack(HSQUIRRELVM v,SQInteger nsize) +{ + if (((SQUnsignedInteger)v->_top + nsize) > v->_stack.size()) { + if(v->_nmetamethodscall) { + return sq_throwerror(v,_SC("cannot resize stack while in a metamethod")); + } + v->_stack.resize(v->_stack.size() + ((v->_top + nsize) - v->_stack.size())); + } + return SQ_OK; +} + +SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror) +{ + if(type(v->GetUp(-1))==OT_GENERATOR){ + v->PushNull(); //retval + if(!v->Execute(v->GetUp(-2),0,v->_top,v->GetUp(-1),raiseerror,SQVM::ET_RESUME_GENERATOR)) + {v->Raise_Error(v->_lasterror); return SQ_ERROR;} + if(!retval) + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v,_SC("only generators can be resumed")); +} + +SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror) +{ + SQObjectPtr res; + if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){ + + if(!v->_suspended) { + v->Pop(params);//pop closure and args + } + if(retval){ + v->Push(res); return SQ_OK; + } + return SQ_OK; + } + else { + v->Pop(params); + return SQ_ERROR; + } + if(!v->_suspended) + v->Pop(params); + return sq_throwerror(v,_SC("call failed")); +} + +SQRESULT sq_suspendvm(HSQUIRRELVM v) +{ + return v->Suspend(); +} + +SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror,SQBool throwerror) +{ + SQObjectPtr ret; + if(!v->_suspended) + return sq_throwerror(v,_SC("cannot resume a vm that is not running any code")); + SQInteger target = v->_suspended_target; + if(wakeupret) { + if(target != -1) { + v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval + } + v->Pop(); + } else if(target != -1) { v->GetAt(v->_stackbase+v->_suspended_target).Null(); } + SQObjectPtr dummy; + if(!v->Execute(dummy,-1,-1,ret,raiseerror,throwerror?SQVM::ET_RESUME_THROW_VM : SQVM::ET_RESUME_VM)) { + return SQ_ERROR; + } + if(retval) + v->Push(ret); + return SQ_OK; +} + +void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook) +{ + if(sq_gettop(v) >= 1){ + SQObjectPtr &ud=stack_get(v,idx); + switch( type(ud) ) { + case OT_USERDATA: _userdata(ud)->_hook = hook; break; + case OT_INSTANCE: _instance(ud)->_hook = hook; break; + case OT_CLASS: _class(ud)->_hook = hook; break; + default: break; //shutup compiler + } + } +} + +void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f) +{ + _ss(v)->_compilererrorhandler = f; +} + +SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, -1, OT_CLOSURE,o); + unsigned short tag = SQ_BYTECODE_STREAM_TAG; + if(w(up,&tag,2) != 2) + return sq_throwerror(v,_SC("io error")); + if(!_closure(*o)->Save(v,up,w)) + return SQ_ERROR; + return SQ_OK; +} + +SQRESULT sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up) +{ + SQObjectPtr closure; + + unsigned short tag; + if(r(up,&tag,2) != 2) + return sq_throwerror(v,_SC("io error")); + if(tag != SQ_BYTECODE_STREAM_TAG) + return sq_throwerror(v,_SC("invalid stream")); + if(!SQClosure::Load(v,up,r,closure)) + return SQ_ERROR; + v->Push(closure); + return SQ_OK; +} + +SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize) +{ + return _ss(v)->GetScratchPad(minsize); +} + +SQRESULT sq_resurrectunreachable(HSQUIRRELVM v) +{ +#ifndef NO_GARBAGE_COLLECTOR + _ss(v)->ResurrectUnreachable(v); + return SQ_OK; +#else + return sq_throwerror(v,_SC("sq_resurrectunreachable requires a garbage collector build")); +#endif +} + +SQInteger sq_collectgarbage(HSQUIRRELVM v) +{ +#ifndef NO_GARBAGE_COLLECTOR + return _ss(v)->CollectGarbage(v); +#else + return -1; +#endif +} + +SQRESULT sq_getcallee(HSQUIRRELVM v) +{ + if(v->_callsstacksize > 1) + { + v->Push(v->_callsstack[v->_callsstacksize - 2]._closure); + return SQ_OK; + } + return sq_throwerror(v,_SC("no closure in the calls stack")); +} + +const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval) +{ + SQObjectPtr &self=stack_get(v,idx); + const SQChar *name = NULL; + switch(type(self)) + { + case OT_CLOSURE:{ + SQClosure *clo = _closure(self); + SQFunctionProto *fp = clo->_function; + if(((SQUnsignedInteger)fp->_noutervalues) > nval) { + v->Push(*(_outer(clo->_outervalues[nval])->_valptr)); + SQOuterVar &ov = fp->_outervalues[nval]; + name = _stringval(ov._name); + } + } + break; + case OT_NATIVECLOSURE:{ + SQNativeClosure *clo = _nativeclosure(self); + if(clo->_noutervalues > nval) { + v->Push(clo->_outervalues[nval]); + name = _SC("@NATIVE"); + } + } + break; + default: break; //shutup compiler + } + return name; +} + +SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval) +{ + SQObjectPtr &self=stack_get(v,idx); + switch(type(self)) + { + case OT_CLOSURE:{ + SQFunctionProto *fp = _closure(self)->_function; + if(((SQUnsignedInteger)fp->_noutervalues) > nval){ + *(_outer(_closure(self)->_outervalues[nval])->_valptr) = stack_get(v,-1); + } + else return sq_throwerror(v,_SC("invalid free var index")); + } + break; + case OT_NATIVECLOSURE: + if(_nativeclosure(self)->_noutervalues > nval){ + _nativeclosure(self)->_outervalues[nval] = stack_get(v,-1); + } + else return sq_throwerror(v,_SC("invalid free var index")); + break; + default: + return sq_aux_invalidtype(v,type(self)); + } + v->Pop(); + return SQ_OK; +} + +SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + SQObjectPtr &key = stack_get(v,-2); + SQObjectPtr &val = stack_get(v,-1); + SQObjectPtr attrs; + if(type(key) == OT_NULL) { + attrs = _class(*o)->_attributes; + _class(*o)->_attributes = val; + v->Pop(2); + v->Push(attrs); + return SQ_OK; + }else if(_class(*o)->GetAttributes(key,attrs)) { + _class(*o)->SetAttributes(key,val); + v->Pop(2); + v->Push(attrs); + return SQ_OK; + } + return sq_throwerror(v,_SC("wrong index")); +} + +SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + SQObjectPtr &key = stack_get(v,-1); + SQObjectPtr attrs; + if(type(key) == OT_NULL) { + attrs = _class(*o)->_attributes; + v->Pop(); + v->Push(attrs); + return SQ_OK; + } + else if(_class(*o)->GetAttributes(key,attrs)) { + v->Pop(); + v->Push(attrs); + return SQ_OK; + } + return sq_throwerror(v,_SC("wrong index")); +} + +SQRESULT sq_getmemberhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + SQObjectPtr &key = stack_get(v,-1); + SQTable *m = _class(*o)->_members; + SQObjectPtr val; + if(m->Get(key,val)) { + handle->_static = _isfield(val) ? SQFalse : SQTrue; + handle->_index = _member_idx(val); + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v,_SC("wrong index")); +} + +SQRESULT _getmemberbyhandle(HSQUIRRELVM v,SQObjectPtr &self,HSQMEMBERHANDLE *handle,SQObjectPtr *&val) +{ + switch(type(self)) { + case OT_INSTANCE: { + SQInstance *i = _instance(self); + if(handle->_static) { + SQClass *c = i->_class; + val = &c->_methods[handle->_index].val; + } + else { + val = &i->_values[handle->_index]; + + } + } + break; + case OT_CLASS: { + SQClass *c = _class(self); + if(handle->_static) { + val = &c->_methods[handle->_index].val; + } + else { + val = &c->_defaultvalues[handle->_index].val; + } + } + break; + default: + return sq_throwerror(v,_SC("wrong type(expected class or instance)")); + } + return SQ_OK; +} + +SQRESULT sq_getbyhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle) +{ + SQObjectPtr &self = stack_get(v,idx); + SQObjectPtr *val = NULL; + if(SQ_FAILED(_getmemberbyhandle(v,self,handle,val))) { + return SQ_ERROR; + } + v->Push(_realval(*val)); + return SQ_OK; +} + +SQRESULT sq_setbyhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle) +{ + SQObjectPtr &self = stack_get(v,idx); + SQObjectPtr &newval = stack_get(v,-1); + SQObjectPtr *val = NULL; + if(SQ_FAILED(_getmemberbyhandle(v,self,handle,val))) { + return SQ_ERROR; + } + *val = newval; + v->Pop(); + return SQ_OK; +} + +SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + if(_class(*o)->_base) + v->Push(SQObjectPtr(_class(*o)->_base)); + else + v->PushNull(); + return SQ_OK; +} + +SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_INSTANCE,o); + v->Push(SQObjectPtr(_instance(*o)->_class)); + return SQ_OK; +} + +SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + v->Push(_class(*o)->CreateInstance()); + return SQ_OK; +} + +void sq_weakref(HSQUIRRELVM v,SQInteger idx) +{ + SQObject &o=stack_get(v,idx); + if(ISREFCOUNTED(type(o))) { + v->Push(_refcounted(o)->GetWeakRef(type(o))); + return; + } + v->Push(o); +} + +SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v,idx); + if(type(o) != OT_WEAKREF) { + return sq_throwerror(v,_SC("the object must be a weakref")); + } + v->Push(_weakref(o)->_obj); + return SQ_OK; +} + +SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t) +{ + SQSharedState *ss = _ss(v); + switch(t) { + case OT_TABLE: v->Push(ss->_table_default_delegate); break; + case OT_ARRAY: v->Push(ss->_array_default_delegate); break; + case OT_STRING: v->Push(ss->_string_default_delegate); break; + case OT_INTEGER: case OT_FLOAT: v->Push(ss->_number_default_delegate); break; + case OT_GENERATOR: v->Push(ss->_generator_default_delegate); break; + case OT_CLOSURE: case OT_NATIVECLOSURE: v->Push(ss->_closure_default_delegate); break; + case OT_THREAD: v->Push(ss->_thread_default_delegate); break; + case OT_CLASS: v->Push(ss->_class_default_delegate); break; + case OT_INSTANCE: v->Push(ss->_instance_default_delegate); break; + case OT_WEAKREF: v->Push(ss->_weakref_default_delegate); break; + default: return sq_throwerror(v,_SC("the type doesn't have a default delegate")); + } + return SQ_OK; +} + +SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val; + if(type(o) == OT_GENERATOR) { + return sq_throwerror(v,_SC("cannot iterate a generator")); + } + int faketojump; + if(!v->FOREACH_OP(o,realkey,val,refpos,0,666,faketojump)) + return SQ_ERROR; + if(faketojump != 666) { + v->Push(realkey); + v->Push(val); + return SQ_OK; + } + return SQ_ERROR; +} + +struct BufState{ + const SQChar *buf; + SQInteger ptr; + SQInteger size; +}; + +SQInteger buf_lexfeed(SQUserPointer file) +{ + BufState *buf=(BufState*)file; + if(buf->size<(buf->ptr+1)) + return 0; + return buf->buf[buf->ptr++]; +} + +SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror) { + BufState buf; + buf.buf = s; + buf.size = size; + buf.ptr = 0; + return sq_compile(v, buf_lexfeed, &buf, sourcename, raiseerror); +} + +void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx) +{ + dest->Push(stack_get(src,idx)); +} + +void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc,SQPRINTFUNCTION errfunc) +{ + _ss(v)->_printfunc = printfunc; + _ss(v)->_errorfunc = errfunc; +} + +SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v) +{ + return _ss(v)->_printfunc; +} + +SQPRINTFUNCTION sq_geterrorfunc(HSQUIRRELVM v) +{ + return _ss(v)->_errorfunc; +} + +void *sq_malloc(SQUnsignedInteger size) +{ + return SQ_MALLOC(size); +} + +void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize) +{ + return SQ_REALLOC(p,oldsize,newsize); +} + +void sq_free(void *p,SQUnsignedInteger size) +{ + SQ_FREE(p,size); +} diff --git a/squirrel_3_0_1_stable/squirrel/sqarray.h b/squirrel_3_0_1_stable/squirrel/sqarray.h index c3a57abcc..e9b746657 100644 --- a/squirrel_3_0_1_stable/squirrel/sqarray.h +++ b/squirrel_3_0_1_stable/squirrel/sqarray.h @@ -1,94 +1,94 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQARRAY_H_ -#define _SQARRAY_H_ - -struct SQArray : public CHAINABLE_OBJ -{ -private: - SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);} - ~SQArray() - { - REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); - } -public: - static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){ - SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray)); - new (newarray) SQArray(ss,nInitialSize); - return newarray; - } -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **chain); - SQObjectType GetType() {return OT_ARRAY;} -#endif - void Finalize(){ - _values.resize(0); - } - bool Get(const SQInteger nidx,SQObjectPtr &val) - { - if(nidx>=0 && nidx<(SQInteger)_values.size()){ - SQObjectPtr &o = _values[nidx]; - val = _realval(o); - return true; - } - else return false; - } - bool Set(const SQInteger nidx,const SQObjectPtr &val) - { - if(nidx>=0 && nidx<(SQInteger)_values.size()){ - _values[nidx]=val; - return true; - } - else return false; - } - SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval) - { - SQUnsignedInteger idx=TranslateIndex(refpos); - while(idx<_values.size()){ - //first found - outkey=(SQInteger)idx; - SQObjectPtr &o = _values[idx]; - outval = _realval(o); - //return idx for the next iteration - return ++idx; - } - //nothing to iterate anymore - return -1; - } - SQArray *Clone(){SQArray *anew=Create(_opt_ss(this),0); anew->_values.copy(_values); return anew; } - SQInteger Size() const {return _values.size();} - void Resize(SQInteger size) - { - SQObjectPtr _null; - Resize(size,_null); - } - void Resize(SQInteger size,SQObjectPtr &fill) { _values.resize(size,fill); ShrinkIfNeeded(); } - void Reserve(SQInteger size) { _values.reserve(size); } - void Append(const SQObject &o){_values.push_back(o);} - void Extend(const SQArray *a); - SQObjectPtr &Top(){return _values.top();} - void Pop(){_values.pop_back(); ShrinkIfNeeded(); } - bool Insert(SQInteger idx,const SQObject &val){ - if(idx < 0 || idx > (SQInteger)_values.size()) - return false; - _values.insert(idx,val); - return true; - } - void ShrinkIfNeeded() { - if(_values.size() <= _values.capacity()>>2) //shrink the array - _values.shrinktofit(); - } - bool Remove(SQInteger idx){ - if(idx < 0 || idx >= (SQInteger)_values.size()) - return false; - _values.remove(idx); - ShrinkIfNeeded(); - return true; - } - void Release() - { - sq_delete(this,SQArray); - } - - SQObjectPtrVec _values; -}; -#endif //_SQARRAY_H_ +/* see copyright notice in squirrel.h */ +#ifndef _SQARRAY_H_ +#define _SQARRAY_H_ + +struct SQArray : public CHAINABLE_OBJ +{ +private: + SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);} + ~SQArray() + { + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); + } +public: + static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){ + SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray)); + new (newarray) SQArray(ss,nInitialSize); + return newarray; + } +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + SQObjectType GetType() {return OT_ARRAY;} +#endif + void Finalize(){ + _values.resize(0); + } + bool Get(const SQInteger nidx,SQObjectPtr &val) + { + if(nidx>=0 && nidx<(SQInteger)_values.size()){ + SQObjectPtr &o = _values[nidx]; + val = _realval(o); + return true; + } + else return false; + } + bool Set(const SQInteger nidx,const SQObjectPtr &val) + { + if(nidx>=0 && nidx<(SQInteger)_values.size()){ + _values[nidx]=val; + return true; + } + else return false; + } + SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval) + { + SQUnsignedInteger idx=TranslateIndex(refpos); + while(idx<_values.size()){ + //first found + outkey=(SQInteger)idx; + SQObjectPtr &o = _values[idx]; + outval = _realval(o); + //return idx for the next iteration + return ++idx; + } + //nothing to iterate anymore + return -1; + } + SQArray *Clone(){SQArray *anew=Create(_opt_ss(this),0); anew->_values.copy(_values); return anew; } + SQInteger Size() const {return _values.size();} + void Resize(SQInteger size) + { + SQObjectPtr _null; + Resize(size,_null); + } + void Resize(SQInteger size,SQObjectPtr &fill) { _values.resize(size,fill); ShrinkIfNeeded(); } + void Reserve(SQInteger size) { _values.reserve(size); } + void Append(const SQObject &o){_values.push_back(o);} + void Extend(const SQArray *a); + SQObjectPtr &Top(){return _values.top();} + void Pop(){_values.pop_back(); ShrinkIfNeeded(); } + bool Insert(SQInteger idx,const SQObject &val){ + if(idx < 0 || idx > (SQInteger)_values.size()) + return false; + _values.insert(idx,val); + return true; + } + void ShrinkIfNeeded() { + if(_values.size() <= _values.capacity()>>2) //shrink the array + _values.shrinktofit(); + } + bool Remove(SQInteger idx){ + if(idx < 0 || idx >= (SQInteger)_values.size()) + return false; + _values.remove(idx); + ShrinkIfNeeded(); + return true; + } + void Release() + { + sq_delete(this,SQArray); + } + + SQObjectPtrVec _values; +}; +#endif //_SQARRAY_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqbaselib.cpp b/squirrel_3_0_1_stable/squirrel/sqbaselib.cpp index 1e9ae1445..c11c4d9bd 100644 --- a/squirrel_3_0_1_stable/squirrel/sqbaselib.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqbaselib.cpp @@ -1,1110 +1,1110 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#include "sqvm.h" -#include "sqstring.h" -#include "sqtable.h" -#include "sqarray.h" -#include "sqfuncproto.h" -#include "sqclosure.h" -#include "sqclass.h" -#include -#include -#include - -bool str2num(const SQChar *s,SQObjectPtr &res) -{ - SQChar *end; - if(scstrstr(s,_SC("."))){ - SQFloat r = SQFloat(scstrtod(s,&end)); - if(s == end) return false; - res = r; - return true; - } - else{ - SQInteger r = SQInteger(scstrtol(s,&end,10)); - if(s == end) return false; - res = r; - return true; - } -} - -static SQInteger base_dummy(HSQUIRRELVM v) -{ - return 0; -} - -#ifndef NO_GARBAGE_COLLECTOR -static SQInteger base_collectgarbage(HSQUIRRELVM v) -{ - sq_pushinteger(v, sq_collectgarbage(v)); - return 1; -} -static SQInteger base_resurectureachable(HSQUIRRELVM v) -{ - sq_resurrectunreachable(v); - return 1; -} -#endif - -static SQInteger base_getroottable(HSQUIRRELVM v) -{ - v->Push(v->_roottable); - return 1; -} - -static SQInteger base_getconsttable(HSQUIRRELVM v) -{ - v->Push(_ss(v)->_consts); - return 1; -} - - -static SQInteger base_setroottable(HSQUIRRELVM v) -{ - SQObjectPtr o = v->_roottable; - if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR; - v->Push(o); - return 1; -} - -static SQInteger base_setconsttable(HSQUIRRELVM v) -{ - SQObjectPtr o = _ss(v)->_consts; - if(SQ_FAILED(sq_setconsttable(v))) return SQ_ERROR; - v->Push(o); - return 1; -} - -static SQInteger base_seterrorhandler(HSQUIRRELVM v) -{ - sq_seterrorhandler(v); - return 0; -} - -static SQInteger base_setdebughook(HSQUIRRELVM v) -{ - sq_setdebughook(v); - return 0; -} - -static SQInteger base_enabledebuginfo(HSQUIRRELVM v) -{ - SQObjectPtr &o=stack_get(v,2); - - sq_enabledebuginfo(v,SQVM::IsFalse(o)?SQFalse:SQTrue); - return 0; -} - -static SQInteger __getcallstackinfos(HSQUIRRELVM v,SQInteger level) -{ - SQStackInfos si; - SQInteger seq = 0; - const SQChar *name = NULL; - - if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si))) - { - const SQChar *fn = _SC("unknown"); - const SQChar *src = _SC("unknown"); - if(si.funcname)fn = si.funcname; - if(si.source)src = si.source; - sq_newtable(v); - sq_pushstring(v, _SC("func"), -1); - sq_pushstring(v, fn, -1); - sq_newslot(v, -3, SQFalse); - sq_pushstring(v, _SC("src"), -1); - sq_pushstring(v, src, -1); - sq_newslot(v, -3, SQFalse); - sq_pushstring(v, _SC("line"), -1); - sq_pushinteger(v, si.line); - sq_newslot(v, -3, SQFalse); - sq_pushstring(v, _SC("locals"), -1); - sq_newtable(v); - seq=0; - while ((name = sq_getlocal(v, level, seq))) { - sq_pushstring(v, name, -1); - sq_push(v, -2); - sq_newslot(v, -4, SQFalse); - sq_pop(v, 1); - seq++; - } - sq_newslot(v, -3, SQFalse); - return 1; - } - - return 0; -} -static SQInteger base_getstackinfos(HSQUIRRELVM v) -{ - SQInteger level; - sq_getinteger(v, -1, &level); - return __getcallstackinfos(v,level); -} - -static SQInteger base_assert(HSQUIRRELVM v) -{ - if(SQVM::IsFalse(stack_get(v,2))){ - return sq_throwerror(v,_SC("assertion failed")); - } - return 0; -} - -static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,SQObjectPtr &o) -{ - SQInteger top = sq_gettop(v); - sidx=0; - eidx=0; - o=stack_get(v,1); - SQObjectPtr &start=stack_get(v,2); - if(type(start)!=OT_NULL && sq_isnumeric(start)){ - sidx=tointeger(start); - } - if(top>2){ - SQObjectPtr &end=stack_get(v,3); - if(sq_isnumeric(end)){ - eidx=tointeger(end); - } - } - else { - eidx = sq_getsize(v,1); - } - return 1; -} - -static SQInteger base_print(HSQUIRRELVM v) -{ - const SQChar *str; - sq_tostring(v,2); - sq_getstring(v,-1,&str); - if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),str); - return 0; -} - -static SQInteger base_error(HSQUIRRELVM v) -{ - const SQChar *str; - sq_tostring(v,2); - sq_getstring(v,-1,&str); - if(_ss(v)->_errorfunc) _ss(v)->_errorfunc(v,_SC("%s"),str); - return 0; -} - -static SQInteger base_compilestring(HSQUIRRELVM v) -{ - SQInteger nargs=sq_gettop(v); - const SQChar *src=NULL,*name=_SC("unnamedbuffer"); - SQInteger size; - sq_getstring(v,2,&src); - size=sq_getsize(v,2); - if(nargs>2){ - sq_getstring(v,3,&name); - } - if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse))) - return 1; - else - return SQ_ERROR; -} - -static SQInteger base_newthread(HSQUIRRELVM v) -{ - SQObjectPtr &func = stack_get(v,2); - SQInteger stksize = (_closure(func)->_function->_stacksize << 1) +2; - HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize); - sq_move(newv,v,-2); - return 1; -} - -static SQInteger base_suspend(HSQUIRRELVM v) -{ - return sq_suspendvm(v); -} - -static SQInteger base_array(HSQUIRRELVM v) -{ - SQArray *a; - SQObject &size = stack_get(v,2); - if(sq_gettop(v) > 2) { - a = SQArray::Create(_ss(v),0); - a->Resize(tointeger(size),stack_get(v,3)); - } - else { - a = SQArray::Create(_ss(v),tointeger(size)); - } - v->Push(a); - return 1; -} - -static SQInteger base_type(HSQUIRRELVM v) -{ - SQObjectPtr &o = stack_get(v,2); - v->Push(SQString::Create(_ss(v),GetTypeName(o),-1)); - return 1; -} - -static SQInteger base_callee(HSQUIRRELVM v) -{ - if(v->_callsstacksize > 1) - { - v->Push(v->_callsstack[v->_callsstacksize - 2]._closure); - return 1; - } - return sq_throwerror(v,_SC("no closure in the calls stack")); -} - -static SQRegFunction base_funcs[]={ - //generic - {_SC("seterrorhandler"),base_seterrorhandler,2, NULL}, - {_SC("setdebughook"),base_setdebughook,2, NULL}, - {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL}, - {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")}, - {_SC("getroottable"),base_getroottable,1, NULL}, - {_SC("setroottable"),base_setroottable,2, NULL}, - {_SC("getconsttable"),base_getconsttable,1, NULL}, - {_SC("setconsttable"),base_setconsttable,2, NULL}, - {_SC("assert"),base_assert,2, NULL}, - {_SC("print"),base_print,2, NULL}, - {_SC("error"),base_error,2, NULL}, - {_SC("compilestring"),base_compilestring,-2, _SC(".ss")}, - {_SC("newthread"),base_newthread,2, _SC(".c")}, - {_SC("suspend"),base_suspend,-1, NULL}, - {_SC("array"),base_array,-2, _SC(".n")}, - {_SC("type"),base_type,2, NULL}, - {_SC("callee"),base_callee,0,NULL}, - {_SC("dummy"),base_dummy,0,NULL}, -#ifndef NO_GARBAGE_COLLECTOR - {_SC("collectgarbage"),base_collectgarbage,0, NULL}, - {_SC("resurrectunreachable"),base_resurectureachable,0, NULL}, -#endif - {0,0} -}; - -void sq_base_register(HSQUIRRELVM v) -{ - SQInteger i=0; - sq_pushroottable(v); - while(base_funcs[i].name!=0) { - sq_pushstring(v,base_funcs[i].name,-1); - sq_newclosure(v,base_funcs[i].f,0); - sq_setnativeclosurename(v,-1,base_funcs[i].name); - sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask); - sq_newslot(v,-3, SQFalse); - i++; - } - - sq_pushstring(v,_SC("_versionnumber_"),-1); - sq_pushinteger(v,SQUIRREL_VERSION_NUMBER); - sq_newslot(v,-3, SQFalse); - sq_pushstring(v,_SC("_version_"),-1); - sq_pushstring(v,SQUIRREL_VERSION,-1); - sq_newslot(v,-3, SQFalse); - sq_pushstring(v,_SC("_charsize_"),-1); - sq_pushinteger(v,sizeof(SQChar)); - sq_newslot(v,-3, SQFalse); - sq_pushstring(v,_SC("_intsize_"),-1); - sq_pushinteger(v,sizeof(SQInteger)); - sq_newslot(v,-3, SQFalse); - sq_pushstring(v,_SC("_floatsize_"),-1); - sq_pushinteger(v,sizeof(SQFloat)); - sq_newslot(v,-3, SQFalse); - sq_pop(v,1); -} - -static SQInteger default_delegate_len(HSQUIRRELVM v) -{ - v->Push(SQInteger(sq_getsize(v,1))); - return 1; -} - -static SQInteger default_delegate_tofloat(HSQUIRRELVM v) -{ - SQObjectPtr &o=stack_get(v,1); - switch(type(o)){ - case OT_STRING:{ - SQObjectPtr res; - if(str2num(_stringval(o),res)){ - v->Push(SQObjectPtr(tofloat(res))); - break; - }} - return sq_throwerror(v, _SC("cannot convert the string")); - break; - case OT_INTEGER:case OT_FLOAT: - v->Push(SQObjectPtr(tofloat(o))); - break; - case OT_BOOL: - v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0))); - break; - default: - v->PushNull(); - break; - } - return 1; -} - -static SQInteger default_delegate_tointeger(HSQUIRRELVM v) -{ - SQObjectPtr &o=stack_get(v,1); - switch(type(o)){ - case OT_STRING:{ - SQObjectPtr res; - if(str2num(_stringval(o),res)){ - v->Push(SQObjectPtr(tointeger(res))); - break; - }} - return sq_throwerror(v, _SC("cannot convert the string")); - break; - case OT_INTEGER:case OT_FLOAT: - v->Push(SQObjectPtr(tointeger(o))); - break; - case OT_BOOL: - v->Push(SQObjectPtr(_integer(o)?(SQInteger)1:(SQInteger)0)); - break; - default: - v->PushNull(); - break; - } - return 1; -} - -static SQInteger default_delegate_tostring(HSQUIRRELVM v) -{ - sq_tostring(v,1); - return 1; -} - -static SQInteger obj_delegate_weakref(HSQUIRRELVM v) -{ - sq_weakref(v,1); - return 1; -} - -static SQInteger obj_clear(HSQUIRRELVM v) -{ - return sq_clear(v,-1); -} - - -static SQInteger number_delegate_tochar(HSQUIRRELVM v) -{ - SQObject &o=stack_get(v,1); - SQChar c = (SQChar)tointeger(o); - v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1)); - return 1; -} - - - -///////////////////////////////////////////////////////////////// -//TABLE DEFAULT DELEGATE - -static SQInteger table_rawdelete(HSQUIRRELVM v) -{ - if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue))) - return SQ_ERROR; - return 1; -} - - -static SQInteger container_rawexists(HSQUIRRELVM v) -{ - if(SQ_SUCCEEDED(sq_rawget(v,-2))) { - sq_pushbool(v,SQTrue); - return 1; - } - sq_pushbool(v,SQFalse); - return 1; -} - -static SQInteger container_rawset(HSQUIRRELVM v) -{ - return sq_rawset(v,-3); -} - - -static SQInteger container_rawget(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR; -} - -static SQInteger table_setdelegate(HSQUIRRELVM v) -{ - if(SQ_FAILED(sq_setdelegate(v,-2))) - return SQ_ERROR; - sq_push(v,-1); // -1 because sq_setdelegate pops 1 - return 1; -} - -static SQInteger table_getdelegate(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_getdelegate(v,-1))?1:SQ_ERROR; -} - -SQRegFunction SQSharedState::_table_default_delegate_funcz[]={ - {_SC("len"),default_delegate_len,1, _SC("t")}, - {_SC("rawget"),container_rawget,2, _SC("t")}, - {_SC("rawset"),container_rawset,3, _SC("t")}, - {_SC("rawdelete"),table_rawdelete,2, _SC("t")}, - {_SC("rawin"),container_rawexists,2, _SC("t")}, - {_SC("weakref"),obj_delegate_weakref,1, NULL }, - {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, - {_SC("clear"),obj_clear,1, _SC(".")}, - {_SC("setdelegate"),table_setdelegate,2, _SC(".t|o")}, - {_SC("getdelegate"),table_getdelegate,1, _SC(".")}, - {0,0} -}; - -//ARRAY DEFAULT DELEGATE/////////////////////////////////////// - -static SQInteger array_append(HSQUIRRELVM v) -{ - return sq_arrayappend(v,-2); -} - -static SQInteger array_extend(HSQUIRRELVM v) -{ - _array(stack_get(v,1))->Extend(_array(stack_get(v,2))); - return 0; -} - -static SQInteger array_reverse(HSQUIRRELVM v) -{ - return sq_arrayreverse(v,-1); -} - -static SQInteger array_pop(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR; -} - -static SQInteger array_top(HSQUIRRELVM v) -{ - SQObject &o=stack_get(v,1); - if(_array(o)->Size()>0){ - v->Push(_array(o)->Top()); - return 1; - } - else return sq_throwerror(v,_SC("top() on a empty array")); -} - -static SQInteger array_insert(HSQUIRRELVM v) -{ - SQObject &o=stack_get(v,1); - SQObject &idx=stack_get(v,2); - SQObject &val=stack_get(v,3); - if(!_array(o)->Insert(tointeger(idx),val)) - return sq_throwerror(v,_SC("index out of range")); - return 0; -} - -static SQInteger array_remove(HSQUIRRELVM v) -{ - SQObject &o = stack_get(v, 1); - SQObject &idx = stack_get(v, 2); - if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type")); - SQObjectPtr val; - if(_array(o)->Get(tointeger(idx), val)) { - _array(o)->Remove(tointeger(idx)); - v->Push(val); - return 1; - } - return sq_throwerror(v, _SC("idx out of range")); -} - -static SQInteger array_resize(HSQUIRRELVM v) -{ - SQObject &o = stack_get(v, 1); - SQObject &nsize = stack_get(v, 2); - SQObjectPtr fill; - if(sq_isnumeric(nsize)) { - if(sq_gettop(v) > 2) - fill = stack_get(v, 3); - _array(o)->Resize(tointeger(nsize),fill); - return 0; - } - return sq_throwerror(v, _SC("size must be a number")); -} - -static SQInteger __map_array(SQArray *dest,SQArray *src,HSQUIRRELVM v) { - SQObjectPtr temp; - SQInteger size = src->Size(); - for(SQInteger n = 0; n < size; n++) { - src->Get(n,temp); - v->Push(src); - v->Push(temp); - if(SQ_FAILED(sq_call(v,2,SQTrue,SQFalse))) { - return SQ_ERROR; - } - dest->Set(n,v->GetUp(-1)); - v->Pop(); - } - return 0; -} - -static SQInteger array_map(HSQUIRRELVM v) -{ - SQObject &o = stack_get(v,1); - SQInteger size = _array(o)->Size(); - SQObjectPtr ret = SQArray::Create(_ss(v),size); - if(SQ_FAILED(__map_array(_array(ret),_array(o),v))) - return SQ_ERROR; - v->Push(ret); - return 1; -} - -static SQInteger array_apply(HSQUIRRELVM v) -{ - SQObject &o = stack_get(v,1); - if(SQ_FAILED(__map_array(_array(o),_array(o),v))) - return SQ_ERROR; - return 0; -} - -static SQInteger array_reduce(HSQUIRRELVM v) -{ - SQObject &o = stack_get(v,1); - SQArray *a = _array(o); - SQInteger size = a->Size(); - if(size == 0) { - return 0; - } - SQObjectPtr res; - a->Get(0,res); - if(size > 1) { - SQObjectPtr other; - for(SQInteger n = 1; n < size; n++) { - a->Get(n,other); - v->Push(o); - v->Push(res); - v->Push(other); - if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) { - return SQ_ERROR; - } - res = v->GetUp(-1); - v->Pop(); - } - } - v->Push(res); - return 1; -} - -static SQInteger array_filter(HSQUIRRELVM v) -{ - SQObject &o = stack_get(v,1); - SQArray *a = _array(o); - SQObjectPtr ret = SQArray::Create(_ss(v),0); - SQInteger size = a->Size(); - SQObjectPtr val; - for(SQInteger n = 0; n < size; n++) { - a->Get(n,val); - v->Push(o); - v->Push(n); - v->Push(val); - if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) { - return SQ_ERROR; - } - if(!SQVM::IsFalse(v->GetUp(-1))) { - _array(ret)->Append(val); - } - v->Pop(); - } - v->Push(ret); - return 1; -} - -static SQInteger array_find(HSQUIRRELVM v) -{ - SQObject &o = stack_get(v,1); - SQObjectPtr &val = stack_get(v,2); - SQArray *a = _array(o); - SQInteger size = a->Size(); - SQObjectPtr temp; - for(SQInteger n = 0; n < size; n++) { - bool res = false; - a->Get(n,temp); - if(SQVM::IsEqual(temp,val,res) && res) { - v->Push(n); - return 1; - } - } - return 0; -} - -//QSORT ala Sedgewick -bool _qsort_compare(HSQUIRRELVM v,SQObjectPtr &arr,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret) -{ - if(func < 0) { - if(!v->ObjCmp(a,b,ret)) return false; - } - else { - SQInteger top = sq_gettop(v); - sq_push(v, func); - sq_pushroottable(v); - v->Push(a); - v->Push(b); - if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) { - if(!sq_isstring( v->_lasterror)) - v->Raise_Error(_SC("compare func failed")); - return false; - } - sq_getinteger(v, -1, &ret); - sq_settop(v, top); - return true; - } - return true; -} -//QSORT ala Sedgewick -bool _qsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger func) -{ - SQInteger i, j; - SQArray *a=_array(arr); - SQObjectPtr pivot,t; - if( l < r ){ - pivot = a->_values[l]; - i = l; j = r+1; - while(1){ - SQInteger ret; - do { - ++i; - if(i > r) break; - if(!_qsort_compare(v,arr,a->_values[i],pivot,func,ret)) - return false; - } while( ret <= 0); - do { - --j; - if ( j < 0 ) { - v->Raise_Error( _SC("Invalid qsort, probably compare function defect") ); - return false; - } - if(!_qsort_compare(v,arr,a->_values[j],pivot,func,ret)) - return false; - } - while( ret > 0 ); - if( i >= j ) break; - t = a->_values[i]; a->_values[i] = a->_values[j]; a->_values[j] = t; - } - t = a->_values[l]; a->_values[l] = a->_values[j]; a->_values[j] = t; - if(!_qsort( v, arr, l, j-1,func)) return false; - if(!_qsort( v, arr, j+1, r,func)) return false; - } - return true; -} - -static SQInteger array_sort(HSQUIRRELVM v) -{ - SQInteger func = -1; - SQObjectPtr &o = stack_get(v,1); - //SQObject &funcobj = stack_get(v,2); - if(_array(o)->Size() > 1) { - if(sq_gettop(v) == 2 /*&& type(funcobj) == OT_CLOSURE || type(funcobj) == OT_NATIVECLOSURE*/) func = 2; - if(!_qsort(v, o, 0, _array(o)->Size()-1, func)) - return SQ_ERROR; - - } - return 0; -} -static SQInteger array_slice(HSQUIRRELVM v) -{ - SQInteger sidx,eidx; - SQObjectPtr o; - if(get_slice_params(v,sidx,eidx,o)==-1)return -1; - SQInteger alen = _array(o)->Size(); - if(sidx < 0)sidx = alen + sidx; - if(eidx < 0)eidx = alen + eidx; - if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes")); - if(eidx > alen)return sq_throwerror(v,_SC("slice out of range")); - SQArray *arr=SQArray::Create(_ss(v),eidx-sidx); - SQObjectPtr t; - SQInteger count=0; - for(SQInteger i=sidx;iGet(i,t); - arr->Set(count++,t); - } - v->Push(arr); - return 1; - -} - -SQRegFunction SQSharedState::_array_default_delegate_funcz[]={ - {_SC("len"),default_delegate_len,1, _SC("a")}, - {_SC("append"),array_append,2, _SC("a")}, - {_SC("extend"),array_extend,2, _SC("aa")}, - {_SC("push"),array_append,2, _SC("a")}, - {_SC("pop"),array_pop,1, _SC("a")}, - {_SC("top"),array_top,1, _SC("a")}, - {_SC("insert"),array_insert,3, _SC("an")}, - {_SC("remove"),array_remove,2, _SC("an")}, - {_SC("resize"),array_resize,-2, _SC("an")}, - {_SC("reverse"),array_reverse,1, _SC("a")}, - {_SC("sort"),array_sort,-1, _SC("ac")}, - {_SC("slice"),array_slice,-1, _SC("ann")}, - {_SC("weakref"),obj_delegate_weakref,1, NULL }, - {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, - {_SC("clear"),obj_clear,1, _SC(".")}, - {_SC("map"),array_map,2, _SC("ac")}, - {_SC("apply"),array_apply,2, _SC("ac")}, - {_SC("reduce"),array_reduce,2, _SC("ac")}, - {_SC("filter"),array_filter,2, _SC("ac")}, - {_SC("find"),array_find,2, _SC("a.")}, - {0,0} -}; - -//STRING DEFAULT DELEGATE////////////////////////// -static SQInteger string_slice(HSQUIRRELVM v) -{ - SQInteger sidx,eidx; - SQObjectPtr o; - if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1; - SQInteger slen = _string(o)->_len; - if(sidx < 0)sidx = slen + sidx; - if(eidx < 0)eidx = slen + eidx; - if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes")); - if(eidx > slen) return sq_throwerror(v,_SC("slice out of range")); - v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx)); - return 1; -} - -static SQInteger string_find(HSQUIRRELVM v) -{ - SQInteger top,start_idx=0; - const SQChar *str,*substr,*ret; - if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){ - if(top>2)sq_getinteger(v,3,&start_idx); - if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){ - ret=scstrstr(&str[start_idx],substr); - if(ret){ - sq_pushinteger(v,(SQInteger)(ret-str)); - return 1; - } - } - return 0; - } - return sq_throwerror(v,_SC("invalid param")); -} - -#define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \ -{ \ - SQObject str=stack_get(v,1); \ - SQInteger len=_string(str)->_len; \ - const SQChar *sThis=_stringval(str); \ - SQChar *sNew=(_ss(v)->GetScratchPad(rsl(len))); \ - for(SQInteger i=0;iPush(SQString::Create(_ss(v),sNew,len)); \ - return 1; \ -} - - -STRING_TOFUNCZ(tolower) -STRING_TOFUNCZ(toupper) - -SQRegFunction SQSharedState::_string_default_delegate_funcz[]={ - {_SC("len"),default_delegate_len,1, _SC("s")}, - {_SC("tointeger"),default_delegate_tointeger,1, _SC("s")}, - {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")}, - {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, - {_SC("slice"),string_slice,-1, _SC(" s n n")}, - {_SC("find"),string_find,-2, _SC("s s n ")}, - {_SC("tolower"),string_tolower,1, _SC("s")}, - {_SC("toupper"),string_toupper,1, _SC("s")}, - {_SC("weakref"),obj_delegate_weakref,1, NULL }, - {0,0} -}; - -//INTEGER DEFAULT DELEGATE////////////////////////// -SQRegFunction SQSharedState::_number_default_delegate_funcz[]={ - {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")}, - {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")}, - {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, - {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")}, - {_SC("weakref"),obj_delegate_weakref,1, NULL }, - {0,0} -}; - -//CLOSURE DEFAULT DELEGATE////////////////////////// -static SQInteger closure_pcall(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQFalse))?1:SQ_ERROR; -} - -static SQInteger closure_call(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQTrue))?1:SQ_ERROR; -} - -static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror) -{ - SQArray *aparams=_array(stack_get(v,2)); - SQInteger nparams=aparams->Size(); - v->Push(stack_get(v,1)); - for(SQInteger i=0;iPush(aparams->_values[i]); - return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR; -} - -static SQInteger closure_acall(HSQUIRRELVM v) -{ - return _closure_acall(v,SQTrue); -} - -static SQInteger closure_pacall(HSQUIRRELVM v) -{ - return _closure_acall(v,SQFalse); -} - -static SQInteger closure_bindenv(HSQUIRRELVM v) -{ - if(SQ_FAILED(sq_bindenv(v,1))) - return SQ_ERROR; - return 1; -} - -static SQInteger closure_getinfos(HSQUIRRELVM v) { - SQObject o = stack_get(v,1); - SQTable *res = SQTable::Create(_ss(v),4); - if(type(o) == OT_CLOSURE) { - SQFunctionProto *f = _closure(o)->_function; - SQInteger nparams = f->_nparameters + (f->_varparams?1:0); - SQObjectPtr params = SQArray::Create(_ss(v),nparams); - for(SQInteger n = 0; n_nparameters; n++) { - _array(params)->Set((SQInteger)n,f->_parameters[n]); - } - if(f->_varparams) { - _array(params)->Set(nparams-1,SQString::Create(_ss(v),_SC("..."),-1)); - } - res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),false); - res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),f->_name); - res->NewSlot(SQString::Create(_ss(v),_SC("src"),-1),f->_sourcename); - res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params); - res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams); - } - else { //OT_NATIVECLOSURE - SQNativeClosure *nc = _nativeclosure(o); - res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true); - res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name); - res->NewSlot(SQString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck); - SQObjectPtr typecheck; - if(nc->_typecheck.size() > 0) { - typecheck = - SQArray::Create(_ss(v), nc->_typecheck.size()); - for(SQUnsignedInteger n = 0; n_typecheck.size(); n++) { - _array(typecheck)->Set((SQInteger)n,nc->_typecheck[n]); - } - } - res->NewSlot(SQString::Create(_ss(v),_SC("typecheck"),-1),typecheck); - } - v->Push(res); - return 1; -} - - -SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={ - {_SC("call"),closure_call,-1, _SC("c")}, - {_SC("pcall"),closure_pcall,-1, _SC("c")}, - {_SC("acall"),closure_acall,2, _SC("ca")}, - {_SC("pacall"),closure_pacall,2, _SC("ca")}, - {_SC("weakref"),obj_delegate_weakref,1, NULL }, - {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, - {_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")}, - {_SC("getinfos"),closure_getinfos,1, _SC("c")}, - {0,0} -}; - -//GENERATOR DEFAULT DELEGATE -static SQInteger generator_getstatus(HSQUIRRELVM v) -{ - SQObject &o=stack_get(v,1); - switch(_generator(o)->_state){ - case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break; - case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break; - case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break; - } - return 1; -} - -SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={ - {_SC("getstatus"),generator_getstatus,1, _SC("g")}, - {_SC("weakref"),obj_delegate_weakref,1, NULL }, - {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, - {0,0} -}; - -//THREAD DEFAULT DELEGATE -static SQInteger thread_call(HSQUIRRELVM v) -{ - SQObjectPtr o = stack_get(v,1); - if(type(o) == OT_THREAD) { - SQInteger nparams = sq_gettop(v); - _thread(o)->Push(_thread(o)->_roottable); - for(SQInteger i = 2; i<(nparams+1); i++) - sq_move(_thread(o),v,i); - if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQFalse))) { - sq_move(v,_thread(o),-1); - sq_pop(_thread(o),1); - return 1; - } - v->_lasterror = _thread(o)->_lasterror; - return SQ_ERROR; - } - return sq_throwerror(v,_SC("wrong parameter")); -} - -static SQInteger thread_wakeup(HSQUIRRELVM v) -{ - SQObjectPtr o = stack_get(v,1); - if(type(o) == OT_THREAD) { - SQVM *thread = _thread(o); - SQInteger state = sq_getvmstate(thread); - if(state != SQ_VMSTATE_SUSPENDED) { - switch(state) { - case SQ_VMSTATE_IDLE: - return sq_throwerror(v,_SC("cannot wakeup a idle thread")); - break; - case SQ_VMSTATE_RUNNING: - return sq_throwerror(v,_SC("cannot wakeup a running thread")); - break; - } - } - - SQInteger wakeupret = sq_gettop(v)>1?1:0; - if(wakeupret) { - sq_move(thread,v,2); - } - if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,SQTrue,SQTrue,SQFalse))) { - sq_move(v,thread,-1); - sq_pop(thread,1); //pop retval - if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) { - sq_settop(thread,1); //pop roottable - } - return 1; - } - sq_settop(thread,1); - v->_lasterror = thread->_lasterror; - return SQ_ERROR; - } - return sq_throwerror(v,_SC("wrong parameter")); -} - -static SQInteger thread_getstatus(HSQUIRRELVM v) -{ - SQObjectPtr &o = stack_get(v,1); - switch(sq_getvmstate(_thread(o))) { - case SQ_VMSTATE_IDLE: - sq_pushstring(v,_SC("idle"),-1); - break; - case SQ_VMSTATE_RUNNING: - sq_pushstring(v,_SC("running"),-1); - break; - case SQ_VMSTATE_SUSPENDED: - sq_pushstring(v,_SC("suspended"),-1); - break; - default: - return sq_throwerror(v,_SC("internal VM error")); - } - return 1; -} - -static SQInteger thread_getstackinfos(HSQUIRRELVM v) -{ - SQObjectPtr o = stack_get(v,1); - if(type(o) == OT_THREAD) { - SQVM *thread = _thread(o); - SQInteger threadtop = sq_gettop(thread); - SQInteger level; - sq_getinteger(v,-1,&level); - SQRESULT res = __getcallstackinfos(thread,level); - if(SQ_FAILED(res)) - { - sq_settop(thread,threadtop); - if(type(thread->_lasterror) == OT_STRING) { - sq_throwerror(v,_stringval(thread->_lasterror)); - } - else { - sq_throwerror(v,_SC("unknown error")); - } - } - if(res > 0) { - //some result - sq_move(v,thread,-1); - sq_settop(thread,threadtop); - return 1; - } - //no result - sq_settop(thread,threadtop); - return 0; - - } - return sq_throwerror(v,_SC("wrong parameter")); -} - -SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = { - {_SC("call"), thread_call, -1, _SC("v")}, - {_SC("wakeup"), thread_wakeup, -1, _SC("v")}, - {_SC("getstatus"), thread_getstatus, 1, _SC("v")}, - {_SC("weakref"),obj_delegate_weakref,1, NULL }, - {_SC("getstackinfos"),thread_getstackinfos,2, _SC("vn")}, - {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, - {0,0}, -}; - -static SQInteger class_getattributes(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_getattributes(v,-2))?1:SQ_ERROR; -} - -static SQInteger class_setattributes(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_setattributes(v,-3))?1:SQ_ERROR; -} - -static SQInteger class_instance(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_createinstance(v,-1))?1:SQ_ERROR; -} - -static SQInteger class_getbase(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_getbase(v,-1))?1:SQ_ERROR; -} - -SQRegFunction SQSharedState::_class_default_delegate_funcz[] = { - {_SC("getattributes"), class_getattributes, 2, _SC("y.")}, - {_SC("setattributes"), class_setattributes, 3, _SC("y..")}, - {_SC("rawget"),container_rawget,2, _SC("y")}, - {_SC("rawset"),container_rawset,3, _SC("y")}, - {_SC("rawin"),container_rawexists,2, _SC("y")}, - {_SC("weakref"),obj_delegate_weakref,1, NULL }, - {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, - {_SC("instance"),class_instance,1, _SC("y")}, - {_SC("getbase"),class_getbase,1, _SC("y")}, - {0,0} -}; - -static SQInteger instance_getclass(HSQUIRRELVM v) -{ - if(SQ_SUCCEEDED(sq_getclass(v,1))) - return 1; - return SQ_ERROR; -} - -SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = { - {_SC("getclass"), instance_getclass, 1, _SC("x")}, - {_SC("rawget"),container_rawget,2, _SC("x")}, - {_SC("rawset"),container_rawset,3, _SC("x")}, - {_SC("rawin"),container_rawexists,2, _SC("x")}, - {_SC("weakref"),obj_delegate_weakref,1, NULL }, - {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, - {0,0} -}; - -static SQInteger weakref_ref(HSQUIRRELVM v) -{ - if(SQ_FAILED(sq_getweakrefval(v,1))) - return SQ_ERROR; - return 1; -} - -SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = { - {_SC("ref"),weakref_ref,1, _SC("r")}, - {_SC("weakref"),obj_delegate_weakref,1, NULL }, - {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, - {0,0} -}; - +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqstring.h" +#include "sqtable.h" +#include "sqarray.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "sqclass.h" +#include +#include +#include + +bool str2num(const SQChar *s,SQObjectPtr &res) +{ + SQChar *end; + if(scstrstr(s,_SC("."))){ + SQFloat r = SQFloat(scstrtod(s,&end)); + if(s == end) return false; + res = r; + return true; + } + else{ + SQInteger r = SQInteger(scstrtol(s,&end,10)); + if(s == end) return false; + res = r; + return true; + } +} + +static SQInteger base_dummy(HSQUIRRELVM v) +{ + return 0; +} + +#ifndef NO_GARBAGE_COLLECTOR +static SQInteger base_collectgarbage(HSQUIRRELVM v) +{ + sq_pushinteger(v, sq_collectgarbage(v)); + return 1; +} +static SQInteger base_resurectureachable(HSQUIRRELVM v) +{ + sq_resurrectunreachable(v); + return 1; +} +#endif + +static SQInteger base_getroottable(HSQUIRRELVM v) +{ + v->Push(v->_roottable); + return 1; +} + +static SQInteger base_getconsttable(HSQUIRRELVM v) +{ + v->Push(_ss(v)->_consts); + return 1; +} + + +static SQInteger base_setroottable(HSQUIRRELVM v) +{ + SQObjectPtr o = v->_roottable; + if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR; + v->Push(o); + return 1; +} + +static SQInteger base_setconsttable(HSQUIRRELVM v) +{ + SQObjectPtr o = _ss(v)->_consts; + if(SQ_FAILED(sq_setconsttable(v))) return SQ_ERROR; + v->Push(o); + return 1; +} + +static SQInteger base_seterrorhandler(HSQUIRRELVM v) +{ + sq_seterrorhandler(v); + return 0; +} + +static SQInteger base_setdebughook(HSQUIRRELVM v) +{ + sq_setdebughook(v); + return 0; +} + +static SQInteger base_enabledebuginfo(HSQUIRRELVM v) +{ + SQObjectPtr &o=stack_get(v,2); + + sq_enabledebuginfo(v,SQVM::IsFalse(o)?SQFalse:SQTrue); + return 0; +} + +static SQInteger __getcallstackinfos(HSQUIRRELVM v,SQInteger level) +{ + SQStackInfos si; + SQInteger seq = 0; + const SQChar *name = NULL; + + if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si))) + { + const SQChar *fn = _SC("unknown"); + const SQChar *src = _SC("unknown"); + if(si.funcname)fn = si.funcname; + if(si.source)src = si.source; + sq_newtable(v); + sq_pushstring(v, _SC("func"), -1); + sq_pushstring(v, fn, -1); + sq_newslot(v, -3, SQFalse); + sq_pushstring(v, _SC("src"), -1); + sq_pushstring(v, src, -1); + sq_newslot(v, -3, SQFalse); + sq_pushstring(v, _SC("line"), -1); + sq_pushinteger(v, si.line); + sq_newslot(v, -3, SQFalse); + sq_pushstring(v, _SC("locals"), -1); + sq_newtable(v); + seq=0; + while ((name = sq_getlocal(v, level, seq))) { + sq_pushstring(v, name, -1); + sq_push(v, -2); + sq_newslot(v, -4, SQFalse); + sq_pop(v, 1); + seq++; + } + sq_newslot(v, -3, SQFalse); + return 1; + } + + return 0; +} +static SQInteger base_getstackinfos(HSQUIRRELVM v) +{ + SQInteger level; + sq_getinteger(v, -1, &level); + return __getcallstackinfos(v,level); +} + +static SQInteger base_assert(HSQUIRRELVM v) +{ + if(SQVM::IsFalse(stack_get(v,2))){ + return sq_throwerror(v,_SC("assertion failed")); + } + return 0; +} + +static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,SQObjectPtr &o) +{ + SQInteger top = sq_gettop(v); + sidx=0; + eidx=0; + o=stack_get(v,1); + SQObjectPtr &start=stack_get(v,2); + if(type(start)!=OT_NULL && sq_isnumeric(start)){ + sidx=tointeger(start); + } + if(top>2){ + SQObjectPtr &end=stack_get(v,3); + if(sq_isnumeric(end)){ + eidx=tointeger(end); + } + } + else { + eidx = sq_getsize(v,1); + } + return 1; +} + +static SQInteger base_print(HSQUIRRELVM v) +{ + const SQChar *str; + sq_tostring(v,2); + sq_getstring(v,-1,&str); + if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),str); + return 0; +} + +static SQInteger base_error(HSQUIRRELVM v) +{ + const SQChar *str; + sq_tostring(v,2); + sq_getstring(v,-1,&str); + if(_ss(v)->_errorfunc) _ss(v)->_errorfunc(v,_SC("%s"),str); + return 0; +} + +static SQInteger base_compilestring(HSQUIRRELVM v) +{ + SQInteger nargs=sq_gettop(v); + const SQChar *src=NULL,*name=_SC("unnamedbuffer"); + SQInteger size; + sq_getstring(v,2,&src); + size=sq_getsize(v,2); + if(nargs>2){ + sq_getstring(v,3,&name); + } + if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse))) + return 1; + else + return SQ_ERROR; +} + +static SQInteger base_newthread(HSQUIRRELVM v) +{ + SQObjectPtr &func = stack_get(v,2); + SQInteger stksize = (_closure(func)->_function->_stacksize << 1) +2; + HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize); + sq_move(newv,v,-2); + return 1; +} + +static SQInteger base_suspend(HSQUIRRELVM v) +{ + return sq_suspendvm(v); +} + +static SQInteger base_array(HSQUIRRELVM v) +{ + SQArray *a; + SQObject &size = stack_get(v,2); + if(sq_gettop(v) > 2) { + a = SQArray::Create(_ss(v),0); + a->Resize(tointeger(size),stack_get(v,3)); + } + else { + a = SQArray::Create(_ss(v),tointeger(size)); + } + v->Push(a); + return 1; +} + +static SQInteger base_type(HSQUIRRELVM v) +{ + SQObjectPtr &o = stack_get(v,2); + v->Push(SQString::Create(_ss(v),GetTypeName(o),-1)); + return 1; +} + +static SQInteger base_callee(HSQUIRRELVM v) +{ + if(v->_callsstacksize > 1) + { + v->Push(v->_callsstack[v->_callsstacksize - 2]._closure); + return 1; + } + return sq_throwerror(v,_SC("no closure in the calls stack")); +} + +static SQRegFunction base_funcs[]={ + //generic + {_SC("seterrorhandler"),base_seterrorhandler,2, NULL}, + {_SC("setdebughook"),base_setdebughook,2, NULL}, + {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL}, + {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")}, + {_SC("getroottable"),base_getroottable,1, NULL}, + {_SC("setroottable"),base_setroottable,2, NULL}, + {_SC("getconsttable"),base_getconsttable,1, NULL}, + {_SC("setconsttable"),base_setconsttable,2, NULL}, + {_SC("assert"),base_assert,2, NULL}, + {_SC("print"),base_print,2, NULL}, + {_SC("error"),base_error,2, NULL}, + {_SC("compilestring"),base_compilestring,-2, _SC(".ss")}, + {_SC("newthread"),base_newthread,2, _SC(".c")}, + {_SC("suspend"),base_suspend,-1, NULL}, + {_SC("array"),base_array,-2, _SC(".n")}, + {_SC("type"),base_type,2, NULL}, + {_SC("callee"),base_callee,0,NULL}, + {_SC("dummy"),base_dummy,0,NULL}, +#ifndef NO_GARBAGE_COLLECTOR + {_SC("collectgarbage"),base_collectgarbage,0, NULL}, + {_SC("resurrectunreachable"),base_resurectureachable,0, NULL}, +#endif + {0,0} +}; + +void sq_base_register(HSQUIRRELVM v) +{ + SQInteger i=0; + sq_pushroottable(v); + while(base_funcs[i].name!=0) { + sq_pushstring(v,base_funcs[i].name,-1); + sq_newclosure(v,base_funcs[i].f,0); + sq_setnativeclosurename(v,-1,base_funcs[i].name); + sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask); + sq_newslot(v,-3, SQFalse); + i++; + } + + sq_pushstring(v,_SC("_versionnumber_"),-1); + sq_pushinteger(v,SQUIRREL_VERSION_NUMBER); + sq_newslot(v,-3, SQFalse); + sq_pushstring(v,_SC("_version_"),-1); + sq_pushstring(v,SQUIRREL_VERSION,-1); + sq_newslot(v,-3, SQFalse); + sq_pushstring(v,_SC("_charsize_"),-1); + sq_pushinteger(v,sizeof(SQChar)); + sq_newslot(v,-3, SQFalse); + sq_pushstring(v,_SC("_intsize_"),-1); + sq_pushinteger(v,sizeof(SQInteger)); + sq_newslot(v,-3, SQFalse); + sq_pushstring(v,_SC("_floatsize_"),-1); + sq_pushinteger(v,sizeof(SQFloat)); + sq_newslot(v,-3, SQFalse); + sq_pop(v,1); +} + +static SQInteger default_delegate_len(HSQUIRRELVM v) +{ + v->Push(SQInteger(sq_getsize(v,1))); + return 1; +} + +static SQInteger default_delegate_tofloat(HSQUIRRELVM v) +{ + SQObjectPtr &o=stack_get(v,1); + switch(type(o)){ + case OT_STRING:{ + SQObjectPtr res; + if(str2num(_stringval(o),res)){ + v->Push(SQObjectPtr(tofloat(res))); + break; + }} + return sq_throwerror(v, _SC("cannot convert the string")); + break; + case OT_INTEGER:case OT_FLOAT: + v->Push(SQObjectPtr(tofloat(o))); + break; + case OT_BOOL: + v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0))); + break; + default: + v->PushNull(); + break; + } + return 1; +} + +static SQInteger default_delegate_tointeger(HSQUIRRELVM v) +{ + SQObjectPtr &o=stack_get(v,1); + switch(type(o)){ + case OT_STRING:{ + SQObjectPtr res; + if(str2num(_stringval(o),res)){ + v->Push(SQObjectPtr(tointeger(res))); + break; + }} + return sq_throwerror(v, _SC("cannot convert the string")); + break; + case OT_INTEGER:case OT_FLOAT: + v->Push(SQObjectPtr(tointeger(o))); + break; + case OT_BOOL: + v->Push(SQObjectPtr(_integer(o)?(SQInteger)1:(SQInteger)0)); + break; + default: + v->PushNull(); + break; + } + return 1; +} + +static SQInteger default_delegate_tostring(HSQUIRRELVM v) +{ + sq_tostring(v,1); + return 1; +} + +static SQInteger obj_delegate_weakref(HSQUIRRELVM v) +{ + sq_weakref(v,1); + return 1; +} + +static SQInteger obj_clear(HSQUIRRELVM v) +{ + return sq_clear(v,-1); +} + + +static SQInteger number_delegate_tochar(HSQUIRRELVM v) +{ + SQObject &o=stack_get(v,1); + SQChar c = (SQChar)tointeger(o); + v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1)); + return 1; +} + + + +///////////////////////////////////////////////////////////////// +//TABLE DEFAULT DELEGATE + +static SQInteger table_rawdelete(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue))) + return SQ_ERROR; + return 1; +} + + +static SQInteger container_rawexists(HSQUIRRELVM v) +{ + if(SQ_SUCCEEDED(sq_rawget(v,-2))) { + sq_pushbool(v,SQTrue); + return 1; + } + sq_pushbool(v,SQFalse); + return 1; +} + +static SQInteger container_rawset(HSQUIRRELVM v) +{ + return sq_rawset(v,-3); +} + + +static SQInteger container_rawget(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR; +} + +static SQInteger table_setdelegate(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_setdelegate(v,-2))) + return SQ_ERROR; + sq_push(v,-1); // -1 because sq_setdelegate pops 1 + return 1; +} + +static SQInteger table_getdelegate(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_getdelegate(v,-1))?1:SQ_ERROR; +} + +SQRegFunction SQSharedState::_table_default_delegate_funcz[]={ + {_SC("len"),default_delegate_len,1, _SC("t")}, + {_SC("rawget"),container_rawget,2, _SC("t")}, + {_SC("rawset"),container_rawset,3, _SC("t")}, + {_SC("rawdelete"),table_rawdelete,2, _SC("t")}, + {_SC("rawin"),container_rawexists,2, _SC("t")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("clear"),obj_clear,1, _SC(".")}, + {_SC("setdelegate"),table_setdelegate,2, _SC(".t|o")}, + {_SC("getdelegate"),table_getdelegate,1, _SC(".")}, + {0,0} +}; + +//ARRAY DEFAULT DELEGATE/////////////////////////////////////// + +static SQInteger array_append(HSQUIRRELVM v) +{ + return sq_arrayappend(v,-2); +} + +static SQInteger array_extend(HSQUIRRELVM v) +{ + _array(stack_get(v,1))->Extend(_array(stack_get(v,2))); + return 0; +} + +static SQInteger array_reverse(HSQUIRRELVM v) +{ + return sq_arrayreverse(v,-1); +} + +static SQInteger array_pop(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR; +} + +static SQInteger array_top(HSQUIRRELVM v) +{ + SQObject &o=stack_get(v,1); + if(_array(o)->Size()>0){ + v->Push(_array(o)->Top()); + return 1; + } + else return sq_throwerror(v,_SC("top() on a empty array")); +} + +static SQInteger array_insert(HSQUIRRELVM v) +{ + SQObject &o=stack_get(v,1); + SQObject &idx=stack_get(v,2); + SQObject &val=stack_get(v,3); + if(!_array(o)->Insert(tointeger(idx),val)) + return sq_throwerror(v,_SC("index out of range")); + return 0; +} + +static SQInteger array_remove(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v, 1); + SQObject &idx = stack_get(v, 2); + if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type")); + SQObjectPtr val; + if(_array(o)->Get(tointeger(idx), val)) { + _array(o)->Remove(tointeger(idx)); + v->Push(val); + return 1; + } + return sq_throwerror(v, _SC("idx out of range")); +} + +static SQInteger array_resize(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v, 1); + SQObject &nsize = stack_get(v, 2); + SQObjectPtr fill; + if(sq_isnumeric(nsize)) { + if(sq_gettop(v) > 2) + fill = stack_get(v, 3); + _array(o)->Resize(tointeger(nsize),fill); + return 0; + } + return sq_throwerror(v, _SC("size must be a number")); +} + +static SQInteger __map_array(SQArray *dest,SQArray *src,HSQUIRRELVM v) { + SQObjectPtr temp; + SQInteger size = src->Size(); + for(SQInteger n = 0; n < size; n++) { + src->Get(n,temp); + v->Push(src); + v->Push(temp); + if(SQ_FAILED(sq_call(v,2,SQTrue,SQFalse))) { + return SQ_ERROR; + } + dest->Set(n,v->GetUp(-1)); + v->Pop(); + } + return 0; +} + +static SQInteger array_map(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + SQInteger size = _array(o)->Size(); + SQObjectPtr ret = SQArray::Create(_ss(v),size); + if(SQ_FAILED(__map_array(_array(ret),_array(o),v))) + return SQ_ERROR; + v->Push(ret); + return 1; +} + +static SQInteger array_apply(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + if(SQ_FAILED(__map_array(_array(o),_array(o),v))) + return SQ_ERROR; + return 0; +} + +static SQInteger array_reduce(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + SQArray *a = _array(o); + SQInteger size = a->Size(); + if(size == 0) { + return 0; + } + SQObjectPtr res; + a->Get(0,res); + if(size > 1) { + SQObjectPtr other; + for(SQInteger n = 1; n < size; n++) { + a->Get(n,other); + v->Push(o); + v->Push(res); + v->Push(other); + if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) { + return SQ_ERROR; + } + res = v->GetUp(-1); + v->Pop(); + } + } + v->Push(res); + return 1; +} + +static SQInteger array_filter(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + SQArray *a = _array(o); + SQObjectPtr ret = SQArray::Create(_ss(v),0); + SQInteger size = a->Size(); + SQObjectPtr val; + for(SQInteger n = 0; n < size; n++) { + a->Get(n,val); + v->Push(o); + v->Push(n); + v->Push(val); + if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) { + return SQ_ERROR; + } + if(!SQVM::IsFalse(v->GetUp(-1))) { + _array(ret)->Append(val); + } + v->Pop(); + } + v->Push(ret); + return 1; +} + +static SQInteger array_find(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + SQObjectPtr &val = stack_get(v,2); + SQArray *a = _array(o); + SQInteger size = a->Size(); + SQObjectPtr temp; + for(SQInteger n = 0; n < size; n++) { + bool res = false; + a->Get(n,temp); + if(SQVM::IsEqual(temp,val,res) && res) { + v->Push(n); + return 1; + } + } + return 0; +} + +//QSORT ala Sedgewick +bool _qsort_compare(HSQUIRRELVM v,SQObjectPtr &arr,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret) +{ + if(func < 0) { + if(!v->ObjCmp(a,b,ret)) return false; + } + else { + SQInteger top = sq_gettop(v); + sq_push(v, func); + sq_pushroottable(v); + v->Push(a); + v->Push(b); + if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) { + if(!sq_isstring( v->_lasterror)) + v->Raise_Error(_SC("compare func failed")); + return false; + } + sq_getinteger(v, -1, &ret); + sq_settop(v, top); + return true; + } + return true; +} +//QSORT ala Sedgewick +bool _qsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger func) +{ + SQInteger i, j; + SQArray *a=_array(arr); + SQObjectPtr pivot,t; + if( l < r ){ + pivot = a->_values[l]; + i = l; j = r+1; + while(1){ + SQInteger ret; + do { + ++i; + if(i > r) break; + if(!_qsort_compare(v,arr,a->_values[i],pivot,func,ret)) + return false; + } while( ret <= 0); + do { + --j; + if ( j < 0 ) { + v->Raise_Error( _SC("Invalid qsort, probably compare function defect") ); + return false; + } + if(!_qsort_compare(v,arr,a->_values[j],pivot,func,ret)) + return false; + } + while( ret > 0 ); + if( i >= j ) break; + t = a->_values[i]; a->_values[i] = a->_values[j]; a->_values[j] = t; + } + t = a->_values[l]; a->_values[l] = a->_values[j]; a->_values[j] = t; + if(!_qsort( v, arr, l, j-1,func)) return false; + if(!_qsort( v, arr, j+1, r,func)) return false; + } + return true; +} + +static SQInteger array_sort(HSQUIRRELVM v) +{ + SQInteger func = -1; + SQObjectPtr &o = stack_get(v,1); + //SQObject &funcobj = stack_get(v,2); + if(_array(o)->Size() > 1) { + if(sq_gettop(v) == 2 /*&& type(funcobj) == OT_CLOSURE || type(funcobj) == OT_NATIVECLOSURE*/) func = 2; + if(!_qsort(v, o, 0, _array(o)->Size()-1, func)) + return SQ_ERROR; + + } + return 0; +} +static SQInteger array_slice(HSQUIRRELVM v) +{ + SQInteger sidx,eidx; + SQObjectPtr o; + if(get_slice_params(v,sidx,eidx,o)==-1)return -1; + SQInteger alen = _array(o)->Size(); + if(sidx < 0)sidx = alen + sidx; + if(eidx < 0)eidx = alen + eidx; + if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes")); + if(eidx > alen)return sq_throwerror(v,_SC("slice out of range")); + SQArray *arr=SQArray::Create(_ss(v),eidx-sidx); + SQObjectPtr t; + SQInteger count=0; + for(SQInteger i=sidx;iGet(i,t); + arr->Set(count++,t); + } + v->Push(arr); + return 1; + +} + +SQRegFunction SQSharedState::_array_default_delegate_funcz[]={ + {_SC("len"),default_delegate_len,1, _SC("a")}, + {_SC("append"),array_append,2, _SC("a")}, + {_SC("extend"),array_extend,2, _SC("aa")}, + {_SC("push"),array_append,2, _SC("a")}, + {_SC("pop"),array_pop,1, _SC("a")}, + {_SC("top"),array_top,1, _SC("a")}, + {_SC("insert"),array_insert,3, _SC("an")}, + {_SC("remove"),array_remove,2, _SC("an")}, + {_SC("resize"),array_resize,-2, _SC("an")}, + {_SC("reverse"),array_reverse,1, _SC("a")}, + {_SC("sort"),array_sort,-1, _SC("ac")}, + {_SC("slice"),array_slice,-1, _SC("ann")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("clear"),obj_clear,1, _SC(".")}, + {_SC("map"),array_map,2, _SC("ac")}, + {_SC("apply"),array_apply,2, _SC("ac")}, + {_SC("reduce"),array_reduce,2, _SC("ac")}, + {_SC("filter"),array_filter,2, _SC("ac")}, + {_SC("find"),array_find,2, _SC("a.")}, + {0,0} +}; + +//STRING DEFAULT DELEGATE////////////////////////// +static SQInteger string_slice(HSQUIRRELVM v) +{ + SQInteger sidx,eidx; + SQObjectPtr o; + if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1; + SQInteger slen = _string(o)->_len; + if(sidx < 0)sidx = slen + sidx; + if(eidx < 0)eidx = slen + eidx; + if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes")); + if(eidx > slen) return sq_throwerror(v,_SC("slice out of range")); + v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx)); + return 1; +} + +static SQInteger string_find(HSQUIRRELVM v) +{ + SQInteger top,start_idx=0; + const SQChar *str,*substr,*ret; + if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){ + if(top>2)sq_getinteger(v,3,&start_idx); + if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){ + ret=scstrstr(&str[start_idx],substr); + if(ret){ + sq_pushinteger(v,(SQInteger)(ret-str)); + return 1; + } + } + return 0; + } + return sq_throwerror(v,_SC("invalid param")); +} + +#define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \ +{ \ + SQObject str=stack_get(v,1); \ + SQInteger len=_string(str)->_len; \ + const SQChar *sThis=_stringval(str); \ + SQChar *sNew=(_ss(v)->GetScratchPad(rsl(len))); \ + for(SQInteger i=0;iPush(SQString::Create(_ss(v),sNew,len)); \ + return 1; \ +} + + +STRING_TOFUNCZ(tolower) +STRING_TOFUNCZ(toupper) + +SQRegFunction SQSharedState::_string_default_delegate_funcz[]={ + {_SC("len"),default_delegate_len,1, _SC("s")}, + {_SC("tointeger"),default_delegate_tointeger,1, _SC("s")}, + {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")}, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("slice"),string_slice,-1, _SC(" s n n")}, + {_SC("find"),string_find,-2, _SC("s s n ")}, + {_SC("tolower"),string_tolower,1, _SC("s")}, + {_SC("toupper"),string_toupper,1, _SC("s")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {0,0} +}; + +//INTEGER DEFAULT DELEGATE////////////////////////// +SQRegFunction SQSharedState::_number_default_delegate_funcz[]={ + {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")}, + {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")}, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {0,0} +}; + +//CLOSURE DEFAULT DELEGATE////////////////////////// +static SQInteger closure_pcall(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQFalse))?1:SQ_ERROR; +} + +static SQInteger closure_call(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQTrue))?1:SQ_ERROR; +} + +static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror) +{ + SQArray *aparams=_array(stack_get(v,2)); + SQInteger nparams=aparams->Size(); + v->Push(stack_get(v,1)); + for(SQInteger i=0;iPush(aparams->_values[i]); + return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR; +} + +static SQInteger closure_acall(HSQUIRRELVM v) +{ + return _closure_acall(v,SQTrue); +} + +static SQInteger closure_pacall(HSQUIRRELVM v) +{ + return _closure_acall(v,SQFalse); +} + +static SQInteger closure_bindenv(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_bindenv(v,1))) + return SQ_ERROR; + return 1; +} + +static SQInteger closure_getinfos(HSQUIRRELVM v) { + SQObject o = stack_get(v,1); + SQTable *res = SQTable::Create(_ss(v),4); + if(type(o) == OT_CLOSURE) { + SQFunctionProto *f = _closure(o)->_function; + SQInteger nparams = f->_nparameters + (f->_varparams?1:0); + SQObjectPtr params = SQArray::Create(_ss(v),nparams); + for(SQInteger n = 0; n_nparameters; n++) { + _array(params)->Set((SQInteger)n,f->_parameters[n]); + } + if(f->_varparams) { + _array(params)->Set(nparams-1,SQString::Create(_ss(v),_SC("..."),-1)); + } + res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),false); + res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),f->_name); + res->NewSlot(SQString::Create(_ss(v),_SC("src"),-1),f->_sourcename); + res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params); + res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams); + } + else { //OT_NATIVECLOSURE + SQNativeClosure *nc = _nativeclosure(o); + res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true); + res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name); + res->NewSlot(SQString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck); + SQObjectPtr typecheck; + if(nc->_typecheck.size() > 0) { + typecheck = + SQArray::Create(_ss(v), nc->_typecheck.size()); + for(SQUnsignedInteger n = 0; n_typecheck.size(); n++) { + _array(typecheck)->Set((SQInteger)n,nc->_typecheck[n]); + } + } + res->NewSlot(SQString::Create(_ss(v),_SC("typecheck"),-1),typecheck); + } + v->Push(res); + return 1; +} + + +SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={ + {_SC("call"),closure_call,-1, _SC("c")}, + {_SC("pcall"),closure_pcall,-1, _SC("c")}, + {_SC("acall"),closure_acall,2, _SC("ca")}, + {_SC("pacall"),closure_pacall,2, _SC("ca")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")}, + {_SC("getinfos"),closure_getinfos,1, _SC("c")}, + {0,0} +}; + +//GENERATOR DEFAULT DELEGATE +static SQInteger generator_getstatus(HSQUIRRELVM v) +{ + SQObject &o=stack_get(v,1); + switch(_generator(o)->_state){ + case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break; + case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break; + case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break; + } + return 1; +} + +SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={ + {_SC("getstatus"),generator_getstatus,1, _SC("g")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {0,0} +}; + +//THREAD DEFAULT DELEGATE +static SQInteger thread_call(HSQUIRRELVM v) +{ + SQObjectPtr o = stack_get(v,1); + if(type(o) == OT_THREAD) { + SQInteger nparams = sq_gettop(v); + _thread(o)->Push(_thread(o)->_roottable); + for(SQInteger i = 2; i<(nparams+1); i++) + sq_move(_thread(o),v,i); + if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQFalse))) { + sq_move(v,_thread(o),-1); + sq_pop(_thread(o),1); + return 1; + } + v->_lasterror = _thread(o)->_lasterror; + return SQ_ERROR; + } + return sq_throwerror(v,_SC("wrong parameter")); +} + +static SQInteger thread_wakeup(HSQUIRRELVM v) +{ + SQObjectPtr o = stack_get(v,1); + if(type(o) == OT_THREAD) { + SQVM *thread = _thread(o); + SQInteger state = sq_getvmstate(thread); + if(state != SQ_VMSTATE_SUSPENDED) { + switch(state) { + case SQ_VMSTATE_IDLE: + return sq_throwerror(v,_SC("cannot wakeup a idle thread")); + break; + case SQ_VMSTATE_RUNNING: + return sq_throwerror(v,_SC("cannot wakeup a running thread")); + break; + } + } + + SQInteger wakeupret = sq_gettop(v)>1?1:0; + if(wakeupret) { + sq_move(thread,v,2); + } + if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,SQTrue,SQTrue,SQFalse))) { + sq_move(v,thread,-1); + sq_pop(thread,1); //pop retval + if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) { + sq_settop(thread,1); //pop roottable + } + return 1; + } + sq_settop(thread,1); + v->_lasterror = thread->_lasterror; + return SQ_ERROR; + } + return sq_throwerror(v,_SC("wrong parameter")); +} + +static SQInteger thread_getstatus(HSQUIRRELVM v) +{ + SQObjectPtr &o = stack_get(v,1); + switch(sq_getvmstate(_thread(o))) { + case SQ_VMSTATE_IDLE: + sq_pushstring(v,_SC("idle"),-1); + break; + case SQ_VMSTATE_RUNNING: + sq_pushstring(v,_SC("running"),-1); + break; + case SQ_VMSTATE_SUSPENDED: + sq_pushstring(v,_SC("suspended"),-1); + break; + default: + return sq_throwerror(v,_SC("internal VM error")); + } + return 1; +} + +static SQInteger thread_getstackinfos(HSQUIRRELVM v) +{ + SQObjectPtr o = stack_get(v,1); + if(type(o) == OT_THREAD) { + SQVM *thread = _thread(o); + SQInteger threadtop = sq_gettop(thread); + SQInteger level; + sq_getinteger(v,-1,&level); + SQRESULT res = __getcallstackinfos(thread,level); + if(SQ_FAILED(res)) + { + sq_settop(thread,threadtop); + if(type(thread->_lasterror) == OT_STRING) { + sq_throwerror(v,_stringval(thread->_lasterror)); + } + else { + sq_throwerror(v,_SC("unknown error")); + } + } + if(res > 0) { + //some result + sq_move(v,thread,-1); + sq_settop(thread,threadtop); + return 1; + } + //no result + sq_settop(thread,threadtop); + return 0; + + } + return sq_throwerror(v,_SC("wrong parameter")); +} + +SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = { + {_SC("call"), thread_call, -1, _SC("v")}, + {_SC("wakeup"), thread_wakeup, -1, _SC("v")}, + {_SC("getstatus"), thread_getstatus, 1, _SC("v")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("getstackinfos"),thread_getstackinfos,2, _SC("vn")}, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {0,0}, +}; + +static SQInteger class_getattributes(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_getattributes(v,-2))?1:SQ_ERROR; +} + +static SQInteger class_setattributes(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_setattributes(v,-3))?1:SQ_ERROR; +} + +static SQInteger class_instance(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_createinstance(v,-1))?1:SQ_ERROR; +} + +static SQInteger class_getbase(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_getbase(v,-1))?1:SQ_ERROR; +} + +SQRegFunction SQSharedState::_class_default_delegate_funcz[] = { + {_SC("getattributes"), class_getattributes, 2, _SC("y.")}, + {_SC("setattributes"), class_setattributes, 3, _SC("y..")}, + {_SC("rawget"),container_rawget,2, _SC("y")}, + {_SC("rawset"),container_rawset,3, _SC("y")}, + {_SC("rawin"),container_rawexists,2, _SC("y")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("instance"),class_instance,1, _SC("y")}, + {_SC("getbase"),class_getbase,1, _SC("y")}, + {0,0} +}; + +static SQInteger instance_getclass(HSQUIRRELVM v) +{ + if(SQ_SUCCEEDED(sq_getclass(v,1))) + return 1; + return SQ_ERROR; +} + +SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = { + {_SC("getclass"), instance_getclass, 1, _SC("x")}, + {_SC("rawget"),container_rawget,2, _SC("x")}, + {_SC("rawset"),container_rawset,3, _SC("x")}, + {_SC("rawin"),container_rawexists,2, _SC("x")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {0,0} +}; + +static SQInteger weakref_ref(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_getweakrefval(v,1))) + return SQ_ERROR; + return 1; +} + +SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = { + {_SC("ref"),weakref_ref,1, _SC("r")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {0,0} +}; + diff --git a/squirrel_3_0_1_stable/squirrel/sqclass.cpp b/squirrel_3_0_1_stable/squirrel/sqclass.cpp index 1f26cc92f..dcee77d70 100644 --- a/squirrel_3_0_1_stable/squirrel/sqclass.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqclass.cpp @@ -1,213 +1,213 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#include "sqvm.h" -#include "sqtable.h" -#include "sqclass.h" -#include "sqfuncproto.h" -#include "sqclosure.h" - - - -SQClass::SQClass(SQSharedState *ss,SQClass *base) -{ - _base = base; - _typetag = 0; - _hook = NULL; - _udsize = 0; - _locked = false; - _constructoridx = -1; - if(_base) { - _constructoridx = _base->_constructoridx; - _udsize = _base->_udsize; - _defaultvalues.copy(base->_defaultvalues); - _methods.copy(base->_methods); - _COPY_VECTOR(_metamethods,base->_metamethods,MT_LAST); - __ObjAddRef(_base); - } - _members = base?base->_members->Clone() : SQTable::Create(ss,0); - __ObjAddRef(_members); - - INIT_CHAIN(); - ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); -} - -void SQClass::Finalize() { - _attributes.Null(); - _defaultvalues.resize(0); - _methods.resize(0); - _NULL_SQOBJECT_VECTOR(_metamethods,MT_LAST); - __ObjRelease(_members); - if(_base) { - __ObjRelease(_base); - } -} - -SQClass::~SQClass() -{ - REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); - Finalize(); -} - -bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic) -{ - SQObjectPtr temp; - bool belongs_to_static_table = type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic; - if(_locked && !belongs_to_static_table) - return false; //the class already has an instance so cannot be modified - if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value - { - _defaultvalues[_member_idx(temp)].val = val; - return true; - } - if(belongs_to_static_table) { - SQInteger mmidx; - if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) && - (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) { - _metamethods[mmidx] = val; - } - else { - SQObjectPtr theval = val; - if(_base && type(val) == OT_CLOSURE) { - theval = _closure(val)->Clone(); - _closure(theval)->_base = _base; - __ObjAddRef(_base); //ref for the closure - } - if(type(temp) == OT_NULL) { - bool isconstructor; - SQVM::IsEqual(ss->_constructoridx, key, isconstructor); - if(isconstructor) { - _constructoridx = (SQInteger)_methods.size(); - } - SQClassMember m; - m.val = theval; - _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size()))); - _methods.push_back(m); - } - else { - _methods[_member_idx(temp)].val = theval; - } - } - return true; - } - SQClassMember m; - m.val = val; - _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size()))); - _defaultvalues.push_back(m); - return true; -} - -SQInstance *SQClass::CreateInstance() -{ - if(!_locked) Lock(); - return SQInstance::Create(_opt_ss(this),this); -} - -SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) -{ - SQObjectPtr oval; - SQInteger idx = _members->Next(false,refpos,outkey,oval); - if(idx != -1) { - if(_ismethod(oval)) { - outval = _methods[_member_idx(oval)].val; - } - else { - SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val; - outval = _realval(o); - } - } - return idx; -} - -bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val) -{ - SQObjectPtr idx; - if(_members->Get(key,idx)) { - if(_isfield(idx)) - _defaultvalues[_member_idx(idx)].attrs = val; - else - _methods[_member_idx(idx)].attrs = val; - return true; - } - return false; -} - -bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval) -{ - SQObjectPtr idx; - if(_members->Get(key,idx)) { - outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs); - return true; - } - return false; -} - -/////////////////////////////////////////////////////////////////////// -void SQInstance::Init(SQSharedState *ss) -{ - _userpointer = NULL; - _hook = NULL; - __ObjAddRef(_class); - _delegate = _class->_members; - INIT_CHAIN(); - ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); -} - -SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize) -{ - _memsize = memsize; - _class = c; - SQUnsignedInteger nvalues = _class->_defaultvalues.size(); - for(SQUnsignedInteger n = 0; n < nvalues; n++) { - new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val); - } - Init(ss); -} - -SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize) -{ - _memsize = memsize; - _class = i->_class; - SQUnsignedInteger nvalues = _class->_defaultvalues.size(); - for(SQUnsignedInteger n = 0; n < nvalues; n++) { - new (&_values[n]) SQObjectPtr(i->_values[n]); - } - Init(ss); -} - -void SQInstance::Finalize() -{ - SQUnsignedInteger nvalues = _class->_defaultvalues.size(); - __ObjRelease(_class); - _NULL_SQOBJECT_VECTOR(_values,nvalues); - //for(SQUnsignedInteger i = 0; i < nvalues; i++) { -// _values[i].Null(); -// } -} - -SQInstance::~SQInstance() -{ - REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); - if(_class){ Finalize(); } //if _class is null it was already finalized by the GC -} - -bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) -{ - if(type(_class->_metamethods[mm]) != OT_NULL) { - res = _class->_metamethods[mm]; - return true; - } - return false; -} - -bool SQInstance::InstanceOf(SQClass *trg) -{ - SQClass *parent = _class; - while(parent != NULL) { - if(parent == trg) - return true; - parent = parent->_base; - } - return false; -} +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqtable.h" +#include "sqclass.h" +#include "sqfuncproto.h" +#include "sqclosure.h" + + + +SQClass::SQClass(SQSharedState *ss,SQClass *base) +{ + _base = base; + _typetag = 0; + _hook = NULL; + _udsize = 0; + _locked = false; + _constructoridx = -1; + if(_base) { + _constructoridx = _base->_constructoridx; + _udsize = _base->_udsize; + _defaultvalues.copy(base->_defaultvalues); + _methods.copy(base->_methods); + _COPY_VECTOR(_metamethods,base->_metamethods,MT_LAST); + __ObjAddRef(_base); + } + _members = base?base->_members->Clone() : SQTable::Create(ss,0); + __ObjAddRef(_members); + + INIT_CHAIN(); + ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); +} + +void SQClass::Finalize() { + _attributes.Null(); + _defaultvalues.resize(0); + _methods.resize(0); + _NULL_SQOBJECT_VECTOR(_metamethods,MT_LAST); + __ObjRelease(_members); + if(_base) { + __ObjRelease(_base); + } +} + +SQClass::~SQClass() +{ + REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); + Finalize(); +} + +bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic) +{ + SQObjectPtr temp; + bool belongs_to_static_table = type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic; + if(_locked && !belongs_to_static_table) + return false; //the class already has an instance so cannot be modified + if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value + { + _defaultvalues[_member_idx(temp)].val = val; + return true; + } + if(belongs_to_static_table) { + SQInteger mmidx; + if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) && + (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) { + _metamethods[mmidx] = val; + } + else { + SQObjectPtr theval = val; + if(_base && type(val) == OT_CLOSURE) { + theval = _closure(val)->Clone(); + _closure(theval)->_base = _base; + __ObjAddRef(_base); //ref for the closure + } + if(type(temp) == OT_NULL) { + bool isconstructor; + SQVM::IsEqual(ss->_constructoridx, key, isconstructor); + if(isconstructor) { + _constructoridx = (SQInteger)_methods.size(); + } + SQClassMember m; + m.val = theval; + _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size()))); + _methods.push_back(m); + } + else { + _methods[_member_idx(temp)].val = theval; + } + } + return true; + } + SQClassMember m; + m.val = val; + _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size()))); + _defaultvalues.push_back(m); + return true; +} + +SQInstance *SQClass::CreateInstance() +{ + if(!_locked) Lock(); + return SQInstance::Create(_opt_ss(this),this); +} + +SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) +{ + SQObjectPtr oval; + SQInteger idx = _members->Next(false,refpos,outkey,oval); + if(idx != -1) { + if(_ismethod(oval)) { + outval = _methods[_member_idx(oval)].val; + } + else { + SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val; + outval = _realval(o); + } + } + return idx; +} + +bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val) +{ + SQObjectPtr idx; + if(_members->Get(key,idx)) { + if(_isfield(idx)) + _defaultvalues[_member_idx(idx)].attrs = val; + else + _methods[_member_idx(idx)].attrs = val; + return true; + } + return false; +} + +bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval) +{ + SQObjectPtr idx; + if(_members->Get(key,idx)) { + outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs); + return true; + } + return false; +} + +/////////////////////////////////////////////////////////////////////// +void SQInstance::Init(SQSharedState *ss) +{ + _userpointer = NULL; + _hook = NULL; + __ObjAddRef(_class); + _delegate = _class->_members; + INIT_CHAIN(); + ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); +} + +SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize) +{ + _memsize = memsize; + _class = c; + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + for(SQUnsignedInteger n = 0; n < nvalues; n++) { + new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val); + } + Init(ss); +} + +SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize) +{ + _memsize = memsize; + _class = i->_class; + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + for(SQUnsignedInteger n = 0; n < nvalues; n++) { + new (&_values[n]) SQObjectPtr(i->_values[n]); + } + Init(ss); +} + +void SQInstance::Finalize() +{ + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + __ObjRelease(_class); + _NULL_SQOBJECT_VECTOR(_values,nvalues); + //for(SQUnsignedInteger i = 0; i < nvalues; i++) { +// _values[i].Null(); +// } +} + +SQInstance::~SQInstance() +{ + REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); + if(_class){ Finalize(); } //if _class is null it was already finalized by the GC +} + +bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) +{ + if(type(_class->_metamethods[mm]) != OT_NULL) { + res = _class->_metamethods[mm]; + return true; + } + return false; +} + +bool SQInstance::InstanceOf(SQClass *trg) +{ + SQClass *parent = _class; + while(parent != NULL) { + if(parent == trg) + return true; + parent = parent->_base; + } + return false; +} diff --git a/squirrel_3_0_1_stable/squirrel/sqclass.h b/squirrel_3_0_1_stable/squirrel/sqclass.h index 996a3df70..5c1fe2d20 100644 --- a/squirrel_3_0_1_stable/squirrel/sqclass.h +++ b/squirrel_3_0_1_stable/squirrel/sqclass.h @@ -1,158 +1,158 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQCLASS_H_ -#define _SQCLASS_H_ - -struct SQInstance; - -struct SQClassMember { - SQObjectPtr val; - SQObjectPtr attrs; -}; - -typedef sqvector SQClassMemberVec; - -#define MEMBER_TYPE_METHOD 0x01000000 -#define MEMBER_TYPE_FIELD 0x02000000 - -#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD) -#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD) -#define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i)) -#define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i)) -#define _member_type(o) (_integer(o)&0xFF000000) -#define _member_idx(o) (_integer(o)&0x00FFFFFF) - -struct SQClass : public CHAINABLE_OBJ -{ - SQClass(SQSharedState *ss,SQClass *base); -public: - static SQClass* Create(SQSharedState *ss,SQClass *base) { - SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass)); - new (newclass) SQClass(ss, base); - return newclass; - } - ~SQClass(); - bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic); - bool Get(const SQObjectPtr &key,SQObjectPtr &val) { - if(_members->Get(key,val)) { - if(_isfield(val)) { - SQObjectPtr &o = _defaultvalues[_member_idx(val)].val; - val = _realval(o); - } - else { - val = _methods[_member_idx(val)].val; - } - return true; - } - return false; - } - bool GetConstructor(SQObjectPtr &ctor) - { - if(_constructoridx != -1) { - ctor = _methods[_constructoridx].val; - return true; - } - return false; - } - bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val); - bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval); - void Lock() { _locked = true; if(_base) _base->Lock(); } - void Release() { - if (_hook) { _hook(_typetag,0);} - sq_delete(this, SQClass); - } - void Finalize(); -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable ** ); - SQObjectType GetType() {return OT_CLASS;} -#endif - SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); - SQInstance *CreateInstance(); - SQTable *_members; - SQClass *_base; - SQClassMemberVec _defaultvalues; - SQClassMemberVec _methods; - SQObjectPtr _metamethods[MT_LAST]; - SQObjectPtr _attributes; - SQUserPointer _typetag; - SQRELEASEHOOK _hook; - bool _locked; - SQInteger _constructoridx; - SQInteger _udsize; -}; - -#define calcinstancesize(_theclass_) \ - (_theclass_->_udsize + sq_aligning(sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0)))) - -struct SQInstance : public SQDelegable -{ - void Init(SQSharedState *ss); - SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize); - SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize); -public: - static SQInstance* Create(SQSharedState *ss,SQClass *theclass) { - - SQInteger size = calcinstancesize(theclass); - SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); - new (newinst) SQInstance(ss, theclass,size); - if(theclass->_udsize) { - newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize); - } - return newinst; - } - SQInstance *Clone(SQSharedState *ss) - { - SQInteger size = calcinstancesize(_class); - SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); - new (newinst) SQInstance(ss, this,size); - if(_class->_udsize) { - newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize); - } - return newinst; - } - ~SQInstance(); - bool Get(const SQObjectPtr &key,SQObjectPtr &val) { - if(_class->_members->Get(key,val)) { - if(_isfield(val)) { - SQObjectPtr &o = _values[_member_idx(val)]; - val = _realval(o); - } - else { - val = _class->_methods[_member_idx(val)].val; - } - return true; - } - return false; - } - bool Set(const SQObjectPtr &key,const SQObjectPtr &val) { - SQObjectPtr idx; - if(_class->_members->Get(key,idx) && _isfield(idx)) { - _values[_member_idx(idx)] = val; - return true; - } - return false; - } - void Release() { - _uiRef++; - if (_hook) { _hook(_userpointer,0);} - _uiRef--; - if(_uiRef > 0) return; - SQInteger size = _memsize; - this->~SQInstance(); - SQ_FREE(this, size); - } - void Finalize(); -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable ** ); - SQObjectType GetType() {return OT_INSTANCE;} -#endif - bool InstanceOf(SQClass *trg); - bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res); - - SQClass *_class; - SQUserPointer _userpointer; - SQRELEASEHOOK _hook; - SQInteger _memsize; - SQObjectPtr _values[1]; -}; - -#endif //_SQCLASS_H_ +/* see copyright notice in squirrel.h */ +#ifndef _SQCLASS_H_ +#define _SQCLASS_H_ + +struct SQInstance; + +struct SQClassMember { + SQObjectPtr val; + SQObjectPtr attrs; +}; + +typedef sqvector SQClassMemberVec; + +#define MEMBER_TYPE_METHOD 0x01000000 +#define MEMBER_TYPE_FIELD 0x02000000 + +#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD) +#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD) +#define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i)) +#define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i)) +#define _member_type(o) (_integer(o)&0xFF000000) +#define _member_idx(o) (_integer(o)&0x00FFFFFF) + +struct SQClass : public CHAINABLE_OBJ +{ + SQClass(SQSharedState *ss,SQClass *base); +public: + static SQClass* Create(SQSharedState *ss,SQClass *base) { + SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass)); + new (newclass) SQClass(ss, base); + return newclass; + } + ~SQClass(); + bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic); + bool Get(const SQObjectPtr &key,SQObjectPtr &val) { + if(_members->Get(key,val)) { + if(_isfield(val)) { + SQObjectPtr &o = _defaultvalues[_member_idx(val)].val; + val = _realval(o); + } + else { + val = _methods[_member_idx(val)].val; + } + return true; + } + return false; + } + bool GetConstructor(SQObjectPtr &ctor) + { + if(_constructoridx != -1) { + ctor = _methods[_constructoridx].val; + return true; + } + return false; + } + bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val); + bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval); + void Lock() { _locked = true; if(_base) _base->Lock(); } + void Release() { + if (_hook) { _hook(_typetag,0);} + sq_delete(this, SQClass); + } + void Finalize(); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable ** ); + SQObjectType GetType() {return OT_CLASS;} +#endif + SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); + SQInstance *CreateInstance(); + SQTable *_members; + SQClass *_base; + SQClassMemberVec _defaultvalues; + SQClassMemberVec _methods; + SQObjectPtr _metamethods[MT_LAST]; + SQObjectPtr _attributes; + SQUserPointer _typetag; + SQRELEASEHOOK _hook; + bool _locked; + SQInteger _constructoridx; + SQInteger _udsize; +}; + +#define calcinstancesize(_theclass_) \ + (_theclass_->_udsize + sq_aligning(sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0)))) + +struct SQInstance : public SQDelegable +{ + void Init(SQSharedState *ss); + SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize); + SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize); +public: + static SQInstance* Create(SQSharedState *ss,SQClass *theclass) { + + SQInteger size = calcinstancesize(theclass); + SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); + new (newinst) SQInstance(ss, theclass,size); + if(theclass->_udsize) { + newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize); + } + return newinst; + } + SQInstance *Clone(SQSharedState *ss) + { + SQInteger size = calcinstancesize(_class); + SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); + new (newinst) SQInstance(ss, this,size); + if(_class->_udsize) { + newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize); + } + return newinst; + } + ~SQInstance(); + bool Get(const SQObjectPtr &key,SQObjectPtr &val) { + if(_class->_members->Get(key,val)) { + if(_isfield(val)) { + SQObjectPtr &o = _values[_member_idx(val)]; + val = _realval(o); + } + else { + val = _class->_methods[_member_idx(val)].val; + } + return true; + } + return false; + } + bool Set(const SQObjectPtr &key,const SQObjectPtr &val) { + SQObjectPtr idx; + if(_class->_members->Get(key,idx) && _isfield(idx)) { + _values[_member_idx(idx)] = val; + return true; + } + return false; + } + void Release() { + _uiRef++; + if (_hook) { _hook(_userpointer,0);} + _uiRef--; + if(_uiRef > 0) return; + SQInteger size = _memsize; + this->~SQInstance(); + SQ_FREE(this, size); + } + void Finalize(); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable ** ); + SQObjectType GetType() {return OT_INSTANCE;} +#endif + bool InstanceOf(SQClass *trg); + bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res); + + SQClass *_class; + SQUserPointer _userpointer; + SQRELEASEHOOK _hook; + SQInteger _memsize; + SQObjectPtr _values[1]; +}; + +#endif //_SQCLASS_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqclosure.h b/squirrel_3_0_1_stable/squirrel/sqclosure.h index 07b3efcfe..353eb5041 100644 --- a/squirrel_3_0_1_stable/squirrel/sqclosure.h +++ b/squirrel_3_0_1_stable/squirrel/sqclosure.h @@ -1,193 +1,193 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQCLOSURE_H_ -#define _SQCLOSURE_H_ - - -#define _CALC_CLOSURE_SIZE(func) (sizeof(SQClosure) + (func->_noutervalues*sizeof(SQObjectPtr)) + (func->_ndefaultparams*sizeof(SQObjectPtr))) - -struct SQFunctionProto; -struct SQClass; -struct SQClosure : public CHAINABLE_OBJ -{ -private: - SQClosure(SQSharedState *ss,SQFunctionProto *func){_function = func; __ObjAddRef(_function); _base = NULL; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;} -public: - static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func){ - SQInteger size = _CALC_CLOSURE_SIZE(func); - SQClosure *nc=(SQClosure*)SQ_MALLOC(size); - new (nc) SQClosure(ss,func); - nc->_outervalues = (SQObjectPtr *)(nc + 1); - nc->_defaultparams = &nc->_outervalues[func->_noutervalues]; - _CONSTRUCT_VECTOR(SQObjectPtr,func->_noutervalues,nc->_outervalues); - _CONSTRUCT_VECTOR(SQObjectPtr,func->_ndefaultparams,nc->_defaultparams); - return nc; - } - void Release(){ - SQFunctionProto *f = _function; - SQInteger size = _CALC_CLOSURE_SIZE(f); - _DESTRUCT_VECTOR(SQObjectPtr,f->_noutervalues,_outervalues); - _DESTRUCT_VECTOR(SQObjectPtr,f->_ndefaultparams,_defaultparams); - __ObjRelease(_function); - this->~SQClosure(); - sq_vm_free(this,size); - } - - SQClosure *Clone() - { - SQFunctionProto *f = _function; - SQClosure * ret = SQClosure::Create(_opt_ss(this),f); - ret->_env = _env; - if(ret->_env) __ObjAddRef(ret->_env); - _COPY_VECTOR(ret->_outervalues,_outervalues,f->_noutervalues); - _COPY_VECTOR(ret->_defaultparams,_defaultparams,f->_ndefaultparams); - return ret; - } - ~SQClosure(); - - bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write); - static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret); -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **chain); - void Finalize(){ - SQFunctionProto *f = _function; - _NULL_SQOBJECT_VECTOR(_outervalues,f->_noutervalues); - _NULL_SQOBJECT_VECTOR(_defaultparams,f->_ndefaultparams); - } - SQObjectType GetType() {return OT_CLOSURE;} -#endif - SQWeakRef *_env; - SQClass *_base; - SQFunctionProto *_function; - SQObjectPtr *_outervalues; - SQObjectPtr *_defaultparams; -}; - -////////////////////////////////////////////// -struct SQOuter : public CHAINABLE_OBJ -{ - -private: - SQOuter(SQSharedState *ss, SQObjectPtr *outer){_valptr = outer; _next = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); } - -public: - static SQOuter *Create(SQSharedState *ss, SQObjectPtr *outer) - { - SQOuter *nc = (SQOuter*)SQ_MALLOC(sizeof(SQOuter)); - new (nc) SQOuter(ss, outer); - return nc; - } - ~SQOuter() { REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); } - - void Release() - { - this->~SQOuter(); - sq_vm_free(this,sizeof(SQOuter)); - } - -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **chain); - void Finalize() { _value.Null(); } - SQObjectType GetType() {return OT_OUTER;} -#endif - - SQObjectPtr *_valptr; /* pointer to value on stack, or _value below */ - SQInteger _idx; /* idx in stack array, for relocation */ - SQObjectPtr _value; /* value of outer after stack frame is closed */ - SQOuter *_next; /* pointer to next outer when frame is open */ -}; - -////////////////////////////////////////////// -struct SQGenerator : public CHAINABLE_OBJ -{ - enum SQGeneratorState{eRunning,eSuspended,eDead}; -private: - SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);} -public: - static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){ - SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator)); - new (nc) SQGenerator(ss,closure); - return nc; - } - ~SQGenerator() - { - REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); - } - void Kill(){ - _state=eDead; - _stack.resize(0); - _closure.Null();} - void Release(){ - sq_delete(this,SQGenerator); - } - - bool Yield(SQVM *v,SQInteger target); - bool Resume(SQVM *v,SQObjectPtr &dest); -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **chain); - void Finalize(){_stack.resize(0);_closure.Null();} - SQObjectType GetType() {return OT_GENERATOR;} -#endif - SQObjectPtr _closure; - SQObjectPtrVec _stack; - SQVM::CallInfo _ci; - ExceptionsTraps _etraps; - SQGeneratorState _state; -}; - -#define _CALC_NATVIVECLOSURE_SIZE(noutervalues) (sizeof(SQNativeClosure) + (noutervalues*sizeof(SQObjectPtr))) - -struct SQNativeClosure : public CHAINABLE_OBJ -{ -private: - SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;} -public: - static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func,SQInteger nouters) - { - SQInteger size = _CALC_NATVIVECLOSURE_SIZE(nouters); - SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(size); - new (nc) SQNativeClosure(ss,func); - nc->_outervalues = (SQObjectPtr *)(nc + 1); - nc->_noutervalues = nouters; - _CONSTRUCT_VECTOR(SQObjectPtr,nc->_noutervalues,nc->_outervalues); - return nc; - } - SQNativeClosure *Clone() - { - SQNativeClosure * ret = SQNativeClosure::Create(_opt_ss(this),_function,_noutervalues); - ret->_env = _env; - if(ret->_env) __ObjAddRef(ret->_env); - ret->_name = _name; - _COPY_VECTOR(ret->_outervalues,_outervalues,_noutervalues); - ret->_typecheck.copy(_typecheck); - ret->_nparamscheck = _nparamscheck; - return ret; - } - ~SQNativeClosure() - { - __ObjRelease(_env); - REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); - } - void Release(){ - SQInteger size = _CALC_NATVIVECLOSURE_SIZE(_noutervalues); - _DESTRUCT_VECTOR(SQObjectPtr,_noutervalues,_outervalues); - this->~SQNativeClosure(); - sq_free(this,size); - } - -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **chain); - void Finalize() { _NULL_SQOBJECT_VECTOR(_outervalues,_noutervalues); } - SQObjectType GetType() {return OT_NATIVECLOSURE;} -#endif - SQInteger _nparamscheck; - SQIntVec _typecheck; - SQObjectPtr *_outervalues; - SQUnsignedInteger _noutervalues; - SQWeakRef *_env; - SQFUNCTION _function; - SQObjectPtr _name; -}; - - - -#endif //_SQCLOSURE_H_ +/* see copyright notice in squirrel.h */ +#ifndef _SQCLOSURE_H_ +#define _SQCLOSURE_H_ + + +#define _CALC_CLOSURE_SIZE(func) (sizeof(SQClosure) + (func->_noutervalues*sizeof(SQObjectPtr)) + (func->_ndefaultparams*sizeof(SQObjectPtr))) + +struct SQFunctionProto; +struct SQClass; +struct SQClosure : public CHAINABLE_OBJ +{ +private: + SQClosure(SQSharedState *ss,SQFunctionProto *func){_function = func; __ObjAddRef(_function); _base = NULL; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;} +public: + static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func){ + SQInteger size = _CALC_CLOSURE_SIZE(func); + SQClosure *nc=(SQClosure*)SQ_MALLOC(size); + new (nc) SQClosure(ss,func); + nc->_outervalues = (SQObjectPtr *)(nc + 1); + nc->_defaultparams = &nc->_outervalues[func->_noutervalues]; + _CONSTRUCT_VECTOR(SQObjectPtr,func->_noutervalues,nc->_outervalues); + _CONSTRUCT_VECTOR(SQObjectPtr,func->_ndefaultparams,nc->_defaultparams); + return nc; + } + void Release(){ + SQFunctionProto *f = _function; + SQInteger size = _CALC_CLOSURE_SIZE(f); + _DESTRUCT_VECTOR(SQObjectPtr,f->_noutervalues,_outervalues); + _DESTRUCT_VECTOR(SQObjectPtr,f->_ndefaultparams,_defaultparams); + __ObjRelease(_function); + this->~SQClosure(); + sq_vm_free(this,size); + } + + SQClosure *Clone() + { + SQFunctionProto *f = _function; + SQClosure * ret = SQClosure::Create(_opt_ss(this),f); + ret->_env = _env; + if(ret->_env) __ObjAddRef(ret->_env); + _COPY_VECTOR(ret->_outervalues,_outervalues,f->_noutervalues); + _COPY_VECTOR(ret->_defaultparams,_defaultparams,f->_ndefaultparams); + return ret; + } + ~SQClosure(); + + bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write); + static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize(){ + SQFunctionProto *f = _function; + _NULL_SQOBJECT_VECTOR(_outervalues,f->_noutervalues); + _NULL_SQOBJECT_VECTOR(_defaultparams,f->_ndefaultparams); + } + SQObjectType GetType() {return OT_CLOSURE;} +#endif + SQWeakRef *_env; + SQClass *_base; + SQFunctionProto *_function; + SQObjectPtr *_outervalues; + SQObjectPtr *_defaultparams; +}; + +////////////////////////////////////////////// +struct SQOuter : public CHAINABLE_OBJ +{ + +private: + SQOuter(SQSharedState *ss, SQObjectPtr *outer){_valptr = outer; _next = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); } + +public: + static SQOuter *Create(SQSharedState *ss, SQObjectPtr *outer) + { + SQOuter *nc = (SQOuter*)SQ_MALLOC(sizeof(SQOuter)); + new (nc) SQOuter(ss, outer); + return nc; + } + ~SQOuter() { REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); } + + void Release() + { + this->~SQOuter(); + sq_vm_free(this,sizeof(SQOuter)); + } + +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize() { _value.Null(); } + SQObjectType GetType() {return OT_OUTER;} +#endif + + SQObjectPtr *_valptr; /* pointer to value on stack, or _value below */ + SQInteger _idx; /* idx in stack array, for relocation */ + SQObjectPtr _value; /* value of outer after stack frame is closed */ + SQOuter *_next; /* pointer to next outer when frame is open */ +}; + +////////////////////////////////////////////// +struct SQGenerator : public CHAINABLE_OBJ +{ + enum SQGeneratorState{eRunning,eSuspended,eDead}; +private: + SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);} +public: + static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){ + SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator)); + new (nc) SQGenerator(ss,closure); + return nc; + } + ~SQGenerator() + { + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); + } + void Kill(){ + _state=eDead; + _stack.resize(0); + _closure.Null();} + void Release(){ + sq_delete(this,SQGenerator); + } + + bool Yield(SQVM *v,SQInteger target); + bool Resume(SQVM *v,SQObjectPtr &dest); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize(){_stack.resize(0);_closure.Null();} + SQObjectType GetType() {return OT_GENERATOR;} +#endif + SQObjectPtr _closure; + SQObjectPtrVec _stack; + SQVM::CallInfo _ci; + ExceptionsTraps _etraps; + SQGeneratorState _state; +}; + +#define _CALC_NATVIVECLOSURE_SIZE(noutervalues) (sizeof(SQNativeClosure) + (noutervalues*sizeof(SQObjectPtr))) + +struct SQNativeClosure : public CHAINABLE_OBJ +{ +private: + SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;} +public: + static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func,SQInteger nouters) + { + SQInteger size = _CALC_NATVIVECLOSURE_SIZE(nouters); + SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(size); + new (nc) SQNativeClosure(ss,func); + nc->_outervalues = (SQObjectPtr *)(nc + 1); + nc->_noutervalues = nouters; + _CONSTRUCT_VECTOR(SQObjectPtr,nc->_noutervalues,nc->_outervalues); + return nc; + } + SQNativeClosure *Clone() + { + SQNativeClosure * ret = SQNativeClosure::Create(_opt_ss(this),_function,_noutervalues); + ret->_env = _env; + if(ret->_env) __ObjAddRef(ret->_env); + ret->_name = _name; + _COPY_VECTOR(ret->_outervalues,_outervalues,_noutervalues); + ret->_typecheck.copy(_typecheck); + ret->_nparamscheck = _nparamscheck; + return ret; + } + ~SQNativeClosure() + { + __ObjRelease(_env); + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); + } + void Release(){ + SQInteger size = _CALC_NATVIVECLOSURE_SIZE(_noutervalues); + _DESTRUCT_VECTOR(SQObjectPtr,_noutervalues,_outervalues); + this->~SQNativeClosure(); + sq_free(this,size); + } + +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize() { _NULL_SQOBJECT_VECTOR(_outervalues,_noutervalues); } + SQObjectType GetType() {return OT_NATIVECLOSURE;} +#endif + SQInteger _nparamscheck; + SQIntVec _typecheck; + SQObjectPtr *_outervalues; + SQUnsignedInteger _noutervalues; + SQWeakRef *_env; + SQFUNCTION _function; + SQObjectPtr _name; +}; + + + +#endif //_SQCLOSURE_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqcompiler.cpp b/squirrel_3_0_1_stable/squirrel/sqcompiler.cpp index e8c1496c9..d2f161642 100644 --- a/squirrel_3_0_1_stable/squirrel/sqcompiler.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqcompiler.cpp @@ -1,1504 +1,1504 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#ifndef NO_COMPILER -#include -#include -#include "sqopcodes.h" -#include "sqstring.h" -#include "sqfuncproto.h" -#include "sqcompiler.h" -#include "sqfuncstate.h" -#include "sqlexer.h" -#include "sqvm.h" -#include "sqtable.h" - -#define EXPR 1 -#define OBJECT 2 -#define BASE 3 -#define LOCAL 4 -#define OUTER 5 - -struct SQExpState { - SQInteger etype; /* expr. type; one of EXPR, OBJECT, BASE, OUTER or LOCAL */ - SQInteger epos; /* expr. location on stack; -1 for OBJECT and BASE */ - bool donot_get; /* signal not to deref the next value */ -}; - -struct SQScope { - SQInteger outers; - SQInteger stacksize; -}; - -#define BEGIN_SCOPE() SQScope __oldscope__ = _scope; \ - _scope.outers = _fs->_outers; \ - _scope.stacksize = _fs->GetStackSize(); - -#define RESOLVE_OUTERS() if(_fs->GetStackSize() != _scope.stacksize) { \ - if(_fs->CountOuters(_scope.stacksize)) { \ - _fs->AddInstruction(_OP_CLOSE,0,_scope.stacksize); \ - } \ - } - -#define END_SCOPE_NO_CLOSE() { if(_fs->GetStackSize() != _scope.stacksize) { \ - _fs->SetStackSize(_scope.stacksize); \ - } \ - _scope = __oldscope__; \ - } - -#define END_SCOPE() { SQInteger oldouters = _fs->_outers;\ - if(_fs->GetStackSize() != _scope.stacksize) { \ - _fs->SetStackSize(_scope.stacksize); \ - if(oldouters != _fs->_outers) { \ - _fs->AddInstruction(_OP_CLOSE,0,_scope.stacksize); \ - } \ - } \ - _scope = __oldscope__; \ - } - -#define BEGIN_BREAKBLE_BLOCK() SQInteger __nbreaks__=_fs->_unresolvedbreaks.size(); \ - SQInteger __ncontinues__=_fs->_unresolvedcontinues.size(); \ - _fs->_breaktargets.push_back(0);_fs->_continuetargets.push_back(0); - -#define END_BREAKBLE_BLOCK(continue_target) {__nbreaks__=_fs->_unresolvedbreaks.size()-__nbreaks__; \ - __ncontinues__=_fs->_unresolvedcontinues.size()-__ncontinues__; \ - if(__ncontinues__>0)ResolveContinues(_fs,__ncontinues__,continue_target); \ - if(__nbreaks__>0)ResolveBreaks(_fs,__nbreaks__); \ - _fs->_breaktargets.pop_back();_fs->_continuetargets.pop_back();} - -class SQCompiler -{ -public: - SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo) - { - _vm=v; - _lex.Init(_ss(v), rg, up,ThrowError,this); - _sourcename = SQString::Create(_ss(v), sourcename); - _lineinfo = lineinfo;_raiseerror = raiseerror; - _scope.outers = 0; - _scope.stacksize = 0; - compilererror = NULL; - } - static void ThrowError(void *ud, const SQChar *s) { - SQCompiler *c = (SQCompiler *)ud; - c->Error(s); - } - void Error(const SQChar *s, ...) - { - static SQChar temp[256]; - va_list vl; - va_start(vl, s); - scvsprintf(temp, s, vl); - va_end(vl); - compilererror = temp; - longjmp(_errorjmp,1); - } - void Lex(){ _token = _lex.Lex();} - SQObject Expect(SQInteger tok) - { - - if(_token != tok) { - if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) { - //do nothing - } - else { - const SQChar *etypename; - if(tok > 255) { - switch(tok) - { - case TK_IDENTIFIER: - etypename = _SC("IDENTIFIER"); - break; - case TK_STRING_LITERAL: - etypename = _SC("STRING_LITERAL"); - break; - case TK_INTEGER: - etypename = _SC("INTEGER"); - break; - case TK_FLOAT: - etypename = _SC("FLOAT"); - break; - default: - etypename = _lex.Tok2Str(tok); - } - Error(_SC("expected '%s'"), etypename); - } - Error(_SC("expected '%c'"), tok); - } - } - SQObjectPtr ret; - switch(tok) - { - case TK_IDENTIFIER: - ret = _fs->CreateString(_lex._svalue); - break; - case TK_STRING_LITERAL: - ret = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1); - break; - case TK_INTEGER: - ret = SQObjectPtr(_lex._nvalue); - break; - case TK_FLOAT: - ret = SQObjectPtr(_lex._fvalue); - break; - } - Lex(); - return ret; - } - bool IsEndOfStatement() { return ((_lex._prevtoken == _SC('\n')) || (_token == SQUIRREL_EOB) || (_token == _SC('}')) || (_token == _SC(';'))); } - void OptionalSemicolon() - { - if(_token == _SC(';')) { Lex(); return; } - if(!IsEndOfStatement()) { - Error(_SC("end of statement expected (; or lf)")); - } - } - void MoveIfCurrentTargetIsLocal() { - SQInteger trg = _fs->TopTarget(); - if(_fs->IsLocal(trg)) { - trg = _fs->PopTarget(); //no pops the target and move it - _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), trg); - } - } - bool Compile(SQObjectPtr &o) - { - _debugline = 1; - _debugop = 0; - - SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this); - funcstate._name = SQString::Create(_ss(_vm), _SC("main")); - _fs = &funcstate; - _fs->AddParameter(_fs->CreateString(_SC("this"))); - _fs->AddParameter(_fs->CreateString(_SC("vargv"))); - _fs->_varparams = true; - _fs->_sourcename = _sourcename; - SQInteger stacksize = _fs->GetStackSize(); - if(setjmp(_errorjmp) == 0) { - Lex(); - while(_token > 0){ - Statement(); - if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon(); - } - _fs->SetStackSize(stacksize); - _fs->AddLineInfos(_lex._currentline, _lineinfo, true); - _fs->AddInstruction(_OP_RETURN, 0xFF); - _fs->SetStackSize(0); - o =_fs->BuildProto(); -#ifdef _DEBUG_DUMP - _fs->Dump(_funcproto(o)); -#endif - } - else { - if(_raiseerror && _ss(_vm)->_compilererrorhandler) { - _ss(_vm)->_compilererrorhandler(_vm, compilererror, type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"), - _lex._currentline, _lex._currentcolumn); - } - _vm->_lasterror = SQString::Create(_ss(_vm), compilererror, -1); - return false; - } - return true; - } - void Statements() - { - while(_token != _SC('}') && _token != TK_DEFAULT && _token != TK_CASE) { - Statement(); - if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon(); - } - } - void Statement(bool closeframe = true) - { - _fs->AddLineInfos(_lex._currentline, _lineinfo); - switch(_token){ - case _SC(';'): Lex(); break; - case TK_IF: IfStatement(); break; - case TK_WHILE: WhileStatement(); break; - case TK_DO: DoWhileStatement(); break; - case TK_FOR: ForStatement(); break; - case TK_FOREACH: ForEachStatement(); break; - case TK_SWITCH: SwitchStatement(); break; - case TK_LOCAL: LocalDeclStatement(); break; - case TK_RETURN: - case TK_YIELD: { - SQOpcode op; - if(_token == TK_RETURN) { - op = _OP_RETURN; - } - else { - op = _OP_YIELD; - _fs->_bgenerator = true; - } - Lex(); - if(!IsEndOfStatement()) { - SQInteger retexp = _fs->GetCurrentPos()+1; - CommaExpr(); - if(op == _OP_RETURN && _fs->_traps > 0) - _fs->AddInstruction(_OP_POPTRAP, _fs->_traps, 0); - _fs->_returnexp = retexp; - _fs->AddInstruction(op, 1, _fs->PopTarget(),_fs->GetStackSize()); - } - else{ - if(op == _OP_RETURN && _fs->_traps > 0) - _fs->AddInstruction(_OP_POPTRAP, _fs->_traps ,0); - _fs->_returnexp = -1; - _fs->AddInstruction(op, 0xFF,0,_fs->GetStackSize()); - } - break;} - case TK_BREAK: - if(_fs->_breaktargets.size() <= 0)Error(_SC("'break' has to be in a loop block")); - if(_fs->_breaktargets.top() > 0){ - _fs->AddInstruction(_OP_POPTRAP, _fs->_breaktargets.top(), 0); - } - RESOLVE_OUTERS(); - _fs->AddInstruction(_OP_JMP, 0, -1234); - _fs->_unresolvedbreaks.push_back(_fs->GetCurrentPos()); - Lex(); - break; - case TK_CONTINUE: - if(_fs->_continuetargets.size() <= 0)Error(_SC("'continue' has to be in a loop block")); - if(_fs->_continuetargets.top() > 0) { - _fs->AddInstruction(_OP_POPTRAP, _fs->_continuetargets.top(), 0); - } - RESOLVE_OUTERS(); - _fs->AddInstruction(_OP_JMP, 0, -1234); - _fs->_unresolvedcontinues.push_back(_fs->GetCurrentPos()); - Lex(); - break; - case TK_FUNCTION: - FunctionStatement(); - break; - case TK_CLASS: - ClassStatement(); - break; - case TK_ENUM: - EnumStatement(); - break; - case _SC('{'):{ - BEGIN_SCOPE(); - Lex(); - Statements(); - Expect(_SC('}')); - if(closeframe) { - END_SCOPE(); - } - else { - END_SCOPE_NO_CLOSE(); - } - } - break; - case TK_TRY: - TryCatchStatement(); - break; - case TK_THROW: - Lex(); - CommaExpr(); - _fs->AddInstruction(_OP_THROW, _fs->PopTarget()); - break; - case TK_CONST: - { - Lex(); - SQObject id = Expect(TK_IDENTIFIER); - Expect('='); - SQObject val = ExpectScalar(); - OptionalSemicolon(); - SQTable *enums = _table(_ss(_vm)->_consts); - SQObjectPtr strongid = id; - enums->NewSlot(strongid,SQObjectPtr(val)); - strongid.Null(); - } - break; - default: - CommaExpr(); - _fs->DiscardTarget(); - //_fs->PopTarget(); - break; - } - _fs->SnoozeOpt(); - } - void EmitDerefOp(SQOpcode op) - { - SQInteger val = _fs->PopTarget(); - SQInteger key = _fs->PopTarget(); - SQInteger src = _fs->PopTarget(); - _fs->AddInstruction(op,_fs->PushTarget(),src,key,val); - } - void Emit2ArgsOP(SQOpcode op, SQInteger p3 = 0) - { - SQInteger p2 = _fs->PopTarget(); //src in OP_GET - SQInteger p1 = _fs->PopTarget(); //key in OP_GET - _fs->AddInstruction(op,_fs->PushTarget(), p1, p2, p3); - } - void EmitCompoundArith(SQInteger tok, SQInteger etype, SQInteger pos) - { - /* Generate code depending on the expression type */ - switch(etype) { - case LOCAL:{ - SQInteger p2 = _fs->PopTarget(); //src in OP_GET - SQInteger p1 = _fs->PopTarget(); //key in OP_GET - _fs->PushTarget(p1); - //EmitCompArithLocal(tok, p1, p1, p2); - _fs->AddInstruction(ChooseArithOpByToken(tok),p1, p2, p1, 0); - } - break; - case OBJECT: - case BASE: - { - SQInteger val = _fs->PopTarget(); - SQInteger key = _fs->PopTarget(); - SQInteger src = _fs->PopTarget(); - /* _OP_COMPARITH mixes dest obj and source val in the arg1 */ - _fs->AddInstruction(_OP_COMPARITH, _fs->PushTarget(), (src<<16)|val, key, ChooseCompArithCharByToken(tok)); - } - break; - case OUTER: - { - SQInteger val = _fs->TopTarget(); - SQInteger tmp = _fs->PushTarget(); - _fs->AddInstruction(_OP_GETOUTER, tmp, pos); - _fs->AddInstruction(ChooseArithOpByToken(tok), tmp, val, tmp, 0); - _fs->AddInstruction(_OP_SETOUTER, tmp, pos, tmp); - } - break; - } - } - void CommaExpr() - { - for(Expression();_token == ',';_fs->PopTarget(), Lex(), CommaExpr()); - } - void Expression() - { - SQExpState es = _es; - _es.etype = EXPR; - _es.epos = -1; - _es.donot_get = false; - LogicalOrExp(); - switch(_token) { - case _SC('='): - case TK_NEWSLOT: - case TK_MINUSEQ: - case TK_PLUSEQ: - case TK_MULEQ: - case TK_DIVEQ: - case TK_MODEQ:{ - SQInteger op = _token; - SQInteger ds = _es.etype; - SQInteger pos = _es.epos; - if(ds == EXPR) Error(_SC("can't assign expression")); - Lex(); Expression(); - - switch(op){ - case TK_NEWSLOT: - if(ds == OBJECT || ds == BASE) - EmitDerefOp(_OP_NEWSLOT); - else //if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local - Error(_SC("can't 'create' a local slot")); - break; - case _SC('='): //ASSIGN - switch(ds) { - case LOCAL: - { - SQInteger src = _fs->PopTarget(); - SQInteger dst = _fs->TopTarget(); - _fs->AddInstruction(_OP_MOVE, dst, src); - } - break; - case OBJECT: - case BASE: - EmitDerefOp(_OP_SET); - break; - case OUTER: - { - SQInteger src = _fs->PopTarget(); - SQInteger dst = _fs->PushTarget(); - _fs->AddInstruction(_OP_SETOUTER, dst, pos, src); - } - } - break; - case TK_MINUSEQ: - case TK_PLUSEQ: - case TK_MULEQ: - case TK_DIVEQ: - case TK_MODEQ: - EmitCompoundArith(op, ds, pos); - break; - } - } - break; - case _SC('?'): { - Lex(); - _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); - SQInteger jzpos = _fs->GetCurrentPos(); - SQInteger trg = _fs->PushTarget(); - Expression(); - SQInteger first_exp = _fs->PopTarget(); - if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); - SQInteger endfirstexp = _fs->GetCurrentPos(); - _fs->AddInstruction(_OP_JMP, 0, 0); - Expect(_SC(':')); - SQInteger jmppos = _fs->GetCurrentPos(); - Expression(); - SQInteger second_exp = _fs->PopTarget(); - if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); - _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos); - _fs->SetIntructionParam(jzpos, 1, endfirstexp - jzpos + 1); - _fs->SnoozeOpt(); - } - break; - } - _es = es; - } - template void BIN_EXP(SQOpcode op, T f,SQInteger op3 = 0) - { - Lex(); (this->*f)(); - SQInteger op1 = _fs->PopTarget();SQInteger op2 = _fs->PopTarget(); - _fs->AddInstruction(op, _fs->PushTarget(), op1, op2, op3); - } - void LogicalOrExp() - { - LogicalAndExp(); - for(;;) if(_token == TK_OR) { - SQInteger first_exp = _fs->PopTarget(); - SQInteger trg = _fs->PushTarget(); - _fs->AddInstruction(_OP_OR, trg, 0, first_exp, 0); - SQInteger jpos = _fs->GetCurrentPos(); - if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); - Lex(); LogicalOrExp(); - _fs->SnoozeOpt(); - SQInteger second_exp = _fs->PopTarget(); - if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); - _fs->SnoozeOpt(); - _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos)); - break; - }else return; - } - void LogicalAndExp() - { - BitwiseOrExp(); - for(;;) switch(_token) { - case TK_AND: { - SQInteger first_exp = _fs->PopTarget(); - SQInteger trg = _fs->PushTarget(); - _fs->AddInstruction(_OP_AND, trg, 0, first_exp, 0); - SQInteger jpos = _fs->GetCurrentPos(); - if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); - Lex(); LogicalAndExp(); - _fs->SnoozeOpt(); - SQInteger second_exp = _fs->PopTarget(); - if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); - _fs->SnoozeOpt(); - _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos)); - break; - } - case TK_IN: BIN_EXP(_OP_EXISTS, &SQCompiler::BitwiseOrExp); break; - case TK_INSTANCEOF: BIN_EXP(_OP_INSTANCEOF, &SQCompiler::BitwiseOrExp); break; - default: - return; - } - } - void BitwiseOrExp() - { - BitwiseXorExp(); - for(;;) if(_token == _SC('|')) - {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseXorExp,BW_OR); - }else return; - } - void BitwiseXorExp() - { - BitwiseAndExp(); - for(;;) if(_token == _SC('^')) - {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseAndExp,BW_XOR); - }else return; - } - void BitwiseAndExp() - { - EqExp(); - for(;;) if(_token == _SC('&')) - {BIN_EXP(_OP_BITW, &SQCompiler::EqExp,BW_AND); - }else return; - } - void EqExp() - { - CompExp(); - for(;;) switch(_token) { - case TK_EQ: BIN_EXP(_OP_EQ, &SQCompiler::CompExp); break; - case TK_NE: BIN_EXP(_OP_NE, &SQCompiler::CompExp); break; - case TK_3WAYSCMP: BIN_EXP(_OP_CMP, &SQCompiler::CompExp,CMP_3W); break; - default: return; - } - } - void CompExp() - { - ShiftExp(); - for(;;) switch(_token) { - case _SC('>'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_G); break; - case _SC('<'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_L); break; - case TK_GE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_GE); break; - case TK_LE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_LE); break; - default: return; - } - } - void ShiftExp() - { - PlusExp(); - for(;;) switch(_token) { - case TK_USHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_USHIFTR); break; - case TK_SHIFTL: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTL); break; - case TK_SHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTR); break; - default: return; - } - } - SQOpcode ChooseArithOpByToken(SQInteger tok) - { - switch(tok) { - case TK_PLUSEQ: case '+': return _OP_ADD; - case TK_MINUSEQ: case '-': return _OP_SUB; - case TK_MULEQ: case '*': return _OP_MUL; - case TK_DIVEQ: case '/': return _OP_DIV; - case TK_MODEQ: case '%': return _OP_MOD; - default: assert(0); - } - return _OP_ADD; - } - SQInteger ChooseCompArithCharByToken(SQInteger tok) - { - SQInteger oper; - switch(tok){ - case TK_MINUSEQ: oper = '-'; break; - case TK_PLUSEQ: oper = '+'; break; - case TK_MULEQ: oper = '*'; break; - case TK_DIVEQ: oper = '/'; break; - case TK_MODEQ: oper = '%'; break; - default: oper = 0; //shut up compiler - assert(0); break; - }; - return oper; - } - void PlusExp() - { - MultExp(); - for(;;) switch(_token) { - case _SC('+'): case _SC('-'): - BIN_EXP(ChooseArithOpByToken(_token), &SQCompiler::MultExp); break; - default: return; - } - } - - void MultExp() - { - PrefixedExpr(); - for(;;) switch(_token) { - case _SC('*'): case _SC('/'): case _SC('%'): - BIN_EXP(ChooseArithOpByToken(_token), &SQCompiler::PrefixedExpr); break; - default: return; - } - } - //if 'pos' != -1 the previous variable is a local variable - void PrefixedExpr() - { - SQInteger pos = Factor(); - for(;;) { - switch(_token) { - case _SC('.'): - pos = -1; - Lex(); - - _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER))); - if(_es.etype==BASE) { - Emit2ArgsOP(_OP_GET); - pos = _fs->TopTarget(); - _es.etype = EXPR; - _es.epos = pos; - } - else { - if(NeedGet()) { - Emit2ArgsOP(_OP_GET); - } - _es.etype = OBJECT; - } - break; - case _SC('['): - if(_lex._prevtoken == _SC('\n')) Error(_SC("cannot brake deref/or comma needed after [exp]=exp slot declaration")); - Lex(); Expression(); Expect(_SC(']')); - pos = -1; - if(_es.etype==BASE) { - Emit2ArgsOP(_OP_GET); - pos = _fs->TopTarget(); - _es.etype = EXPR; - _es.epos = pos; - } - else { - if(NeedGet()) { - Emit2ArgsOP(_OP_GET); - } - _es.etype = OBJECT; - } - break; - case TK_MINUSMINUS: - case TK_PLUSPLUS: - { - if(IsEndOfStatement()) return; - SQInteger diff = (_token==TK_MINUSMINUS) ? -1 : 1; - Lex(); - switch(_es.etype) - { - case EXPR: Error(_SC("can't '++' or '--' an expression")); break; - case OBJECT: - case BASE: - Emit2ArgsOP(_OP_PINC, diff); - break; - case LOCAL: { - SQInteger src = _fs->PopTarget(); - _fs->AddInstruction(_OP_PINCL, _fs->PushTarget(), src, 0, diff); - } - break; - case OUTER: { - SQInteger tmp1 = _fs->PushTarget(); - SQInteger tmp2 = _fs->PushTarget(); - _fs->AddInstruction(_OP_GETOUTER, tmp2, _es.epos); - _fs->AddInstruction(_OP_PINCL, tmp1, tmp2, 0, diff); - _fs->AddInstruction(_OP_SETOUTER, tmp2, _es.epos, tmp2); - _fs->PopTarget(); - } - } - } - return; - break; - case _SC('('): - switch(_es.etype) { - case OBJECT: { - SQInteger key = _fs->PopTarget(); /* location of the key */ - SQInteger table = _fs->PopTarget(); /* location of the object */ - SQInteger closure = _fs->PushTarget(); /* location for the closure */ - SQInteger ttarget = _fs->PushTarget(); /* location for 'this' pointer */ - _fs->AddInstruction(_OP_PREPCALL, closure, key, table, ttarget); - } - break; - case BASE: - //Emit2ArgsOP(_OP_GET); - _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0); - break; - case OUTER: - _fs->AddInstruction(_OP_GETOUTER, _fs->PushTarget(), _es.epos); - _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0); - break; - default: - _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0); - } - _es.etype = EXPR; - Lex(); - FunctionCallArgs(); - break; - default: return; - } - } - } - SQInteger Factor() - { - _es.etype = EXPR; - switch(_token) - { - case TK_STRING_LITERAL: - _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1))); - Lex(); - break; - case TK_BASE: - Lex(); - _fs->AddInstruction(_OP_GETBASE, _fs->PushTarget()); - _es.etype = BASE; - _es.epos = _fs->TopTarget(); - return (_es.epos); - break; - case TK_IDENTIFIER: - case TK_CONSTRUCTOR: - case TK_THIS:{ - SQObject id; - SQObject constant; - - switch(_token) { - case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break; - case TK_THIS: id = _fs->CreateString(_SC("this")); break; - case TK_CONSTRUCTOR: id = _fs->CreateString(_SC("constructor")); break; - } - - SQInteger pos = -1; - Lex(); - if((pos = _fs->GetLocalVariable(id)) != -1) { - /* Handle a local variable (includes 'this') */ - _fs->PushTarget(pos); - _es.etype = LOCAL; - _es.epos = pos; - } - - else if((pos = _fs->GetOuterVariable(id)) != -1) { - /* Handle a free var */ - if(NeedGet()) { - _es.epos = _fs->PushTarget(); - _fs->AddInstruction(_OP_GETOUTER, _es.epos, pos); - /* _es.etype = EXPR; already default value */ - } - else { - _es.etype = OUTER; - _es.epos = pos; - } - } - - else if(_fs->IsConstant(id, constant)) { - /* Handle named constant */ - SQObjectPtr constval; - SQObject constid; - if(type(constant) == OT_TABLE) { - Expect('.'); - constid = Expect(TK_IDENTIFIER); - if(!_table(constant)->Get(constid, constval)) { - constval.Null(); - Error(_SC("invalid constant [%s.%s]"), _stringval(id), _stringval(constid)); - } - } - else { - constval = constant; - } - _es.epos = _fs->PushTarget(); - - /* generate direct or literal function depending on size */ - SQObjectType ctype = type(constval); - switch(ctype) { - case OT_INTEGER: EmitLoadConstInt(_integer(constval),_es.epos); break; - case OT_FLOAT: EmitLoadConstFloat(_float(constval),_es.epos); break; - default: _fs->AddInstruction(_OP_LOAD,_es.epos,_fs->GetConstant(constval)); break; - } - _es.etype = EXPR; - } - else { - /* Handle a non-local variable, aka a field. Push the 'this' pointer on - * the virtual stack (always found in offset 0, so no instruction needs to - * be generated), and push the key next. Generate an _OP_LOAD instruction - * for the latter. If we are not using the variable as a dref expr, generate - * the _OP_GET instruction. - */ - _fs->PushTarget(0); - _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); - if(NeedGet()) { - Emit2ArgsOP(_OP_GET); - } - _es.etype = OBJECT; - } - return _es.epos; - } - break; - case TK_DOUBLE_COLON: // "::" - _fs->AddInstruction(_OP_LOADROOT, _fs->PushTarget()); - _es.etype = OBJECT; - _token = _SC('.'); /* hack: drop into PrefixExpr, case '.'*/ - _es.epos = -1; - return _es.epos; - break; - case TK_NULL: - _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1); - Lex(); - break; - case TK_INTEGER: EmitLoadConstInt(_lex._nvalue,-1); Lex(); break; - case TK_FLOAT: EmitLoadConstFloat(_lex._fvalue,-1); Lex(); break; - case TK_TRUE: case TK_FALSE: - _fs->AddInstruction(_OP_LOADBOOL, _fs->PushTarget(),_token == TK_TRUE?1:0); - Lex(); - break; - case _SC('['): { - _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,0,NOT_ARRAY); - SQInteger apos = _fs->GetCurrentPos(),key = 0; - Lex(); - while(_token != _SC(']')) { - Expression(); - if(_token == _SC(',')) Lex(); - SQInteger val = _fs->PopTarget(); - SQInteger array = _fs->TopTarget(); - _fs->AddInstruction(_OP_APPENDARRAY, array, val, AAT_STACK); - key++; - } - _fs->SetIntructionParam(apos, 1, key); - Lex(); - } - break; - case _SC('{'): - _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE); - Lex();ParseTableOrClass(_SC(','),_SC('}')); - break; - case TK_FUNCTION: FunctionExp(_token);break; - case _SC('@'): FunctionExp(_token,true);break; - case TK_CLASS: Lex(); ClassExp();break; - case _SC('-'): - Lex(); - switch(_token) { - case TK_INTEGER: EmitLoadConstInt(-_lex._nvalue,-1); Lex(); break; - case TK_FLOAT: EmitLoadConstFloat(-_lex._fvalue,-1); Lex(); break; - default: UnaryOP(_OP_NEG); - } - break; - case _SC('!'): Lex(); UnaryOP(_OP_NOT); break; - case _SC('~'): - Lex(); - if(_token == TK_INTEGER) { EmitLoadConstInt(~_lex._nvalue,-1); Lex(); break; } - UnaryOP(_OP_BWNOT); - break; - case TK_TYPEOF : Lex() ;UnaryOP(_OP_TYPEOF); break; - case TK_RESUME : Lex(); UnaryOP(_OP_RESUME); break; - case TK_CLONE : Lex(); UnaryOP(_OP_CLONE); break; - case TK_MINUSMINUS : - case TK_PLUSPLUS :PrefixIncDec(_token); break; - case TK_DELETE : DeleteExpr(); break; - case _SC('('): Lex(); CommaExpr(); Expect(_SC(')')); - break; - default: Error(_SC("expression expected")); - } - return -1; - } - void EmitLoadConstInt(SQInteger value,SQInteger target) - { - if(target < 0) { - target = _fs->PushTarget(); - } - if((value & (~((SQInteger)0xFFFFFFFF))) == 0) { //does it fit in 32 bits? - _fs->AddInstruction(_OP_LOADINT, target,value); - } - else { - _fs->AddInstruction(_OP_LOAD, target, _fs->GetNumericConstant(value)); - } - } - void EmitLoadConstFloat(SQFloat value,SQInteger target) - { - if(target < 0) { - target = _fs->PushTarget(); - } - if(sizeof(SQFloat) == sizeof(SQInt32)) { - _fs->AddInstruction(_OP_LOADFLOAT, target,*((SQInt32 *)&value)); - } - else { - _fs->AddInstruction(_OP_LOAD, target, _fs->GetNumericConstant(value)); - } - } - void UnaryOP(SQOpcode op) - { - PrefixedExpr(); - SQInteger src = _fs->PopTarget(); - _fs->AddInstruction(op, _fs->PushTarget(), src); - } - bool NeedGet() - { - switch(_token) { - case _SC('='): case _SC('('): case TK_NEWSLOT: case TK_MODEQ: case TK_MULEQ: - case TK_DIVEQ: case TK_MINUSEQ: case TK_PLUSEQ: case TK_PLUSPLUS: case TK_MINUSMINUS: - return false; - } - return (!_es.donot_get || ( _es.donot_get && (_token == _SC('.') || _token == _SC('[')))); - } - void FunctionCallArgs() - { - SQInteger nargs = 1;//this - while(_token != _SC(')')) { - Expression(); - MoveIfCurrentTargetIsLocal(); - nargs++; - if(_token == _SC(',')){ - Lex(); - if(_token == ')') Error(_SC("expression expected, found ')'")); - } - } - Lex(); - for(SQInteger i = 0; i < (nargs - 1); i++) _fs->PopTarget(); - SQInteger stackbase = _fs->PopTarget(); - SQInteger closure = _fs->PopTarget(); - _fs->AddInstruction(_OP_CALL, _fs->PushTarget(), closure, stackbase, nargs); - } - void ParseTableOrClass(SQInteger separator,SQInteger terminator) - { - SQInteger tpos = _fs->GetCurrentPos(),nkeys = 0; - while(_token != terminator) { - bool hasattrs = false; - bool isstatic = false; - //check if is an attribute - if(separator == ';') { - if(_token == TK_ATTR_OPEN) { - _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE); Lex(); - ParseTableOrClass(',',TK_ATTR_CLOSE); - hasattrs = true; - } - if(_token == TK_STATIC) { - isstatic = true; - Lex(); - } - } - switch(_token) { - case TK_FUNCTION: - case TK_CONSTRUCTOR:{ - SQInteger tk = _token; - Lex(); - SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor")); - Expect(_SC('(')); - _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); - CreateFunction(id); - _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0); - } - break; - case _SC('['): - Lex(); CommaExpr(); Expect(_SC(']')); - Expect(_SC('=')); Expression(); - break; - case TK_STRING_LITERAL: //JSON - if(separator == ',') { //only works for tables - _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_STRING_LITERAL))); - Expect(_SC(':')); Expression(); - break; - } - default : - _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER))); - Expect(_SC('=')); Expression(); - } - if(_token == separator) Lex();//optional comma/semicolon - nkeys++; - SQInteger val = _fs->PopTarget(); - SQInteger key = _fs->PopTarget(); - SQInteger attrs = hasattrs ? _fs->PopTarget():-1; - assert((hasattrs && (attrs == key-1)) || !hasattrs); - unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0); - SQInteger table = _fs->TopTarget(); //<AddInstruction(_OP_NEWSLOT, 0xFF, table, key, val); - } - else { - _fs->AddInstruction(_OP_NEWSLOTA, flags, table, key, val); //this for classes only as it invokes _newmember - } - } - if(separator == _SC(',')) //hack recognizes a table from the separator - _fs->SetIntructionParam(tpos, 1, nkeys); - Lex(); - } - void LocalDeclStatement() - { - SQObject varname; - Lex(); - if( _token == TK_FUNCTION) { - Lex(); - varname = Expect(TK_IDENTIFIER); - Expect(_SC('(')); - CreateFunction(varname,false); - _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0); - _fs->PopTarget(); - _fs->PushLocalVariable(varname); - return; - } - - do { - varname = Expect(TK_IDENTIFIER); - if(_token == _SC('=')) { - Lex(); Expression(); - SQInteger src = _fs->PopTarget(); - SQInteger dest = _fs->PushTarget(); - if(dest != src) _fs->AddInstruction(_OP_MOVE, dest, src); - } - else{ - _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1); - } - _fs->PopTarget(); - _fs->PushLocalVariable(varname); - if(_token == _SC(',')) Lex(); else break; - } while(1); - } - void IfStatement() - { - SQInteger jmppos; - bool haselse = false; - Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); - _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); - SQInteger jnepos = _fs->GetCurrentPos(); - BEGIN_SCOPE(); - - Statement(); - // - if(_token != _SC('}') && _token != TK_ELSE) OptionalSemicolon(); - - END_SCOPE(); - SQInteger endifblock = _fs->GetCurrentPos(); - if(_token == TK_ELSE){ - haselse = true; - BEGIN_SCOPE(); - _fs->AddInstruction(_OP_JMP); - jmppos = _fs->GetCurrentPos(); - Lex(); - Statement(); OptionalSemicolon(); - END_SCOPE(); - _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos); - } - _fs->SetIntructionParam(jnepos, 1, endifblock - jnepos + (haselse?1:0)); - } - void WhileStatement() - { - SQInteger jzpos, jmppos; - jmppos = _fs->GetCurrentPos(); - Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); - - BEGIN_BREAKBLE_BLOCK(); - _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); - jzpos = _fs->GetCurrentPos(); - BEGIN_SCOPE(); - - Statement(); - - END_SCOPE(); - _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1); - _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos); - - END_BREAKBLE_BLOCK(jmppos); - } - void DoWhileStatement() - { - Lex(); - SQInteger jmptrg = _fs->GetCurrentPos(); - BEGIN_BREAKBLE_BLOCK() - BEGIN_SCOPE(); - Statement(); - END_SCOPE(); - Expect(TK_WHILE); - SQInteger continuetrg = _fs->GetCurrentPos(); - Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); - _fs->AddInstruction(_OP_JZ, _fs->PopTarget(), 1); - _fs->AddInstruction(_OP_JMP, 0, jmptrg - _fs->GetCurrentPos() - 1); - END_BREAKBLE_BLOCK(continuetrg); - } - void ForStatement() - { - Lex(); - BEGIN_SCOPE(); - Expect(_SC('(')); - if(_token == TK_LOCAL) LocalDeclStatement(); - else if(_token != _SC(';')){ - CommaExpr(); - _fs->PopTarget(); - } - Expect(_SC(';')); - _fs->SnoozeOpt(); - SQInteger jmppos = _fs->GetCurrentPos(); - SQInteger jzpos = -1; - if(_token != _SC(';')) { CommaExpr(); _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); jzpos = _fs->GetCurrentPos(); } - Expect(_SC(';')); - _fs->SnoozeOpt(); - SQInteger expstart = _fs->GetCurrentPos() + 1; - if(_token != _SC(')')) { - CommaExpr(); - _fs->PopTarget(); - } - Expect(_SC(')')); - _fs->SnoozeOpt(); - SQInteger expend = _fs->GetCurrentPos(); - SQInteger expsize = (expend - expstart) + 1; - SQInstructionVec exp; - if(expsize > 0) { - for(SQInteger i = 0; i < expsize; i++) - exp.push_back(_fs->GetInstruction(expstart + i)); - _fs->PopInstructions(expsize); - } - BEGIN_BREAKBLE_BLOCK() - Statement(); - SQInteger continuetrg = _fs->GetCurrentPos(); - if(expsize > 0) { - for(SQInteger i = 0; i < expsize; i++) - _fs->AddInstruction(exp[i]); - } - _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1, 0); - if(jzpos> 0) _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos); - END_SCOPE(); - - END_BREAKBLE_BLOCK(continuetrg); - } - void ForEachStatement() - { - SQObject idxname, valname; - Lex(); Expect(_SC('(')); valname = Expect(TK_IDENTIFIER); - if(_token == _SC(',')) { - idxname = valname; - Lex(); valname = Expect(TK_IDENTIFIER); - } - else{ - idxname = _fs->CreateString(_SC("@INDEX@")); - } - Expect(TK_IN); - - //save the stack size - BEGIN_SCOPE(); - //put the table in the stack(evaluate the table expression) - Expression(); Expect(_SC(')')); - SQInteger container = _fs->TopTarget(); - //push the index local var - SQInteger indexpos = _fs->PushLocalVariable(idxname); - _fs->AddInstruction(_OP_LOADNULLS, indexpos,1); - //push the value local var - SQInteger valuepos = _fs->PushLocalVariable(valname); - _fs->AddInstruction(_OP_LOADNULLS, valuepos,1); - //push reference index - SQInteger itrpos = _fs->PushLocalVariable(_fs->CreateString(_SC("@ITERATOR@"))); //use invalid id to make it inaccessible - _fs->AddInstruction(_OP_LOADNULLS, itrpos,1); - SQInteger jmppos = _fs->GetCurrentPos(); - _fs->AddInstruction(_OP_FOREACH, container, 0, indexpos); - SQInteger foreachpos = _fs->GetCurrentPos(); - _fs->AddInstruction(_OP_POSTFOREACH, container, 0, indexpos); - //generate the statement code - BEGIN_BREAKBLE_BLOCK() - Statement(); - _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1); - _fs->SetIntructionParam(foreachpos, 1, _fs->GetCurrentPos() - foreachpos); - _fs->SetIntructionParam(foreachpos + 1, 1, _fs->GetCurrentPos() - foreachpos); - END_BREAKBLE_BLOCK(foreachpos - 1); - //restore the local variable stack(remove index,val and ref idx) - END_SCOPE(); - } - void SwitchStatement() - { - Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); - Expect(_SC('{')); - SQInteger expr = _fs->TopTarget(); - bool bfirst = true; - SQInteger tonextcondjmp = -1; - SQInteger skipcondjmp = -1; - SQInteger __nbreaks__ = _fs->_unresolvedbreaks.size(); - _fs->_breaktargets.push_back(0); - while(_token == TK_CASE) { - if(!bfirst) { - _fs->AddInstruction(_OP_JMP, 0, 0); - skipcondjmp = _fs->GetCurrentPos(); - _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp); - } - //condition - Lex(); Expression(); Expect(_SC(':')); - SQInteger trg = _fs->PopTarget(); - _fs->AddInstruction(_OP_EQ, trg, trg, expr); - _fs->AddInstruction(_OP_JZ, trg, 0); - //end condition - if(skipcondjmp != -1) { - _fs->SetIntructionParam(skipcondjmp, 1, (_fs->GetCurrentPos() - skipcondjmp)); - } - tonextcondjmp = _fs->GetCurrentPos(); - BEGIN_SCOPE(); - Statements(); - END_SCOPE(); - bfirst = false; - } - if(tonextcondjmp != -1) - _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp); - if(_token == TK_DEFAULT) { - Lex(); Expect(_SC(':')); - BEGIN_SCOPE(); - Statements(); - END_SCOPE(); - } - Expect(_SC('}')); - _fs->PopTarget(); - __nbreaks__ = _fs->_unresolvedbreaks.size() - __nbreaks__; - if(__nbreaks__ > 0)ResolveBreaks(_fs, __nbreaks__); - _fs->_breaktargets.pop_back(); - } - void FunctionStatement() - { - SQObject id; - Lex(); id = Expect(TK_IDENTIFIER); - _fs->PushTarget(0); - _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); - if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET); - - while(_token == TK_DOUBLE_COLON) { - Lex(); - id = Expect(TK_IDENTIFIER); - _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); - if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET); - } - Expect(_SC('(')); - CreateFunction(id); - _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0); - EmitDerefOp(_OP_NEWSLOT); - _fs->PopTarget(); - } - void ClassStatement() - { - SQExpState es; - Lex(); - es = _es; - _es.donot_get = true; - PrefixedExpr(); - if(_es.etype == EXPR) { - Error(_SC("invalid class name")); - } - else if(_es.etype == OBJECT || _es.etype == BASE) { - ClassExp(); - EmitDerefOp(_OP_NEWSLOT); - _fs->PopTarget(); - } - else { - Error(_SC("cannot create a class in a local with the syntax(class )")); - } - _es = es; - } - SQObject ExpectScalar() - { - SQObject val; - val._type = OT_NULL; val._unVal.nInteger = 0; //shut up GCC 4.x - switch(_token) { - case TK_INTEGER: - val._type = OT_INTEGER; - val._unVal.nInteger = _lex._nvalue; - break; - case TK_FLOAT: - val._type = OT_FLOAT; - val._unVal.fFloat = _lex._fvalue; - break; - case TK_STRING_LITERAL: - val = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1); - break; - case '-': - Lex(); - switch(_token) - { - case TK_INTEGER: - val._type = OT_INTEGER; - val._unVal.nInteger = -_lex._nvalue; - break; - case TK_FLOAT: - val._type = OT_FLOAT; - val._unVal.fFloat = -_lex._fvalue; - break; - default: - Error(_SC("scalar expected : integer,float")); - } - break; - default: - Error(_SC("scalar expected : integer,float or string")); - } - Lex(); - return val; - } - void EnumStatement() - { - Lex(); - SQObject id = Expect(TK_IDENTIFIER); - Expect(_SC('{')); - - SQObject table = _fs->CreateTable(); - SQInteger nval = 0; - while(_token != _SC('}')) { - SQObject key = Expect(TK_IDENTIFIER); - SQObject val; - if(_token == _SC('=')) { - Lex(); - val = ExpectScalar(); - } - else { - val._type = OT_INTEGER; - val._unVal.nInteger = nval++; - } - _table(table)->NewSlot(SQObjectPtr(key),SQObjectPtr(val)); - if(_token == ',') Lex(); - } - SQTable *enums = _table(_ss(_vm)->_consts); - SQObjectPtr strongid = id; - enums->NewSlot(SQObjectPtr(strongid),SQObjectPtr(table)); - strongid.Null(); - Lex(); - } - void TryCatchStatement() - { - SQObject exid; - Lex(); - _fs->AddInstruction(_OP_PUSHTRAP,0,0); - _fs->_traps++; - if(_fs->_breaktargets.size()) _fs->_breaktargets.top()++; - if(_fs->_continuetargets.size()) _fs->_continuetargets.top()++; - SQInteger trappos = _fs->GetCurrentPos(); - { - BEGIN_SCOPE(); - Statement(); - END_SCOPE(); - } - _fs->_traps--; - _fs->AddInstruction(_OP_POPTRAP, 1, 0); - if(_fs->_breaktargets.size()) _fs->_breaktargets.top()--; - if(_fs->_continuetargets.size()) _fs->_continuetargets.top()--; - _fs->AddInstruction(_OP_JMP, 0, 0); - SQInteger jmppos = _fs->GetCurrentPos(); - _fs->SetIntructionParam(trappos, 1, (_fs->GetCurrentPos() - trappos)); - Expect(TK_CATCH); Expect(_SC('(')); exid = Expect(TK_IDENTIFIER); Expect(_SC(')')); - { - BEGIN_SCOPE(); - SQInteger ex_target = _fs->PushLocalVariable(exid); - _fs->SetIntructionParam(trappos, 0, ex_target); - Statement(); - _fs->SetIntructionParams(jmppos, 0, (_fs->GetCurrentPos() - jmppos), 0); - END_SCOPE(); - } - } - void FunctionExp(SQInteger ftype,bool lambda = false) - { - Lex(); Expect(_SC('(')); - SQObjectPtr dummy; - CreateFunction(dummy,lambda); - _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, ftype == TK_FUNCTION?0:1); - } - void ClassExp() - { - SQInteger base = -1; - SQInteger attrs = -1; - if(_token == TK_EXTENDS) { - Lex(); Expression(); - base = _fs->TopTarget(); - } - if(_token == TK_ATTR_OPEN) { - Lex(); - _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE); - ParseTableOrClass(_SC(','),TK_ATTR_CLOSE); - attrs = _fs->TopTarget(); - } - Expect(_SC('{')); - if(attrs != -1) _fs->PopTarget(); - if(base != -1) _fs->PopTarget(); - _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(), base, attrs,NOT_CLASS); - ParseTableOrClass(_SC(';'),_SC('}')); - } - void DeleteExpr() - { - SQExpState es; - Lex(); - es = _es; - _es.donot_get = true; - PrefixedExpr(); - if(_es.etype==EXPR) Error(_SC("can't delete an expression")); - if(_es.etype==OBJECT || _es.etype==BASE) { - Emit2ArgsOP(_OP_DELETE); - } - else { - Error(_SC("cannot delete an (outer) local")); - } - _es = es; - } - void PrefixIncDec(SQInteger token) - { - SQExpState es; - SQInteger diff = (token==TK_MINUSMINUS) ? -1 : 1; - Lex(); - es = _es; - _es.donot_get = true; - PrefixedExpr(); - if(_es.etype==EXPR) { - Error(_SC("can't '++' or '--' an expression")); - } - else if(_es.etype==OBJECT || _es.etype==BASE) { - Emit2ArgsOP(_OP_INC, diff); - } - else if(_es.etype==LOCAL) { - SQInteger src = _fs->TopTarget(); - _fs->AddInstruction(_OP_INCL, src, src, 0, diff); - - } - else if(_es.etype==OUTER) { - SQInteger tmp = _fs->PushTarget(); - _fs->AddInstruction(_OP_GETOUTER, tmp, _es.epos); - _fs->AddInstruction(_OP_INCL, tmp, tmp, 0, diff); - _fs->AddInstruction(_OP_SETOUTER, tmp, _es.epos, tmp); - } - _es = es; - } - void CreateFunction(SQObject &name,bool lambda = false) - { - SQFuncState *funcstate = _fs->PushChildState(_ss(_vm)); - funcstate->_name = name; - SQObject paramname; - funcstate->AddParameter(_fs->CreateString(_SC("this"))); - funcstate->_sourcename = _sourcename; - SQInteger defparams = 0; - while(_token!=_SC(')')) { - if(_token == TK_VARPARAMS) { - if(defparams > 0) Error(_SC("function with default parameters cannot have variable number of parameters")); - funcstate->AddParameter(_fs->CreateString(_SC("vargv"))); - funcstate->_varparams = true; - Lex(); - if(_token != _SC(')')) Error(_SC("expected ')'")); - break; - } - else { - paramname = Expect(TK_IDENTIFIER); - funcstate->AddParameter(paramname); - if(_token == _SC('=')) { - Lex(); - Expression(); - funcstate->AddDefaultParam(_fs->TopTarget()); - defparams++; - } - else { - if(defparams > 0) Error(_SC("expected '='")); - } - if(_token == _SC(',')) Lex(); - else if(_token != _SC(')')) Error(_SC("expected ')' or ','")); - } - } - Expect(_SC(')')); - for(SQInteger n = 0; n < defparams; n++) { - _fs->PopTarget(); - } - - SQFuncState *currchunk = _fs; - _fs = funcstate; - if(lambda) { - Expression(); - _fs->AddInstruction(_OP_RETURN, 1, _fs->PopTarget());} - else { - Statement(false); - } - funcstate->AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true); - funcstate->AddInstruction(_OP_RETURN, -1); - funcstate->SetStackSize(0); - - SQFunctionProto *func = funcstate->BuildProto(); -#ifdef _DEBUG_DUMP - funcstate->Dump(func); -#endif - _fs = currchunk; - _fs->_functions.push_back(func); - _fs->PopChildState(); - } - void ResolveBreaks(SQFuncState *funcstate, SQInteger ntoresolve) - { - while(ntoresolve > 0) { - SQInteger pos = funcstate->_unresolvedbreaks.back(); - funcstate->_unresolvedbreaks.pop_back(); - //set the jmp instruction - funcstate->SetIntructionParams(pos, 0, funcstate->GetCurrentPos() - pos, 0); - ntoresolve--; - } - } - void ResolveContinues(SQFuncState *funcstate, SQInteger ntoresolve, SQInteger targetpos) - { - while(ntoresolve > 0) { - SQInteger pos = funcstate->_unresolvedcontinues.back(); - funcstate->_unresolvedcontinues.pop_back(); - //set the jmp instruction - funcstate->SetIntructionParams(pos, 0, targetpos - pos, 0); - ntoresolve--; - } - } -private: - SQInteger _token; - SQFuncState *_fs; - SQObjectPtr _sourcename; - SQLexer _lex; - bool _lineinfo; - bool _raiseerror; - SQInteger _debugline; - SQInteger _debugop; - SQExpState _es; - SQScope _scope; - SQChar *compilererror; - jmp_buf _errorjmp; - SQVM *_vm; -}; - -bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo) -{ - SQCompiler p(vm, rg, up, sourcename, raiseerror, lineinfo); - return p.Compile(out); -} - -#endif +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#ifndef NO_COMPILER +#include +#include +#include "sqopcodes.h" +#include "sqstring.h" +#include "sqfuncproto.h" +#include "sqcompiler.h" +#include "sqfuncstate.h" +#include "sqlexer.h" +#include "sqvm.h" +#include "sqtable.h" + +#define EXPR 1 +#define OBJECT 2 +#define BASE 3 +#define LOCAL 4 +#define OUTER 5 + +struct SQExpState { + SQInteger etype; /* expr. type; one of EXPR, OBJECT, BASE, OUTER or LOCAL */ + SQInteger epos; /* expr. location on stack; -1 for OBJECT and BASE */ + bool donot_get; /* signal not to deref the next value */ +}; + +struct SQScope { + SQInteger outers; + SQInteger stacksize; +}; + +#define BEGIN_SCOPE() SQScope __oldscope__ = _scope; \ + _scope.outers = _fs->_outers; \ + _scope.stacksize = _fs->GetStackSize(); + +#define RESOLVE_OUTERS() if(_fs->GetStackSize() != _scope.stacksize) { \ + if(_fs->CountOuters(_scope.stacksize)) { \ + _fs->AddInstruction(_OP_CLOSE,0,_scope.stacksize); \ + } \ + } + +#define END_SCOPE_NO_CLOSE() { if(_fs->GetStackSize() != _scope.stacksize) { \ + _fs->SetStackSize(_scope.stacksize); \ + } \ + _scope = __oldscope__; \ + } + +#define END_SCOPE() { SQInteger oldouters = _fs->_outers;\ + if(_fs->GetStackSize() != _scope.stacksize) { \ + _fs->SetStackSize(_scope.stacksize); \ + if(oldouters != _fs->_outers) { \ + _fs->AddInstruction(_OP_CLOSE,0,_scope.stacksize); \ + } \ + } \ + _scope = __oldscope__; \ + } + +#define BEGIN_BREAKBLE_BLOCK() SQInteger __nbreaks__=_fs->_unresolvedbreaks.size(); \ + SQInteger __ncontinues__=_fs->_unresolvedcontinues.size(); \ + _fs->_breaktargets.push_back(0);_fs->_continuetargets.push_back(0); + +#define END_BREAKBLE_BLOCK(continue_target) {__nbreaks__=_fs->_unresolvedbreaks.size()-__nbreaks__; \ + __ncontinues__=_fs->_unresolvedcontinues.size()-__ncontinues__; \ + if(__ncontinues__>0)ResolveContinues(_fs,__ncontinues__,continue_target); \ + if(__nbreaks__>0)ResolveBreaks(_fs,__nbreaks__); \ + _fs->_breaktargets.pop_back();_fs->_continuetargets.pop_back();} + +class SQCompiler +{ +public: + SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo) + { + _vm=v; + _lex.Init(_ss(v), rg, up,ThrowError,this); + _sourcename = SQString::Create(_ss(v), sourcename); + _lineinfo = lineinfo;_raiseerror = raiseerror; + _scope.outers = 0; + _scope.stacksize = 0; + compilererror = NULL; + } + static void ThrowError(void *ud, const SQChar *s) { + SQCompiler *c = (SQCompiler *)ud; + c->Error(s); + } + void Error(const SQChar *s, ...) + { + static SQChar temp[256]; + va_list vl; + va_start(vl, s); + scvsprintf(temp, s, vl); + va_end(vl); + compilererror = temp; + longjmp(_errorjmp,1); + } + void Lex(){ _token = _lex.Lex();} + SQObject Expect(SQInteger tok) + { + + if(_token != tok) { + if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) { + //do nothing + } + else { + const SQChar *etypename; + if(tok > 255) { + switch(tok) + { + case TK_IDENTIFIER: + etypename = _SC("IDENTIFIER"); + break; + case TK_STRING_LITERAL: + etypename = _SC("STRING_LITERAL"); + break; + case TK_INTEGER: + etypename = _SC("INTEGER"); + break; + case TK_FLOAT: + etypename = _SC("FLOAT"); + break; + default: + etypename = _lex.Tok2Str(tok); + } + Error(_SC("expected '%s'"), etypename); + } + Error(_SC("expected '%c'"), tok); + } + } + SQObjectPtr ret; + switch(tok) + { + case TK_IDENTIFIER: + ret = _fs->CreateString(_lex._svalue); + break; + case TK_STRING_LITERAL: + ret = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1); + break; + case TK_INTEGER: + ret = SQObjectPtr(_lex._nvalue); + break; + case TK_FLOAT: + ret = SQObjectPtr(_lex._fvalue); + break; + } + Lex(); + return ret; + } + bool IsEndOfStatement() { return ((_lex._prevtoken == _SC('\n')) || (_token == SQUIRREL_EOB) || (_token == _SC('}')) || (_token == _SC(';'))); } + void OptionalSemicolon() + { + if(_token == _SC(';')) { Lex(); return; } + if(!IsEndOfStatement()) { + Error(_SC("end of statement expected (; or lf)")); + } + } + void MoveIfCurrentTargetIsLocal() { + SQInteger trg = _fs->TopTarget(); + if(_fs->IsLocal(trg)) { + trg = _fs->PopTarget(); //no pops the target and move it + _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), trg); + } + } + bool Compile(SQObjectPtr &o) + { + _debugline = 1; + _debugop = 0; + + SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this); + funcstate._name = SQString::Create(_ss(_vm), _SC("main")); + _fs = &funcstate; + _fs->AddParameter(_fs->CreateString(_SC("this"))); + _fs->AddParameter(_fs->CreateString(_SC("vargv"))); + _fs->_varparams = true; + _fs->_sourcename = _sourcename; + SQInteger stacksize = _fs->GetStackSize(); + if(setjmp(_errorjmp) == 0) { + Lex(); + while(_token > 0){ + Statement(); + if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon(); + } + _fs->SetStackSize(stacksize); + _fs->AddLineInfos(_lex._currentline, _lineinfo, true); + _fs->AddInstruction(_OP_RETURN, 0xFF); + _fs->SetStackSize(0); + o =_fs->BuildProto(); +#ifdef _DEBUG_DUMP + _fs->Dump(_funcproto(o)); +#endif + } + else { + if(_raiseerror && _ss(_vm)->_compilererrorhandler) { + _ss(_vm)->_compilererrorhandler(_vm, compilererror, type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"), + _lex._currentline, _lex._currentcolumn); + } + _vm->_lasterror = SQString::Create(_ss(_vm), compilererror, -1); + return false; + } + return true; + } + void Statements() + { + while(_token != _SC('}') && _token != TK_DEFAULT && _token != TK_CASE) { + Statement(); + if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon(); + } + } + void Statement(bool closeframe = true) + { + _fs->AddLineInfos(_lex._currentline, _lineinfo); + switch(_token){ + case _SC(';'): Lex(); break; + case TK_IF: IfStatement(); break; + case TK_WHILE: WhileStatement(); break; + case TK_DO: DoWhileStatement(); break; + case TK_FOR: ForStatement(); break; + case TK_FOREACH: ForEachStatement(); break; + case TK_SWITCH: SwitchStatement(); break; + case TK_LOCAL: LocalDeclStatement(); break; + case TK_RETURN: + case TK_YIELD: { + SQOpcode op; + if(_token == TK_RETURN) { + op = _OP_RETURN; + } + else { + op = _OP_YIELD; + _fs->_bgenerator = true; + } + Lex(); + if(!IsEndOfStatement()) { + SQInteger retexp = _fs->GetCurrentPos()+1; + CommaExpr(); + if(op == _OP_RETURN && _fs->_traps > 0) + _fs->AddInstruction(_OP_POPTRAP, _fs->_traps, 0); + _fs->_returnexp = retexp; + _fs->AddInstruction(op, 1, _fs->PopTarget(),_fs->GetStackSize()); + } + else{ + if(op == _OP_RETURN && _fs->_traps > 0) + _fs->AddInstruction(_OP_POPTRAP, _fs->_traps ,0); + _fs->_returnexp = -1; + _fs->AddInstruction(op, 0xFF,0,_fs->GetStackSize()); + } + break;} + case TK_BREAK: + if(_fs->_breaktargets.size() <= 0)Error(_SC("'break' has to be in a loop block")); + if(_fs->_breaktargets.top() > 0){ + _fs->AddInstruction(_OP_POPTRAP, _fs->_breaktargets.top(), 0); + } + RESOLVE_OUTERS(); + _fs->AddInstruction(_OP_JMP, 0, -1234); + _fs->_unresolvedbreaks.push_back(_fs->GetCurrentPos()); + Lex(); + break; + case TK_CONTINUE: + if(_fs->_continuetargets.size() <= 0)Error(_SC("'continue' has to be in a loop block")); + if(_fs->_continuetargets.top() > 0) { + _fs->AddInstruction(_OP_POPTRAP, _fs->_continuetargets.top(), 0); + } + RESOLVE_OUTERS(); + _fs->AddInstruction(_OP_JMP, 0, -1234); + _fs->_unresolvedcontinues.push_back(_fs->GetCurrentPos()); + Lex(); + break; + case TK_FUNCTION: + FunctionStatement(); + break; + case TK_CLASS: + ClassStatement(); + break; + case TK_ENUM: + EnumStatement(); + break; + case _SC('{'):{ + BEGIN_SCOPE(); + Lex(); + Statements(); + Expect(_SC('}')); + if(closeframe) { + END_SCOPE(); + } + else { + END_SCOPE_NO_CLOSE(); + } + } + break; + case TK_TRY: + TryCatchStatement(); + break; + case TK_THROW: + Lex(); + CommaExpr(); + _fs->AddInstruction(_OP_THROW, _fs->PopTarget()); + break; + case TK_CONST: + { + Lex(); + SQObject id = Expect(TK_IDENTIFIER); + Expect('='); + SQObject val = ExpectScalar(); + OptionalSemicolon(); + SQTable *enums = _table(_ss(_vm)->_consts); + SQObjectPtr strongid = id; + enums->NewSlot(strongid,SQObjectPtr(val)); + strongid.Null(); + } + break; + default: + CommaExpr(); + _fs->DiscardTarget(); + //_fs->PopTarget(); + break; + } + _fs->SnoozeOpt(); + } + void EmitDerefOp(SQOpcode op) + { + SQInteger val = _fs->PopTarget(); + SQInteger key = _fs->PopTarget(); + SQInteger src = _fs->PopTarget(); + _fs->AddInstruction(op,_fs->PushTarget(),src,key,val); + } + void Emit2ArgsOP(SQOpcode op, SQInteger p3 = 0) + { + SQInteger p2 = _fs->PopTarget(); //src in OP_GET + SQInteger p1 = _fs->PopTarget(); //key in OP_GET + _fs->AddInstruction(op,_fs->PushTarget(), p1, p2, p3); + } + void EmitCompoundArith(SQInteger tok, SQInteger etype, SQInteger pos) + { + /* Generate code depending on the expression type */ + switch(etype) { + case LOCAL:{ + SQInteger p2 = _fs->PopTarget(); //src in OP_GET + SQInteger p1 = _fs->PopTarget(); //key in OP_GET + _fs->PushTarget(p1); + //EmitCompArithLocal(tok, p1, p1, p2); + _fs->AddInstruction(ChooseArithOpByToken(tok),p1, p2, p1, 0); + } + break; + case OBJECT: + case BASE: + { + SQInteger val = _fs->PopTarget(); + SQInteger key = _fs->PopTarget(); + SQInteger src = _fs->PopTarget(); + /* _OP_COMPARITH mixes dest obj and source val in the arg1 */ + _fs->AddInstruction(_OP_COMPARITH, _fs->PushTarget(), (src<<16)|val, key, ChooseCompArithCharByToken(tok)); + } + break; + case OUTER: + { + SQInteger val = _fs->TopTarget(); + SQInteger tmp = _fs->PushTarget(); + _fs->AddInstruction(_OP_GETOUTER, tmp, pos); + _fs->AddInstruction(ChooseArithOpByToken(tok), tmp, val, tmp, 0); + _fs->AddInstruction(_OP_SETOUTER, tmp, pos, tmp); + } + break; + } + } + void CommaExpr() + { + for(Expression();_token == ',';_fs->PopTarget(), Lex(), CommaExpr()); + } + void Expression() + { + SQExpState es = _es; + _es.etype = EXPR; + _es.epos = -1; + _es.donot_get = false; + LogicalOrExp(); + switch(_token) { + case _SC('='): + case TK_NEWSLOT: + case TK_MINUSEQ: + case TK_PLUSEQ: + case TK_MULEQ: + case TK_DIVEQ: + case TK_MODEQ:{ + SQInteger op = _token; + SQInteger ds = _es.etype; + SQInteger pos = _es.epos; + if(ds == EXPR) Error(_SC("can't assign expression")); + Lex(); Expression(); + + switch(op){ + case TK_NEWSLOT: + if(ds == OBJECT || ds == BASE) + EmitDerefOp(_OP_NEWSLOT); + else //if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local + Error(_SC("can't 'create' a local slot")); + break; + case _SC('='): //ASSIGN + switch(ds) { + case LOCAL: + { + SQInteger src = _fs->PopTarget(); + SQInteger dst = _fs->TopTarget(); + _fs->AddInstruction(_OP_MOVE, dst, src); + } + break; + case OBJECT: + case BASE: + EmitDerefOp(_OP_SET); + break; + case OUTER: + { + SQInteger src = _fs->PopTarget(); + SQInteger dst = _fs->PushTarget(); + _fs->AddInstruction(_OP_SETOUTER, dst, pos, src); + } + } + break; + case TK_MINUSEQ: + case TK_PLUSEQ: + case TK_MULEQ: + case TK_DIVEQ: + case TK_MODEQ: + EmitCompoundArith(op, ds, pos); + break; + } + } + break; + case _SC('?'): { + Lex(); + _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); + SQInteger jzpos = _fs->GetCurrentPos(); + SQInteger trg = _fs->PushTarget(); + Expression(); + SQInteger first_exp = _fs->PopTarget(); + if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); + SQInteger endfirstexp = _fs->GetCurrentPos(); + _fs->AddInstruction(_OP_JMP, 0, 0); + Expect(_SC(':')); + SQInteger jmppos = _fs->GetCurrentPos(); + Expression(); + SQInteger second_exp = _fs->PopTarget(); + if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); + _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos); + _fs->SetIntructionParam(jzpos, 1, endfirstexp - jzpos + 1); + _fs->SnoozeOpt(); + } + break; + } + _es = es; + } + template void BIN_EXP(SQOpcode op, T f,SQInteger op3 = 0) + { + Lex(); (this->*f)(); + SQInteger op1 = _fs->PopTarget();SQInteger op2 = _fs->PopTarget(); + _fs->AddInstruction(op, _fs->PushTarget(), op1, op2, op3); + } + void LogicalOrExp() + { + LogicalAndExp(); + for(;;) if(_token == TK_OR) { + SQInteger first_exp = _fs->PopTarget(); + SQInteger trg = _fs->PushTarget(); + _fs->AddInstruction(_OP_OR, trg, 0, first_exp, 0); + SQInteger jpos = _fs->GetCurrentPos(); + if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); + Lex(); LogicalOrExp(); + _fs->SnoozeOpt(); + SQInteger second_exp = _fs->PopTarget(); + if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); + _fs->SnoozeOpt(); + _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos)); + break; + }else return; + } + void LogicalAndExp() + { + BitwiseOrExp(); + for(;;) switch(_token) { + case TK_AND: { + SQInteger first_exp = _fs->PopTarget(); + SQInteger trg = _fs->PushTarget(); + _fs->AddInstruction(_OP_AND, trg, 0, first_exp, 0); + SQInteger jpos = _fs->GetCurrentPos(); + if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); + Lex(); LogicalAndExp(); + _fs->SnoozeOpt(); + SQInteger second_exp = _fs->PopTarget(); + if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); + _fs->SnoozeOpt(); + _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos)); + break; + } + case TK_IN: BIN_EXP(_OP_EXISTS, &SQCompiler::BitwiseOrExp); break; + case TK_INSTANCEOF: BIN_EXP(_OP_INSTANCEOF, &SQCompiler::BitwiseOrExp); break; + default: + return; + } + } + void BitwiseOrExp() + { + BitwiseXorExp(); + for(;;) if(_token == _SC('|')) + {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseXorExp,BW_OR); + }else return; + } + void BitwiseXorExp() + { + BitwiseAndExp(); + for(;;) if(_token == _SC('^')) + {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseAndExp,BW_XOR); + }else return; + } + void BitwiseAndExp() + { + EqExp(); + for(;;) if(_token == _SC('&')) + {BIN_EXP(_OP_BITW, &SQCompiler::EqExp,BW_AND); + }else return; + } + void EqExp() + { + CompExp(); + for(;;) switch(_token) { + case TK_EQ: BIN_EXP(_OP_EQ, &SQCompiler::CompExp); break; + case TK_NE: BIN_EXP(_OP_NE, &SQCompiler::CompExp); break; + case TK_3WAYSCMP: BIN_EXP(_OP_CMP, &SQCompiler::CompExp,CMP_3W); break; + default: return; + } + } + void CompExp() + { + ShiftExp(); + for(;;) switch(_token) { + case _SC('>'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_G); break; + case _SC('<'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_L); break; + case TK_GE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_GE); break; + case TK_LE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_LE); break; + default: return; + } + } + void ShiftExp() + { + PlusExp(); + for(;;) switch(_token) { + case TK_USHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_USHIFTR); break; + case TK_SHIFTL: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTL); break; + case TK_SHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTR); break; + default: return; + } + } + SQOpcode ChooseArithOpByToken(SQInteger tok) + { + switch(tok) { + case TK_PLUSEQ: case '+': return _OP_ADD; + case TK_MINUSEQ: case '-': return _OP_SUB; + case TK_MULEQ: case '*': return _OP_MUL; + case TK_DIVEQ: case '/': return _OP_DIV; + case TK_MODEQ: case '%': return _OP_MOD; + default: assert(0); + } + return _OP_ADD; + } + SQInteger ChooseCompArithCharByToken(SQInteger tok) + { + SQInteger oper; + switch(tok){ + case TK_MINUSEQ: oper = '-'; break; + case TK_PLUSEQ: oper = '+'; break; + case TK_MULEQ: oper = '*'; break; + case TK_DIVEQ: oper = '/'; break; + case TK_MODEQ: oper = '%'; break; + default: oper = 0; //shut up compiler + assert(0); break; + }; + return oper; + } + void PlusExp() + { + MultExp(); + for(;;) switch(_token) { + case _SC('+'): case _SC('-'): + BIN_EXP(ChooseArithOpByToken(_token), &SQCompiler::MultExp); break; + default: return; + } + } + + void MultExp() + { + PrefixedExpr(); + for(;;) switch(_token) { + case _SC('*'): case _SC('/'): case _SC('%'): + BIN_EXP(ChooseArithOpByToken(_token), &SQCompiler::PrefixedExpr); break; + default: return; + } + } + //if 'pos' != -1 the previous variable is a local variable + void PrefixedExpr() + { + SQInteger pos = Factor(); + for(;;) { + switch(_token) { + case _SC('.'): + pos = -1; + Lex(); + + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER))); + if(_es.etype==BASE) { + Emit2ArgsOP(_OP_GET); + pos = _fs->TopTarget(); + _es.etype = EXPR; + _es.epos = pos; + } + else { + if(NeedGet()) { + Emit2ArgsOP(_OP_GET); + } + _es.etype = OBJECT; + } + break; + case _SC('['): + if(_lex._prevtoken == _SC('\n')) Error(_SC("cannot brake deref/or comma needed after [exp]=exp slot declaration")); + Lex(); Expression(); Expect(_SC(']')); + pos = -1; + if(_es.etype==BASE) { + Emit2ArgsOP(_OP_GET); + pos = _fs->TopTarget(); + _es.etype = EXPR; + _es.epos = pos; + } + else { + if(NeedGet()) { + Emit2ArgsOP(_OP_GET); + } + _es.etype = OBJECT; + } + break; + case TK_MINUSMINUS: + case TK_PLUSPLUS: + { + if(IsEndOfStatement()) return; + SQInteger diff = (_token==TK_MINUSMINUS) ? -1 : 1; + Lex(); + switch(_es.etype) + { + case EXPR: Error(_SC("can't '++' or '--' an expression")); break; + case OBJECT: + case BASE: + Emit2ArgsOP(_OP_PINC, diff); + break; + case LOCAL: { + SQInteger src = _fs->PopTarget(); + _fs->AddInstruction(_OP_PINCL, _fs->PushTarget(), src, 0, diff); + } + break; + case OUTER: { + SQInteger tmp1 = _fs->PushTarget(); + SQInteger tmp2 = _fs->PushTarget(); + _fs->AddInstruction(_OP_GETOUTER, tmp2, _es.epos); + _fs->AddInstruction(_OP_PINCL, tmp1, tmp2, 0, diff); + _fs->AddInstruction(_OP_SETOUTER, tmp2, _es.epos, tmp2); + _fs->PopTarget(); + } + } + } + return; + break; + case _SC('('): + switch(_es.etype) { + case OBJECT: { + SQInteger key = _fs->PopTarget(); /* location of the key */ + SQInteger table = _fs->PopTarget(); /* location of the object */ + SQInteger closure = _fs->PushTarget(); /* location for the closure */ + SQInteger ttarget = _fs->PushTarget(); /* location for 'this' pointer */ + _fs->AddInstruction(_OP_PREPCALL, closure, key, table, ttarget); + } + break; + case BASE: + //Emit2ArgsOP(_OP_GET); + _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0); + break; + case OUTER: + _fs->AddInstruction(_OP_GETOUTER, _fs->PushTarget(), _es.epos); + _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0); + break; + default: + _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0); + } + _es.etype = EXPR; + Lex(); + FunctionCallArgs(); + break; + default: return; + } + } + } + SQInteger Factor() + { + _es.etype = EXPR; + switch(_token) + { + case TK_STRING_LITERAL: + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1))); + Lex(); + break; + case TK_BASE: + Lex(); + _fs->AddInstruction(_OP_GETBASE, _fs->PushTarget()); + _es.etype = BASE; + _es.epos = _fs->TopTarget(); + return (_es.epos); + break; + case TK_IDENTIFIER: + case TK_CONSTRUCTOR: + case TK_THIS:{ + SQObject id; + SQObject constant; + + switch(_token) { + case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break; + case TK_THIS: id = _fs->CreateString(_SC("this")); break; + case TK_CONSTRUCTOR: id = _fs->CreateString(_SC("constructor")); break; + } + + SQInteger pos = -1; + Lex(); + if((pos = _fs->GetLocalVariable(id)) != -1) { + /* Handle a local variable (includes 'this') */ + _fs->PushTarget(pos); + _es.etype = LOCAL; + _es.epos = pos; + } + + else if((pos = _fs->GetOuterVariable(id)) != -1) { + /* Handle a free var */ + if(NeedGet()) { + _es.epos = _fs->PushTarget(); + _fs->AddInstruction(_OP_GETOUTER, _es.epos, pos); + /* _es.etype = EXPR; already default value */ + } + else { + _es.etype = OUTER; + _es.epos = pos; + } + } + + else if(_fs->IsConstant(id, constant)) { + /* Handle named constant */ + SQObjectPtr constval; + SQObject constid; + if(type(constant) == OT_TABLE) { + Expect('.'); + constid = Expect(TK_IDENTIFIER); + if(!_table(constant)->Get(constid, constval)) { + constval.Null(); + Error(_SC("invalid constant [%s.%s]"), _stringval(id), _stringval(constid)); + } + } + else { + constval = constant; + } + _es.epos = _fs->PushTarget(); + + /* generate direct or literal function depending on size */ + SQObjectType ctype = type(constval); + switch(ctype) { + case OT_INTEGER: EmitLoadConstInt(_integer(constval),_es.epos); break; + case OT_FLOAT: EmitLoadConstFloat(_float(constval),_es.epos); break; + default: _fs->AddInstruction(_OP_LOAD,_es.epos,_fs->GetConstant(constval)); break; + } + _es.etype = EXPR; + } + else { + /* Handle a non-local variable, aka a field. Push the 'this' pointer on + * the virtual stack (always found in offset 0, so no instruction needs to + * be generated), and push the key next. Generate an _OP_LOAD instruction + * for the latter. If we are not using the variable as a dref expr, generate + * the _OP_GET instruction. + */ + _fs->PushTarget(0); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); + if(NeedGet()) { + Emit2ArgsOP(_OP_GET); + } + _es.etype = OBJECT; + } + return _es.epos; + } + break; + case TK_DOUBLE_COLON: // "::" + _fs->AddInstruction(_OP_LOADROOT, _fs->PushTarget()); + _es.etype = OBJECT; + _token = _SC('.'); /* hack: drop into PrefixExpr, case '.'*/ + _es.epos = -1; + return _es.epos; + break; + case TK_NULL: + _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1); + Lex(); + break; + case TK_INTEGER: EmitLoadConstInt(_lex._nvalue,-1); Lex(); break; + case TK_FLOAT: EmitLoadConstFloat(_lex._fvalue,-1); Lex(); break; + case TK_TRUE: case TK_FALSE: + _fs->AddInstruction(_OP_LOADBOOL, _fs->PushTarget(),_token == TK_TRUE?1:0); + Lex(); + break; + case _SC('['): { + _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,0,NOT_ARRAY); + SQInteger apos = _fs->GetCurrentPos(),key = 0; + Lex(); + while(_token != _SC(']')) { + Expression(); + if(_token == _SC(',')) Lex(); + SQInteger val = _fs->PopTarget(); + SQInteger array = _fs->TopTarget(); + _fs->AddInstruction(_OP_APPENDARRAY, array, val, AAT_STACK); + key++; + } + _fs->SetIntructionParam(apos, 1, key); + Lex(); + } + break; + case _SC('{'): + _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE); + Lex();ParseTableOrClass(_SC(','),_SC('}')); + break; + case TK_FUNCTION: FunctionExp(_token);break; + case _SC('@'): FunctionExp(_token,true);break; + case TK_CLASS: Lex(); ClassExp();break; + case _SC('-'): + Lex(); + switch(_token) { + case TK_INTEGER: EmitLoadConstInt(-_lex._nvalue,-1); Lex(); break; + case TK_FLOAT: EmitLoadConstFloat(-_lex._fvalue,-1); Lex(); break; + default: UnaryOP(_OP_NEG); + } + break; + case _SC('!'): Lex(); UnaryOP(_OP_NOT); break; + case _SC('~'): + Lex(); + if(_token == TK_INTEGER) { EmitLoadConstInt(~_lex._nvalue,-1); Lex(); break; } + UnaryOP(_OP_BWNOT); + break; + case TK_TYPEOF : Lex() ;UnaryOP(_OP_TYPEOF); break; + case TK_RESUME : Lex(); UnaryOP(_OP_RESUME); break; + case TK_CLONE : Lex(); UnaryOP(_OP_CLONE); break; + case TK_MINUSMINUS : + case TK_PLUSPLUS :PrefixIncDec(_token); break; + case TK_DELETE : DeleteExpr(); break; + case _SC('('): Lex(); CommaExpr(); Expect(_SC(')')); + break; + default: Error(_SC("expression expected")); + } + return -1; + } + void EmitLoadConstInt(SQInteger value,SQInteger target) + { + if(target < 0) { + target = _fs->PushTarget(); + } + if((value & (~((SQInteger)0xFFFFFFFF))) == 0) { //does it fit in 32 bits? + _fs->AddInstruction(_OP_LOADINT, target,value); + } + else { + _fs->AddInstruction(_OP_LOAD, target, _fs->GetNumericConstant(value)); + } + } + void EmitLoadConstFloat(SQFloat value,SQInteger target) + { + if(target < 0) { + target = _fs->PushTarget(); + } + if(sizeof(SQFloat) == sizeof(SQInt32)) { + _fs->AddInstruction(_OP_LOADFLOAT, target,*((SQInt32 *)&value)); + } + else { + _fs->AddInstruction(_OP_LOAD, target, _fs->GetNumericConstant(value)); + } + } + void UnaryOP(SQOpcode op) + { + PrefixedExpr(); + SQInteger src = _fs->PopTarget(); + _fs->AddInstruction(op, _fs->PushTarget(), src); + } + bool NeedGet() + { + switch(_token) { + case _SC('='): case _SC('('): case TK_NEWSLOT: case TK_MODEQ: case TK_MULEQ: + case TK_DIVEQ: case TK_MINUSEQ: case TK_PLUSEQ: case TK_PLUSPLUS: case TK_MINUSMINUS: + return false; + } + return (!_es.donot_get || ( _es.donot_get && (_token == _SC('.') || _token == _SC('[')))); + } + void FunctionCallArgs() + { + SQInteger nargs = 1;//this + while(_token != _SC(')')) { + Expression(); + MoveIfCurrentTargetIsLocal(); + nargs++; + if(_token == _SC(',')){ + Lex(); + if(_token == ')') Error(_SC("expression expected, found ')'")); + } + } + Lex(); + for(SQInteger i = 0; i < (nargs - 1); i++) _fs->PopTarget(); + SQInteger stackbase = _fs->PopTarget(); + SQInteger closure = _fs->PopTarget(); + _fs->AddInstruction(_OP_CALL, _fs->PushTarget(), closure, stackbase, nargs); + } + void ParseTableOrClass(SQInteger separator,SQInteger terminator) + { + SQInteger tpos = _fs->GetCurrentPos(),nkeys = 0; + while(_token != terminator) { + bool hasattrs = false; + bool isstatic = false; + //check if is an attribute + if(separator == ';') { + if(_token == TK_ATTR_OPEN) { + _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE); Lex(); + ParseTableOrClass(',',TK_ATTR_CLOSE); + hasattrs = true; + } + if(_token == TK_STATIC) { + isstatic = true; + Lex(); + } + } + switch(_token) { + case TK_FUNCTION: + case TK_CONSTRUCTOR:{ + SQInteger tk = _token; + Lex(); + SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor")); + Expect(_SC('(')); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); + CreateFunction(id); + _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0); + } + break; + case _SC('['): + Lex(); CommaExpr(); Expect(_SC(']')); + Expect(_SC('=')); Expression(); + break; + case TK_STRING_LITERAL: //JSON + if(separator == ',') { //only works for tables + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_STRING_LITERAL))); + Expect(_SC(':')); Expression(); + break; + } + default : + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER))); + Expect(_SC('=')); Expression(); + } + if(_token == separator) Lex();//optional comma/semicolon + nkeys++; + SQInteger val = _fs->PopTarget(); + SQInteger key = _fs->PopTarget(); + SQInteger attrs = hasattrs ? _fs->PopTarget():-1; + assert((hasattrs && (attrs == key-1)) || !hasattrs); + unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0); + SQInteger table = _fs->TopTarget(); //<AddInstruction(_OP_NEWSLOT, 0xFF, table, key, val); + } + else { + _fs->AddInstruction(_OP_NEWSLOTA, flags, table, key, val); //this for classes only as it invokes _newmember + } + } + if(separator == _SC(',')) //hack recognizes a table from the separator + _fs->SetIntructionParam(tpos, 1, nkeys); + Lex(); + } + void LocalDeclStatement() + { + SQObject varname; + Lex(); + if( _token == TK_FUNCTION) { + Lex(); + varname = Expect(TK_IDENTIFIER); + Expect(_SC('(')); + CreateFunction(varname,false); + _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0); + _fs->PopTarget(); + _fs->PushLocalVariable(varname); + return; + } + + do { + varname = Expect(TK_IDENTIFIER); + if(_token == _SC('=')) { + Lex(); Expression(); + SQInteger src = _fs->PopTarget(); + SQInteger dest = _fs->PushTarget(); + if(dest != src) _fs->AddInstruction(_OP_MOVE, dest, src); + } + else{ + _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1); + } + _fs->PopTarget(); + _fs->PushLocalVariable(varname); + if(_token == _SC(',')) Lex(); else break; + } while(1); + } + void IfStatement() + { + SQInteger jmppos; + bool haselse = false; + Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); + _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); + SQInteger jnepos = _fs->GetCurrentPos(); + BEGIN_SCOPE(); + + Statement(); + // + if(_token != _SC('}') && _token != TK_ELSE) OptionalSemicolon(); + + END_SCOPE(); + SQInteger endifblock = _fs->GetCurrentPos(); + if(_token == TK_ELSE){ + haselse = true; + BEGIN_SCOPE(); + _fs->AddInstruction(_OP_JMP); + jmppos = _fs->GetCurrentPos(); + Lex(); + Statement(); OptionalSemicolon(); + END_SCOPE(); + _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos); + } + _fs->SetIntructionParam(jnepos, 1, endifblock - jnepos + (haselse?1:0)); + } + void WhileStatement() + { + SQInteger jzpos, jmppos; + jmppos = _fs->GetCurrentPos(); + Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); + + BEGIN_BREAKBLE_BLOCK(); + _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); + jzpos = _fs->GetCurrentPos(); + BEGIN_SCOPE(); + + Statement(); + + END_SCOPE(); + _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1); + _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos); + + END_BREAKBLE_BLOCK(jmppos); + } + void DoWhileStatement() + { + Lex(); + SQInteger jmptrg = _fs->GetCurrentPos(); + BEGIN_BREAKBLE_BLOCK() + BEGIN_SCOPE(); + Statement(); + END_SCOPE(); + Expect(TK_WHILE); + SQInteger continuetrg = _fs->GetCurrentPos(); + Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); + _fs->AddInstruction(_OP_JZ, _fs->PopTarget(), 1); + _fs->AddInstruction(_OP_JMP, 0, jmptrg - _fs->GetCurrentPos() - 1); + END_BREAKBLE_BLOCK(continuetrg); + } + void ForStatement() + { + Lex(); + BEGIN_SCOPE(); + Expect(_SC('(')); + if(_token == TK_LOCAL) LocalDeclStatement(); + else if(_token != _SC(';')){ + CommaExpr(); + _fs->PopTarget(); + } + Expect(_SC(';')); + _fs->SnoozeOpt(); + SQInteger jmppos = _fs->GetCurrentPos(); + SQInteger jzpos = -1; + if(_token != _SC(';')) { CommaExpr(); _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); jzpos = _fs->GetCurrentPos(); } + Expect(_SC(';')); + _fs->SnoozeOpt(); + SQInteger expstart = _fs->GetCurrentPos() + 1; + if(_token != _SC(')')) { + CommaExpr(); + _fs->PopTarget(); + } + Expect(_SC(')')); + _fs->SnoozeOpt(); + SQInteger expend = _fs->GetCurrentPos(); + SQInteger expsize = (expend - expstart) + 1; + SQInstructionVec exp; + if(expsize > 0) { + for(SQInteger i = 0; i < expsize; i++) + exp.push_back(_fs->GetInstruction(expstart + i)); + _fs->PopInstructions(expsize); + } + BEGIN_BREAKBLE_BLOCK() + Statement(); + SQInteger continuetrg = _fs->GetCurrentPos(); + if(expsize > 0) { + for(SQInteger i = 0; i < expsize; i++) + _fs->AddInstruction(exp[i]); + } + _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1, 0); + if(jzpos> 0) _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos); + END_SCOPE(); + + END_BREAKBLE_BLOCK(continuetrg); + } + void ForEachStatement() + { + SQObject idxname, valname; + Lex(); Expect(_SC('(')); valname = Expect(TK_IDENTIFIER); + if(_token == _SC(',')) { + idxname = valname; + Lex(); valname = Expect(TK_IDENTIFIER); + } + else{ + idxname = _fs->CreateString(_SC("@INDEX@")); + } + Expect(TK_IN); + + //save the stack size + BEGIN_SCOPE(); + //put the table in the stack(evaluate the table expression) + Expression(); Expect(_SC(')')); + SQInteger container = _fs->TopTarget(); + //push the index local var + SQInteger indexpos = _fs->PushLocalVariable(idxname); + _fs->AddInstruction(_OP_LOADNULLS, indexpos,1); + //push the value local var + SQInteger valuepos = _fs->PushLocalVariable(valname); + _fs->AddInstruction(_OP_LOADNULLS, valuepos,1); + //push reference index + SQInteger itrpos = _fs->PushLocalVariable(_fs->CreateString(_SC("@ITERATOR@"))); //use invalid id to make it inaccessible + _fs->AddInstruction(_OP_LOADNULLS, itrpos,1); + SQInteger jmppos = _fs->GetCurrentPos(); + _fs->AddInstruction(_OP_FOREACH, container, 0, indexpos); + SQInteger foreachpos = _fs->GetCurrentPos(); + _fs->AddInstruction(_OP_POSTFOREACH, container, 0, indexpos); + //generate the statement code + BEGIN_BREAKBLE_BLOCK() + Statement(); + _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1); + _fs->SetIntructionParam(foreachpos, 1, _fs->GetCurrentPos() - foreachpos); + _fs->SetIntructionParam(foreachpos + 1, 1, _fs->GetCurrentPos() - foreachpos); + END_BREAKBLE_BLOCK(foreachpos - 1); + //restore the local variable stack(remove index,val and ref idx) + END_SCOPE(); + } + void SwitchStatement() + { + Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); + Expect(_SC('{')); + SQInteger expr = _fs->TopTarget(); + bool bfirst = true; + SQInteger tonextcondjmp = -1; + SQInteger skipcondjmp = -1; + SQInteger __nbreaks__ = _fs->_unresolvedbreaks.size(); + _fs->_breaktargets.push_back(0); + while(_token == TK_CASE) { + if(!bfirst) { + _fs->AddInstruction(_OP_JMP, 0, 0); + skipcondjmp = _fs->GetCurrentPos(); + _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp); + } + //condition + Lex(); Expression(); Expect(_SC(':')); + SQInteger trg = _fs->PopTarget(); + _fs->AddInstruction(_OP_EQ, trg, trg, expr); + _fs->AddInstruction(_OP_JZ, trg, 0); + //end condition + if(skipcondjmp != -1) { + _fs->SetIntructionParam(skipcondjmp, 1, (_fs->GetCurrentPos() - skipcondjmp)); + } + tonextcondjmp = _fs->GetCurrentPos(); + BEGIN_SCOPE(); + Statements(); + END_SCOPE(); + bfirst = false; + } + if(tonextcondjmp != -1) + _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp); + if(_token == TK_DEFAULT) { + Lex(); Expect(_SC(':')); + BEGIN_SCOPE(); + Statements(); + END_SCOPE(); + } + Expect(_SC('}')); + _fs->PopTarget(); + __nbreaks__ = _fs->_unresolvedbreaks.size() - __nbreaks__; + if(__nbreaks__ > 0)ResolveBreaks(_fs, __nbreaks__); + _fs->_breaktargets.pop_back(); + } + void FunctionStatement() + { + SQObject id; + Lex(); id = Expect(TK_IDENTIFIER); + _fs->PushTarget(0); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); + if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET); + + while(_token == TK_DOUBLE_COLON) { + Lex(); + id = Expect(TK_IDENTIFIER); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); + if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET); + } + Expect(_SC('(')); + CreateFunction(id); + _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0); + EmitDerefOp(_OP_NEWSLOT); + _fs->PopTarget(); + } + void ClassStatement() + { + SQExpState es; + Lex(); + es = _es; + _es.donot_get = true; + PrefixedExpr(); + if(_es.etype == EXPR) { + Error(_SC("invalid class name")); + } + else if(_es.etype == OBJECT || _es.etype == BASE) { + ClassExp(); + EmitDerefOp(_OP_NEWSLOT); + _fs->PopTarget(); + } + else { + Error(_SC("cannot create a class in a local with the syntax(class )")); + } + _es = es; + } + SQObject ExpectScalar() + { + SQObject val; + val._type = OT_NULL; val._unVal.nInteger = 0; //shut up GCC 4.x + switch(_token) { + case TK_INTEGER: + val._type = OT_INTEGER; + val._unVal.nInteger = _lex._nvalue; + break; + case TK_FLOAT: + val._type = OT_FLOAT; + val._unVal.fFloat = _lex._fvalue; + break; + case TK_STRING_LITERAL: + val = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1); + break; + case '-': + Lex(); + switch(_token) + { + case TK_INTEGER: + val._type = OT_INTEGER; + val._unVal.nInteger = -_lex._nvalue; + break; + case TK_FLOAT: + val._type = OT_FLOAT; + val._unVal.fFloat = -_lex._fvalue; + break; + default: + Error(_SC("scalar expected : integer,float")); + } + break; + default: + Error(_SC("scalar expected : integer,float or string")); + } + Lex(); + return val; + } + void EnumStatement() + { + Lex(); + SQObject id = Expect(TK_IDENTIFIER); + Expect(_SC('{')); + + SQObject table = _fs->CreateTable(); + SQInteger nval = 0; + while(_token != _SC('}')) { + SQObject key = Expect(TK_IDENTIFIER); + SQObject val; + if(_token == _SC('=')) { + Lex(); + val = ExpectScalar(); + } + else { + val._type = OT_INTEGER; + val._unVal.nInteger = nval++; + } + _table(table)->NewSlot(SQObjectPtr(key),SQObjectPtr(val)); + if(_token == ',') Lex(); + } + SQTable *enums = _table(_ss(_vm)->_consts); + SQObjectPtr strongid = id; + enums->NewSlot(SQObjectPtr(strongid),SQObjectPtr(table)); + strongid.Null(); + Lex(); + } + void TryCatchStatement() + { + SQObject exid; + Lex(); + _fs->AddInstruction(_OP_PUSHTRAP,0,0); + _fs->_traps++; + if(_fs->_breaktargets.size()) _fs->_breaktargets.top()++; + if(_fs->_continuetargets.size()) _fs->_continuetargets.top()++; + SQInteger trappos = _fs->GetCurrentPos(); + { + BEGIN_SCOPE(); + Statement(); + END_SCOPE(); + } + _fs->_traps--; + _fs->AddInstruction(_OP_POPTRAP, 1, 0); + if(_fs->_breaktargets.size()) _fs->_breaktargets.top()--; + if(_fs->_continuetargets.size()) _fs->_continuetargets.top()--; + _fs->AddInstruction(_OP_JMP, 0, 0); + SQInteger jmppos = _fs->GetCurrentPos(); + _fs->SetIntructionParam(trappos, 1, (_fs->GetCurrentPos() - trappos)); + Expect(TK_CATCH); Expect(_SC('(')); exid = Expect(TK_IDENTIFIER); Expect(_SC(')')); + { + BEGIN_SCOPE(); + SQInteger ex_target = _fs->PushLocalVariable(exid); + _fs->SetIntructionParam(trappos, 0, ex_target); + Statement(); + _fs->SetIntructionParams(jmppos, 0, (_fs->GetCurrentPos() - jmppos), 0); + END_SCOPE(); + } + } + void FunctionExp(SQInteger ftype,bool lambda = false) + { + Lex(); Expect(_SC('(')); + SQObjectPtr dummy; + CreateFunction(dummy,lambda); + _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, ftype == TK_FUNCTION?0:1); + } + void ClassExp() + { + SQInteger base = -1; + SQInteger attrs = -1; + if(_token == TK_EXTENDS) { + Lex(); Expression(); + base = _fs->TopTarget(); + } + if(_token == TK_ATTR_OPEN) { + Lex(); + _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE); + ParseTableOrClass(_SC(','),TK_ATTR_CLOSE); + attrs = _fs->TopTarget(); + } + Expect(_SC('{')); + if(attrs != -1) _fs->PopTarget(); + if(base != -1) _fs->PopTarget(); + _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(), base, attrs,NOT_CLASS); + ParseTableOrClass(_SC(';'),_SC('}')); + } + void DeleteExpr() + { + SQExpState es; + Lex(); + es = _es; + _es.donot_get = true; + PrefixedExpr(); + if(_es.etype==EXPR) Error(_SC("can't delete an expression")); + if(_es.etype==OBJECT || _es.etype==BASE) { + Emit2ArgsOP(_OP_DELETE); + } + else { + Error(_SC("cannot delete an (outer) local")); + } + _es = es; + } + void PrefixIncDec(SQInteger token) + { + SQExpState es; + SQInteger diff = (token==TK_MINUSMINUS) ? -1 : 1; + Lex(); + es = _es; + _es.donot_get = true; + PrefixedExpr(); + if(_es.etype==EXPR) { + Error(_SC("can't '++' or '--' an expression")); + } + else if(_es.etype==OBJECT || _es.etype==BASE) { + Emit2ArgsOP(_OP_INC, diff); + } + else if(_es.etype==LOCAL) { + SQInteger src = _fs->TopTarget(); + _fs->AddInstruction(_OP_INCL, src, src, 0, diff); + + } + else if(_es.etype==OUTER) { + SQInteger tmp = _fs->PushTarget(); + _fs->AddInstruction(_OP_GETOUTER, tmp, _es.epos); + _fs->AddInstruction(_OP_INCL, tmp, tmp, 0, diff); + _fs->AddInstruction(_OP_SETOUTER, tmp, _es.epos, tmp); + } + _es = es; + } + void CreateFunction(SQObject &name,bool lambda = false) + { + SQFuncState *funcstate = _fs->PushChildState(_ss(_vm)); + funcstate->_name = name; + SQObject paramname; + funcstate->AddParameter(_fs->CreateString(_SC("this"))); + funcstate->_sourcename = _sourcename; + SQInteger defparams = 0; + while(_token!=_SC(')')) { + if(_token == TK_VARPARAMS) { + if(defparams > 0) Error(_SC("function with default parameters cannot have variable number of parameters")); + funcstate->AddParameter(_fs->CreateString(_SC("vargv"))); + funcstate->_varparams = true; + Lex(); + if(_token != _SC(')')) Error(_SC("expected ')'")); + break; + } + else { + paramname = Expect(TK_IDENTIFIER); + funcstate->AddParameter(paramname); + if(_token == _SC('=')) { + Lex(); + Expression(); + funcstate->AddDefaultParam(_fs->TopTarget()); + defparams++; + } + else { + if(defparams > 0) Error(_SC("expected '='")); + } + if(_token == _SC(',')) Lex(); + else if(_token != _SC(')')) Error(_SC("expected ')' or ','")); + } + } + Expect(_SC(')')); + for(SQInteger n = 0; n < defparams; n++) { + _fs->PopTarget(); + } + + SQFuncState *currchunk = _fs; + _fs = funcstate; + if(lambda) { + Expression(); + _fs->AddInstruction(_OP_RETURN, 1, _fs->PopTarget());} + else { + Statement(false); + } + funcstate->AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true); + funcstate->AddInstruction(_OP_RETURN, -1); + funcstate->SetStackSize(0); + + SQFunctionProto *func = funcstate->BuildProto(); +#ifdef _DEBUG_DUMP + funcstate->Dump(func); +#endif + _fs = currchunk; + _fs->_functions.push_back(func); + _fs->PopChildState(); + } + void ResolveBreaks(SQFuncState *funcstate, SQInteger ntoresolve) + { + while(ntoresolve > 0) { + SQInteger pos = funcstate->_unresolvedbreaks.back(); + funcstate->_unresolvedbreaks.pop_back(); + //set the jmp instruction + funcstate->SetIntructionParams(pos, 0, funcstate->GetCurrentPos() - pos, 0); + ntoresolve--; + } + } + void ResolveContinues(SQFuncState *funcstate, SQInteger ntoresolve, SQInteger targetpos) + { + while(ntoresolve > 0) { + SQInteger pos = funcstate->_unresolvedcontinues.back(); + funcstate->_unresolvedcontinues.pop_back(); + //set the jmp instruction + funcstate->SetIntructionParams(pos, 0, targetpos - pos, 0); + ntoresolve--; + } + } +private: + SQInteger _token; + SQFuncState *_fs; + SQObjectPtr _sourcename; + SQLexer _lex; + bool _lineinfo; + bool _raiseerror; + SQInteger _debugline; + SQInteger _debugop; + SQExpState _es; + SQScope _scope; + SQChar *compilererror; + jmp_buf _errorjmp; + SQVM *_vm; +}; + +bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo) +{ + SQCompiler p(vm, rg, up, sourcename, raiseerror, lineinfo); + return p.Compile(out); +} + +#endif diff --git a/squirrel_3_0_1_stable/squirrel/sqcompiler.h b/squirrel_3_0_1_stable/squirrel/sqcompiler.h index fcfd46a99..de5983b46 100644 --- a/squirrel_3_0_1_stable/squirrel/sqcompiler.h +++ b/squirrel_3_0_1_stable/squirrel/sqcompiler.h @@ -1,77 +1,77 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQCOMPILER_H_ -#define _SQCOMPILER_H_ - -struct SQVM; - -#define TK_IDENTIFIER 258 -#define TK_STRING_LITERAL 259 -#define TK_INTEGER 260 -#define TK_FLOAT 261 -#define TK_BASE 262 -#define TK_DELETE 263 -#define TK_EQ 264 -#define TK_NE 265 -#define TK_LE 266 -#define TK_GE 267 -#define TK_SWITCH 268 -#define TK_ARROW 269 -#define TK_AND 270 -#define TK_OR 271 -#define TK_IF 272 -#define TK_ELSE 273 -#define TK_WHILE 274 -#define TK_BREAK 275 -#define TK_FOR 276 -#define TK_DO 277 -#define TK_NULL 278 -#define TK_FOREACH 279 -#define TK_IN 280 -#define TK_NEWSLOT 281 -#define TK_MODULO 282 -#define TK_LOCAL 283 -#define TK_CLONE 284 -#define TK_FUNCTION 285 -#define TK_RETURN 286 -#define TK_TYPEOF 287 -#define TK_UMINUS 288 -#define TK_PLUSEQ 289 -#define TK_MINUSEQ 290 -#define TK_CONTINUE 291 -#define TK_YIELD 292 -#define TK_TRY 293 -#define TK_CATCH 294 -#define TK_THROW 295 -#define TK_SHIFTL 296 -#define TK_SHIFTR 297 -#define TK_RESUME 298 -#define TK_DOUBLE_COLON 299 -#define TK_CASE 300 -#define TK_DEFAULT 301 -#define TK_THIS 302 -#define TK_PLUSPLUS 303 -#define TK_MINUSMINUS 304 -#define TK_3WAYSCMP 305 -#define TK_USHIFTR 306 -#define TK_CLASS 307 -#define TK_EXTENDS 308 -#define TK_CONSTRUCTOR 310 -#define TK_INSTANCEOF 311 -#define TK_VARPARAMS 312 -//#define TK_VARGC 313 -//#define TK_VARGV 314 -#define TK_TRUE 315 -#define TK_FALSE 316 -#define TK_MULEQ 317 -#define TK_DIVEQ 318 -#define TK_MODEQ 319 -#define TK_ATTR_OPEN 320 -#define TK_ATTR_CLOSE 321 -#define TK_STATIC 322 -#define TK_ENUM 323 -#define TK_CONST 324 - - -typedef void(*CompilerErrorFunc)(void *ud, const SQChar *s); -bool Compile(SQVM *vm, SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo); -#endif //_SQCOMPILER_H_ +/* see copyright notice in squirrel.h */ +#ifndef _SQCOMPILER_H_ +#define _SQCOMPILER_H_ + +struct SQVM; + +#define TK_IDENTIFIER 258 +#define TK_STRING_LITERAL 259 +#define TK_INTEGER 260 +#define TK_FLOAT 261 +#define TK_BASE 262 +#define TK_DELETE 263 +#define TK_EQ 264 +#define TK_NE 265 +#define TK_LE 266 +#define TK_GE 267 +#define TK_SWITCH 268 +#define TK_ARROW 269 +#define TK_AND 270 +#define TK_OR 271 +#define TK_IF 272 +#define TK_ELSE 273 +#define TK_WHILE 274 +#define TK_BREAK 275 +#define TK_FOR 276 +#define TK_DO 277 +#define TK_NULL 278 +#define TK_FOREACH 279 +#define TK_IN 280 +#define TK_NEWSLOT 281 +#define TK_MODULO 282 +#define TK_LOCAL 283 +#define TK_CLONE 284 +#define TK_FUNCTION 285 +#define TK_RETURN 286 +#define TK_TYPEOF 287 +#define TK_UMINUS 288 +#define TK_PLUSEQ 289 +#define TK_MINUSEQ 290 +#define TK_CONTINUE 291 +#define TK_YIELD 292 +#define TK_TRY 293 +#define TK_CATCH 294 +#define TK_THROW 295 +#define TK_SHIFTL 296 +#define TK_SHIFTR 297 +#define TK_RESUME 298 +#define TK_DOUBLE_COLON 299 +#define TK_CASE 300 +#define TK_DEFAULT 301 +#define TK_THIS 302 +#define TK_PLUSPLUS 303 +#define TK_MINUSMINUS 304 +#define TK_3WAYSCMP 305 +#define TK_USHIFTR 306 +#define TK_CLASS 307 +#define TK_EXTENDS 308 +#define TK_CONSTRUCTOR 310 +#define TK_INSTANCEOF 311 +#define TK_VARPARAMS 312 +//#define TK_VARGC 313 +//#define TK_VARGV 314 +#define TK_TRUE 315 +#define TK_FALSE 316 +#define TK_MULEQ 317 +#define TK_DIVEQ 318 +#define TK_MODEQ 319 +#define TK_ATTR_OPEN 320 +#define TK_ATTR_CLOSE 321 +#define TK_STATIC 322 +#define TK_ENUM 323 +#define TK_CONST 324 + + +typedef void(*CompilerErrorFunc)(void *ud, const SQChar *s); +bool Compile(SQVM *vm, SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo); +#endif //_SQCOMPILER_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqdebug.cpp b/squirrel_3_0_1_stable/squirrel/sqdebug.cpp index 3cb7b71cd..01d0261d2 100644 --- a/squirrel_3_0_1_stable/squirrel/sqdebug.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqdebug.cpp @@ -1,116 +1,116 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#include -#include "sqvm.h" -#include "sqfuncproto.h" -#include "sqclosure.h" -#include "sqstring.h" - -SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger level,SQFunctionInfo *fi) -{ - SQInteger cssize = v->_callsstacksize; - if (cssize > level) { - SQVM::CallInfo &ci = v->_callsstack[cssize-level-1]; - if(sq_isclosure(ci._closure)) { - SQClosure *c = _closure(ci._closure); - SQFunctionProto *proto = c->_function; - fi->funcid = proto; - fi->name = type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown"); - fi->source = type(proto->_name) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown"); - return SQ_OK; - } - } - return sq_throwerror(v,_SC("the object is not a closure")); -} - -SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si) -{ - SQInteger cssize = v->_callsstacksize; - if (cssize > level) { - memset(si, 0, sizeof(SQStackInfos)); - SQVM::CallInfo &ci = v->_callsstack[cssize-level-1]; - switch (type(ci._closure)) { - case OT_CLOSURE:{ - SQFunctionProto *func = _closure(ci._closure)->_function; - if (type(func->_name) == OT_STRING) - si->funcname = _stringval(func->_name); - if (type(func->_sourcename) == OT_STRING) - si->source = _stringval(func->_sourcename); - si->line = func->GetLine(ci._ip); - } - break; - case OT_NATIVECLOSURE: - si->source = _SC("NATIVE"); - si->funcname = _SC("unknown"); - if(type(_nativeclosure(ci._closure)->_name) == OT_STRING) - si->funcname = _stringval(_nativeclosure(ci._closure)->_name); - si->line = -1; - break; - default: break; //shutup compiler - } - return SQ_OK; - } - return SQ_ERROR; -} - -void SQVM::Raise_Error(const SQChar *s, ...) -{ - va_list vl; - va_start(vl, s); - scvsprintf(_sp(rsl((SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2))), s, vl); - va_end(vl); - _lasterror = SQString::Create(_ss(this),_spval,-1); -} - -void SQVM::Raise_Error(const SQObjectPtr &desc) -{ - _lasterror = desc; -} - -SQString *SQVM::PrintObjVal(const SQObjectPtr &o) -{ - switch(type(o)) { - case OT_STRING: return _string(o); - case OT_INTEGER: - scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _PRINT_INT_FMT, _integer(o)); - return SQString::Create(_ss(this), _spval); - break; - case OT_FLOAT: - scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%.14g"), _float(o)); - return SQString::Create(_ss(this), _spval); - break; - default: - return SQString::Create(_ss(this), GetTypeName(o)); - } -} - -void SQVM::Raise_IdxError(const SQObjectPtr &o) -{ - SQObjectPtr oval = PrintObjVal(o); - Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval)); -} - -void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2) -{ - SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2); - Raise_Error(_SC("comparsion between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2)); -} - - -void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type) -{ - SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1); - SQInteger found = 0; - for(SQInteger i=0; i<16; i++) - { - SQInteger mask = 0x00000001 << i; - if(typemask & (mask)) { - if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes); - found ++; - StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes); - } - } - Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes)); -} +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include +#include "sqvm.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "sqstring.h" + +SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger level,SQFunctionInfo *fi) +{ + SQInteger cssize = v->_callsstacksize; + if (cssize > level) { + SQVM::CallInfo &ci = v->_callsstack[cssize-level-1]; + if(sq_isclosure(ci._closure)) { + SQClosure *c = _closure(ci._closure); + SQFunctionProto *proto = c->_function; + fi->funcid = proto; + fi->name = type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown"); + fi->source = type(proto->_name) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown"); + return SQ_OK; + } + } + return sq_throwerror(v,_SC("the object is not a closure")); +} + +SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si) +{ + SQInteger cssize = v->_callsstacksize; + if (cssize > level) { + memset(si, 0, sizeof(SQStackInfos)); + SQVM::CallInfo &ci = v->_callsstack[cssize-level-1]; + switch (type(ci._closure)) { + case OT_CLOSURE:{ + SQFunctionProto *func = _closure(ci._closure)->_function; + if (type(func->_name) == OT_STRING) + si->funcname = _stringval(func->_name); + if (type(func->_sourcename) == OT_STRING) + si->source = _stringval(func->_sourcename); + si->line = func->GetLine(ci._ip); + } + break; + case OT_NATIVECLOSURE: + si->source = _SC("NATIVE"); + si->funcname = _SC("unknown"); + if(type(_nativeclosure(ci._closure)->_name) == OT_STRING) + si->funcname = _stringval(_nativeclosure(ci._closure)->_name); + si->line = -1; + break; + default: break; //shutup compiler + } + return SQ_OK; + } + return SQ_ERROR; +} + +void SQVM::Raise_Error(const SQChar *s, ...) +{ + va_list vl; + va_start(vl, s); + scvsprintf(_sp(rsl((SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2))), s, vl); + va_end(vl); + _lasterror = SQString::Create(_ss(this),_spval,-1); +} + +void SQVM::Raise_Error(const SQObjectPtr &desc) +{ + _lasterror = desc; +} + +SQString *SQVM::PrintObjVal(const SQObjectPtr &o) +{ + switch(type(o)) { + case OT_STRING: return _string(o); + case OT_INTEGER: + scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _PRINT_INT_FMT, _integer(o)); + return SQString::Create(_ss(this), _spval); + break; + case OT_FLOAT: + scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%.14g"), _float(o)); + return SQString::Create(_ss(this), _spval); + break; + default: + return SQString::Create(_ss(this), GetTypeName(o)); + } +} + +void SQVM::Raise_IdxError(const SQObjectPtr &o) +{ + SQObjectPtr oval = PrintObjVal(o); + Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval)); +} + +void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2) +{ + SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2); + Raise_Error(_SC("comparsion between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2)); +} + + +void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type) +{ + SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1); + SQInteger found = 0; + for(SQInteger i=0; i<16; i++) + { + SQInteger mask = 0x00000001 << i; + if(typemask & (mask)) { + if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes); + found ++; + StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes); + } + } + Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes)); +} diff --git a/squirrel_3_0_1_stable/squirrel/sqfuncproto.h b/squirrel_3_0_1_stable/squirrel/sqfuncproto.h index cd48aa6df..e6e9529ec 100644 --- a/squirrel_3_0_1_stable/squirrel/sqfuncproto.h +++ b/squirrel_3_0_1_stable/squirrel/sqfuncproto.h @@ -1,154 +1,154 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQFUNCTION_H_ -#define _SQFUNCTION_H_ - -#include "sqopcodes.h" - -enum SQOuterType { - otLOCAL = 0, - otOUTER = 1 -}; - -struct SQOuterVar -{ - - SQOuterVar(){} - SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t) - { - _name = name; - _src=src; - _type=t; - } - SQOuterVar(const SQOuterVar &ov) - { - _type=ov._type; - _src=ov._src; - _name=ov._name; - } - SQOuterType _type; - SQObjectPtr _name; - SQObjectPtr _src; -}; - -struct SQLocalVarInfo -{ - SQLocalVarInfo():_start_op(0),_end_op(0),_pos(0){} - SQLocalVarInfo(const SQLocalVarInfo &lvi) - { - _name=lvi._name; - _start_op=lvi._start_op; - _end_op=lvi._end_op; - _pos=lvi._pos; - } - SQObjectPtr _name; - SQUnsignedInteger _start_op; - SQUnsignedInteger _end_op; - SQUnsignedInteger _pos; -}; - -struct SQLineInfo { SQInteger _line;SQInteger _op; }; - -typedef sqvector SQOuterVarVec; -typedef sqvector SQLocalVarInfoVec; -typedef sqvector SQLineInfoVec; - -#define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf,defparams) (sizeof(SQFunctionProto) \ - +((ni-1)*sizeof(SQInstruction))+(nl*sizeof(SQObjectPtr)) \ - +(nparams*sizeof(SQObjectPtr))+(nfuncs*sizeof(SQObjectPtr)) \ - +(nouters*sizeof(SQOuterVar))+(nlineinf*sizeof(SQLineInfo)) \ - +(localinf*sizeof(SQLocalVarInfo))+(defparams*sizeof(SQInteger))) - - -struct SQFunctionProto : public CHAINABLE_OBJ -{ -private: - SQFunctionProto(SQSharedState *ss); - ~SQFunctionProto(); - -public: - static SQFunctionProto *Create(SQSharedState *ss,SQInteger ninstructions, - SQInteger nliterals,SQInteger nparameters, - SQInteger nfunctions,SQInteger noutervalues, - SQInteger nlineinfos,SQInteger nlocalvarinfos,SQInteger ndefaultparams) - { - SQFunctionProto *f; - //I compact the whole class and members in a single memory allocation - f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams)); - new (f) SQFunctionProto(ss); - f->_ninstructions = ninstructions; - f->_literals = (SQObjectPtr*)&f->_instructions[ninstructions]; - f->_nliterals = nliterals; - f->_parameters = (SQObjectPtr*)&f->_literals[nliterals]; - f->_nparameters = nparameters; - f->_functions = (SQObjectPtr*)&f->_parameters[nparameters]; - f->_nfunctions = nfunctions; - f->_outervalues = (SQOuterVar*)&f->_functions[nfunctions]; - f->_noutervalues = noutervalues; - f->_lineinfos = (SQLineInfo *)&f->_outervalues[noutervalues]; - f->_nlineinfos = nlineinfos; - f->_localvarinfos = (SQLocalVarInfo *)&f->_lineinfos[nlineinfos]; - f->_nlocalvarinfos = nlocalvarinfos; - f->_defaultparams = (SQInteger *)&f->_localvarinfos[nlocalvarinfos]; - f->_ndefaultparams = ndefaultparams; - - _CONSTRUCT_VECTOR(SQObjectPtr,f->_nliterals,f->_literals); - _CONSTRUCT_VECTOR(SQObjectPtr,f->_nparameters,f->_parameters); - _CONSTRUCT_VECTOR(SQObjectPtr,f->_nfunctions,f->_functions); - _CONSTRUCT_VECTOR(SQOuterVar,f->_noutervalues,f->_outervalues); - //_CONSTRUCT_VECTOR(SQLineInfo,f->_nlineinfos,f->_lineinfos); //not required are 2 integers - _CONSTRUCT_VECTOR(SQLocalVarInfo,f->_nlocalvarinfos,f->_localvarinfos); - return f; - } - void Release(){ - _DESTRUCT_VECTOR(SQObjectPtr,_nliterals,_literals); - _DESTRUCT_VECTOR(SQObjectPtr,_nparameters,_parameters); - _DESTRUCT_VECTOR(SQObjectPtr,_nfunctions,_functions); - _DESTRUCT_VECTOR(SQOuterVar,_noutervalues,_outervalues); - //_DESTRUCT_VECTOR(SQLineInfo,_nlineinfos,_lineinfos); //not required are 2 integers - _DESTRUCT_VECTOR(SQLocalVarInfo,_nlocalvarinfos,_localvarinfos); - SQInteger size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos,_ndefaultparams); - this->~SQFunctionProto(); - sq_vm_free(this,size); - } - - const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop); - SQInteger GetLine(SQInstruction *curr); - bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write); - static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret); -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **chain); - void Finalize(){ _NULL_SQOBJECT_VECTOR(_literals,_nliterals); } - SQObjectType GetType() {return OT_FUNCPROTO;} -#endif - SQObjectPtr _sourcename; - SQObjectPtr _name; - SQInteger _stacksize; - bool _bgenerator; - SQInteger _varparams; - - SQInteger _nlocalvarinfos; - SQLocalVarInfo *_localvarinfos; - - SQInteger _nlineinfos; - SQLineInfo *_lineinfos; - - SQInteger _nliterals; - SQObjectPtr *_literals; - - SQInteger _nparameters; - SQObjectPtr *_parameters; - - SQInteger _nfunctions; - SQObjectPtr *_functions; - - SQInteger _noutervalues; - SQOuterVar *_outervalues; - - SQInteger _ndefaultparams; - SQInteger *_defaultparams; - - SQInteger _ninstructions; - SQInstruction _instructions[1]; -}; - -#endif //_SQFUNCTION_H_ +/* see copyright notice in squirrel.h */ +#ifndef _SQFUNCTION_H_ +#define _SQFUNCTION_H_ + +#include "sqopcodes.h" + +enum SQOuterType { + otLOCAL = 0, + otOUTER = 1 +}; + +struct SQOuterVar +{ + + SQOuterVar(){} + SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t) + { + _name = name; + _src=src; + _type=t; + } + SQOuterVar(const SQOuterVar &ov) + { + _type=ov._type; + _src=ov._src; + _name=ov._name; + } + SQOuterType _type; + SQObjectPtr _name; + SQObjectPtr _src; +}; + +struct SQLocalVarInfo +{ + SQLocalVarInfo():_start_op(0),_end_op(0),_pos(0){} + SQLocalVarInfo(const SQLocalVarInfo &lvi) + { + _name=lvi._name; + _start_op=lvi._start_op; + _end_op=lvi._end_op; + _pos=lvi._pos; + } + SQObjectPtr _name; + SQUnsignedInteger _start_op; + SQUnsignedInteger _end_op; + SQUnsignedInteger _pos; +}; + +struct SQLineInfo { SQInteger _line;SQInteger _op; }; + +typedef sqvector SQOuterVarVec; +typedef sqvector SQLocalVarInfoVec; +typedef sqvector SQLineInfoVec; + +#define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf,defparams) (sizeof(SQFunctionProto) \ + +((ni-1)*sizeof(SQInstruction))+(nl*sizeof(SQObjectPtr)) \ + +(nparams*sizeof(SQObjectPtr))+(nfuncs*sizeof(SQObjectPtr)) \ + +(nouters*sizeof(SQOuterVar))+(nlineinf*sizeof(SQLineInfo)) \ + +(localinf*sizeof(SQLocalVarInfo))+(defparams*sizeof(SQInteger))) + + +struct SQFunctionProto : public CHAINABLE_OBJ +{ +private: + SQFunctionProto(SQSharedState *ss); + ~SQFunctionProto(); + +public: + static SQFunctionProto *Create(SQSharedState *ss,SQInteger ninstructions, + SQInteger nliterals,SQInteger nparameters, + SQInteger nfunctions,SQInteger noutervalues, + SQInteger nlineinfos,SQInteger nlocalvarinfos,SQInteger ndefaultparams) + { + SQFunctionProto *f; + //I compact the whole class and members in a single memory allocation + f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams)); + new (f) SQFunctionProto(ss); + f->_ninstructions = ninstructions; + f->_literals = (SQObjectPtr*)&f->_instructions[ninstructions]; + f->_nliterals = nliterals; + f->_parameters = (SQObjectPtr*)&f->_literals[nliterals]; + f->_nparameters = nparameters; + f->_functions = (SQObjectPtr*)&f->_parameters[nparameters]; + f->_nfunctions = nfunctions; + f->_outervalues = (SQOuterVar*)&f->_functions[nfunctions]; + f->_noutervalues = noutervalues; + f->_lineinfos = (SQLineInfo *)&f->_outervalues[noutervalues]; + f->_nlineinfos = nlineinfos; + f->_localvarinfos = (SQLocalVarInfo *)&f->_lineinfos[nlineinfos]; + f->_nlocalvarinfos = nlocalvarinfos; + f->_defaultparams = (SQInteger *)&f->_localvarinfos[nlocalvarinfos]; + f->_ndefaultparams = ndefaultparams; + + _CONSTRUCT_VECTOR(SQObjectPtr,f->_nliterals,f->_literals); + _CONSTRUCT_VECTOR(SQObjectPtr,f->_nparameters,f->_parameters); + _CONSTRUCT_VECTOR(SQObjectPtr,f->_nfunctions,f->_functions); + _CONSTRUCT_VECTOR(SQOuterVar,f->_noutervalues,f->_outervalues); + //_CONSTRUCT_VECTOR(SQLineInfo,f->_nlineinfos,f->_lineinfos); //not required are 2 integers + _CONSTRUCT_VECTOR(SQLocalVarInfo,f->_nlocalvarinfos,f->_localvarinfos); + return f; + } + void Release(){ + _DESTRUCT_VECTOR(SQObjectPtr,_nliterals,_literals); + _DESTRUCT_VECTOR(SQObjectPtr,_nparameters,_parameters); + _DESTRUCT_VECTOR(SQObjectPtr,_nfunctions,_functions); + _DESTRUCT_VECTOR(SQOuterVar,_noutervalues,_outervalues); + //_DESTRUCT_VECTOR(SQLineInfo,_nlineinfos,_lineinfos); //not required are 2 integers + _DESTRUCT_VECTOR(SQLocalVarInfo,_nlocalvarinfos,_localvarinfos); + SQInteger size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos,_ndefaultparams); + this->~SQFunctionProto(); + sq_vm_free(this,size); + } + + const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop); + SQInteger GetLine(SQInstruction *curr); + bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write); + static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize(){ _NULL_SQOBJECT_VECTOR(_literals,_nliterals); } + SQObjectType GetType() {return OT_FUNCPROTO;} +#endif + SQObjectPtr _sourcename; + SQObjectPtr _name; + SQInteger _stacksize; + bool _bgenerator; + SQInteger _varparams; + + SQInteger _nlocalvarinfos; + SQLocalVarInfo *_localvarinfos; + + SQInteger _nlineinfos; + SQLineInfo *_lineinfos; + + SQInteger _nliterals; + SQObjectPtr *_literals; + + SQInteger _nparameters; + SQObjectPtr *_parameters; + + SQInteger _nfunctions; + SQObjectPtr *_functions; + + SQInteger _noutervalues; + SQOuterVar *_outervalues; + + SQInteger _ndefaultparams; + SQInteger *_defaultparams; + + SQInteger _ninstructions; + SQInstruction _instructions[1]; +}; + +#endif //_SQFUNCTION_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqfuncstate.cpp b/squirrel_3_0_1_stable/squirrel/sqfuncstate.cpp index 9e236c7e7..81ec7e31c 100644 --- a/squirrel_3_0_1_stable/squirrel/sqfuncstate.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqfuncstate.cpp @@ -1,652 +1,652 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#ifndef NO_COMPILER -#include "sqcompiler.h" -#include "sqstring.h" -#include "sqfuncproto.h" -#include "sqtable.h" -#include "sqopcodes.h" -#include "sqfuncstate.h" - -#ifdef _DEBUG_DUMP -SQInstructionDesc g_InstrDesc[]={ - {_SC("_OP_LINE")}, - {_SC("_OP_LOAD")}, - {_SC("_OP_LOADINT")}, - {_SC("_OP_LOADFLOAT")}, - {_SC("_OP_DLOAD")}, - {_SC("_OP_TAILCALL")}, - {_SC("_OP_CALL")}, - {_SC("_OP_PREPCALL")}, - {_SC("_OP_PREPCALLK")}, - {_SC("_OP_GETK")}, - {_SC("_OP_MOVE")}, - {_SC("_OP_NEWSLOT")}, - {_SC("_OP_DELETE")}, - {_SC("_OP_SET")}, - {_SC("_OP_GET")}, - {_SC("_OP_EQ")}, - {_SC("_OP_NE")}, - {_SC("_OP_ADD")}, - {_SC("_OP_SUB")}, - {_SC("_OP_MUL")}, - {_SC("_OP_DIV")}, - {_SC("_OP_MOD")}, - {_SC("_OP_BITW")}, - {_SC("_OP_RETURN")}, - {_SC("_OP_LOADNULLS")}, - {_SC("_OP_LOADROOT")}, - {_SC("_OP_LOADBOOL")}, - {_SC("_OP_DMOVE")}, - {_SC("_OP_JMP")}, - {_SC("_OP_JCMP")}, - {_SC("_OP_JZ")}, - {_SC("_OP_SETOUTER")}, - {_SC("_OP_GETOUTER")}, - {_SC("_OP_NEWOBJ")}, - {_SC("_OP_APPENDARRAY")}, - {_SC("_OP_COMPARITH")}, - {_SC("_OP_INC")}, - {_SC("_OP_INCL")}, - {_SC("_OP_PINC")}, - {_SC("_OP_PINCL")}, - {_SC("_OP_CMP")}, - {_SC("_OP_EXISTS")}, - {_SC("_OP_INSTANCEOF")}, - {_SC("_OP_AND")}, - {_SC("_OP_OR")}, - {_SC("_OP_NEG")}, - {_SC("_OP_NOT")}, - {_SC("_OP_BWNOT")}, - {_SC("_OP_CLOSURE")}, - {_SC("_OP_YIELD")}, - {_SC("_OP_RESUME")}, - {_SC("_OP_FOREACH")}, - {_SC("_OP_POSTFOREACH")}, - {_SC("_OP_CLONE")}, - {_SC("_OP_TYPEOF")}, - {_SC("_OP_PUSHTRAP")}, - {_SC("_OP_POPTRAP")}, - {_SC("_OP_THROW")}, - {_SC("_OP_NEWSLOTA")}, - {_SC("_OP_GETBASE")}, - {_SC("_OP_CLOSE")}, - {_SC("_OP_JCMP")} -}; -#endif -void DumpLiteral(SQObjectPtr &o) -{ - switch(type(o)){ - case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break; - case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break; - case OT_INTEGER: scprintf(_SC("{") _PRINT_INT_FMT _SC("}"),_integer(o));break; - case OT_BOOL: scprintf(_SC("%s"),_integer(o)?_SC("true"):_SC("false"));break; - default: scprintf(_SC("(%s %p)"),GetTypeName(o),(void*)_rawval(o));break; break; //shut up compiler - } -} - -SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed) -{ - _nliterals = 0; - _literals = SQTable::Create(ss,0); - _strings = SQTable::Create(ss,0); - _sharedstate = ss; - _lastline = 0; - _optimization = true; - _parent = parent; - _stacksize = 0; - _traps = 0; - _returnexp = 0; - _varparams = false; - _errfunc = efunc; - _errtarget = ed; - _bgenerator = false; - _outers = 0; - _ss = ss; - -} - -void SQFuncState::Error(const SQChar *err) -{ - _errfunc(_errtarget,err); -} - -#ifdef _DEBUG_DUMP -void SQFuncState::Dump(SQFunctionProto *func) -{ - SQUnsignedInteger n=0,i; - SQInteger si; - scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction)); - scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject)); - scprintf(_SC("--------------------------------------------------------------------\n")); - scprintf(_SC("*****FUNCTION [%s]\n"),type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown")); - scprintf(_SC("-----LITERALS\n")); - SQObjectPtr refidx,key,val; - SQInteger idx; - SQObjectPtrVec templiterals; - templiterals.resize(_nliterals); - while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) { - refidx=idx; - templiterals[_integer(val)]=key; - } - for(i=0;i>\n")); - n=0; - for(i=0;i<_parameters.size();i++){ - scprintf(_SC("[%d] "),n); - DumpLiteral(_parameters[i]); - scprintf(_SC("\n")); - n++; - } - scprintf(_SC("-----LOCALS\n")); - for(si=0;si_nlocalvarinfos;si++){ - SQLocalVarInfo lvi=func->_localvarinfos[si]; - scprintf(_SC("[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op); - n++; - } - scprintf(_SC("-----LINE INFO\n")); - for(i=0;i<_lineinfos.size();i++){ - SQLineInfo li=_lineinfos[i]; - scprintf(_SC("op [%d] line [%d] \n"),li._op,li._line); - n++; - } - scprintf(_SC("-----dump\n")); - n=0; - for(i=0;i<_instructions.size();i++){ - SQInstruction &inst=_instructions[i]; - if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){ - - SQInteger lidx = inst._arg1; - scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0); - if(lidx >= 0xFFFFFFFF) - scprintf(_SC("null")); - else { - SQInteger refidx; - SQObjectPtr val,key,refo; - while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { - refo = refidx; - } - DumpLiteral(key); - } - if(inst.op != _OP_DLOAD) { - scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3); - } - else { - scprintf(_SC(" %d "),inst._arg2); - lidx = inst._arg3; - if(lidx >= 0xFFFFFFFF) - scprintf(_SC("null")); - else { - SQInteger refidx; - SQObjectPtr val,key,refo; - while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { - refo = refidx; - } - DumpLiteral(key); - scprintf(_SC("\n")); - } - } - } - else if(inst.op==_OP_LOADFLOAT) { - scprintf(_SC("[%03d] %15s %d %f %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3); - } - /* else if(inst.op==_OP_ARITH){ - scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); - }*/ - else { - scprintf(_SC("[%03d] %15s %d %d %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); - } - n++; - } - scprintf(_SC("-----\n")); - scprintf(_SC("stack size[%d]\n"),func->_stacksize); - scprintf(_SC("--------------------------------------------------------------------\n\n")); -} -#endif - -SQInteger SQFuncState::GetNumericConstant(const SQInteger cons) -{ - return GetConstant(SQObjectPtr(cons)); -} - -SQInteger SQFuncState::GetNumericConstant(const SQFloat cons) -{ - return GetConstant(SQObjectPtr(cons)); -} - -SQInteger SQFuncState::GetConstant(const SQObject &cons) -{ - SQObjectPtr val; - if(!_table(_literals)->Get(cons,val)) - { - val = _nliterals; - _table(_literals)->NewSlot(cons,val); - _nliterals++; - if(_nliterals > MAX_LITERALS) { - val.Null(); - Error(_SC("internal compiler error: too many literals")); - } - } - return _integer(val); -} - -void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3) -{ - _instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0); - _instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1); - _instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&arg2); - _instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3); -} - -void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val) -{ - switch(arg){ - case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break; - case 1:case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);break; - case 2:_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&val);break; - case 3:_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&val);break; - }; -} - -SQInteger SQFuncState::AllocStackPos() -{ - SQInteger npos=_vlocals.size(); - _vlocals.push_back(SQLocalVarInfo()); - if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) { - if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals")); - _stacksize=_vlocals.size(); - } - return npos; -} - -SQInteger SQFuncState::PushTarget(SQInteger n) -{ - if(n!=-1){ - _targetstack.push_back(n); - return n; - } - n=AllocStackPos(); - _targetstack.push_back(n); - return n; -} - -SQInteger SQFuncState::GetUpTarget(SQInteger n){ - return _targetstack[((_targetstack.size()-1)-n)]; -} - -SQInteger SQFuncState::TopTarget(){ - return _targetstack.back(); -} -SQInteger SQFuncState::PopTarget() -{ - SQInteger npos=_targetstack.back(); - SQLocalVarInfo &t=_vlocals[_targetstack.back()]; - if(type(t._name)==OT_NULL){ - _vlocals.pop_back(); - } - _targetstack.pop_back(); - return npos; -} - -SQInteger SQFuncState::GetStackSize() -{ - return _vlocals.size(); -} - -SQInteger SQFuncState::CountOuters(SQInteger stacksize) -{ - SQInteger outers = 0; - SQInteger k = _vlocals.size() - 1; - while(k >= stacksize) { - SQLocalVarInfo &lvi = _vlocals[k]; - k--; - if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer - outers++; - } - } - return outers; -} - -void SQFuncState::SetStackSize(SQInteger n) -{ - SQInteger size=_vlocals.size(); - while(size>n){ - size--; - SQLocalVarInfo lvi = _vlocals.back(); - if(type(lvi._name)!=OT_NULL){ - if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer - _outers--; - } - lvi._end_op = GetCurrentPos(); - _localvarinfos.push_back(lvi); - } - _vlocals.pop_back(); - } -} - -bool SQFuncState::IsConstant(const SQObject &name,SQObject &e) -{ - SQObjectPtr val; - if(_table(_sharedstate->_consts)->Get(name,val)) { - e = val; - return true; - } - return false; -} - -bool SQFuncState::IsLocal(SQUnsignedInteger stkpos) -{ - if(stkpos>=_vlocals.size())return false; - else if(type(_vlocals[stkpos]._name)!=OT_NULL)return true; - return false; -} - -SQInteger SQFuncState::PushLocalVariable(const SQObject &name) -{ - SQInteger pos=_vlocals.size(); - SQLocalVarInfo lvi; - lvi._name=name; - lvi._start_op=GetCurrentPos()+1; - lvi._pos=_vlocals.size(); - _vlocals.push_back(lvi); - if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size(); - return pos; -} - - - -SQInteger SQFuncState::GetLocalVariable(const SQObject &name) -{ - SQInteger locals=_vlocals.size(); - while(locals>=1){ - SQLocalVarInfo &lvi = _vlocals[locals-1]; - if(type(lvi._name)==OT_STRING && _string(lvi._name)==_string(name)){ - return locals-1; - } - locals--; - } - return -1; -} - -void SQFuncState::MarkLocalAsOuter(SQInteger pos) -{ - SQLocalVarInfo &lvi = _vlocals[pos]; - lvi._end_op = UINT_MINUS_ONE; - _outers++; -} - -SQInteger SQFuncState::GetOuterVariable(const SQObject &name) -{ - SQInteger outers = _outervalues.size(); - for(SQInteger i = 0; iGetLocalVariable(name); - if(pos == -1) { - pos = _parent->GetOuterVariable(name); - if(pos != -1) { - _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otOUTER)); //local - return _outervalues.size() - 1; - } - } - else { - _parent->MarkLocalAsOuter(pos); - _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local - return _outervalues.size() - 1; - - - } - } - return -1; -} - -void SQFuncState::AddParameter(const SQObject &name) -{ - PushLocalVariable(name); - _parameters.push_back(name); -} - -void SQFuncState::AddLineInfos(SQInteger line,bool lineop,bool force) -{ - if(_lastline!=line || force){ - SQLineInfo li; - li._line=line;li._op=(GetCurrentPos()+1); - if(lineop)AddInstruction(_OP_LINE,0,line); - if(_lastline!=line) { - _lineinfos.push_back(li); - } - _lastline=line; - } -} - -void SQFuncState::DiscardTarget() -{ - SQInteger discardedtarget = PopTarget(); - SQInteger size = _instructions.size(); - if(size > 0 && _optimization){ - SQInstruction &pi = _instructions[size-1];//previous instruction - switch(pi.op) { - case _OP_SET:case _OP_NEWSLOT:case _OP_SETOUTER:case _OP_CALL: - if(pi._arg0 == discardedtarget) { - pi._arg0 = 0xFF; - } - } - } -} - -void SQFuncState::AddInstruction(SQInstruction &i) -{ - SQInteger size = _instructions.size(); - if(size > 0 && _optimization){ //simple optimizer - SQInstruction &pi = _instructions[size-1];//previous instruction - switch(i.op) { - case _OP_JZ: - if( pi.op == _OP_CMP && pi._arg1 < 0xFF) { - pi.op = _OP_JCMP; - pi._arg0 = (unsigned char)pi._arg1; - pi._arg1 = i._arg1; - return; - } - case _OP_SET: - case _OP_NEWSLOT: - if(i._arg0 == i._arg3) { - i._arg0 = 0xFF; - } - break; - case _OP_SETOUTER: - if(i._arg0 == i._arg2) { - i._arg0 = 0xFF; - } - break; - case _OP_RETURN: - if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) { - pi.op = _OP_TAILCALL; - } else if(pi.op == _OP_CLOSE){ - pi = i; - return; - } - break; - case _OP_GET: - if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!IsLocal(pi._arg0))){ - pi._arg1 = pi._arg1; - pi._arg2 = (unsigned char)i._arg1; - pi.op = _OP_GETK; - pi._arg0 = i._arg0; - - return; - } - break; - case _OP_PREPCALL: - if( pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){ - pi.op = _OP_PREPCALLK; - pi._arg0 = i._arg0; - pi._arg1 = pi._arg1; - pi._arg2 = i._arg2; - pi._arg3 = i._arg3; - return; - } - break; - case _OP_APPENDARRAY: { - SQInteger aat = -1; - switch(pi.op) { - case _OP_LOAD: aat = AAT_LITERAL; break; - case _OP_LOADINT: aat = AAT_INT; break; - case _OP_LOADBOOL: aat = AAT_BOOL; break; - case _OP_LOADFLOAT: aat = AAT_FLOAT; break; - default: break; - } - if(aat != -1 && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){ - pi.op = _OP_APPENDARRAY; - pi._arg0 = i._arg0; - pi._arg1 = pi._arg1; - pi._arg2 = (unsigned char)aat; - pi._arg3 = MAX_FUNC_STACKSIZE; - return; - } - } - break; - case _OP_MOVE: - switch(pi.op) { - case _OP_GET: case _OP_ADD: case _OP_SUB: case _OP_MUL: case _OP_DIV: case _OP_MOD: case _OP_BITW: - case _OP_LOADINT: case _OP_LOADFLOAT: case _OP_LOADBOOL: case _OP_LOAD: - - if(pi._arg0 == i._arg1) - { - pi._arg0 = i._arg0; - _optimization = false; - //_result_elimination = false; - return; - } - } - - if(pi.op == _OP_MOVE) - { - pi.op = _OP_DMOVE; - pi._arg2 = i._arg0; - pi._arg3 = (unsigned char)i._arg1; - return; - } - break; - case _OP_LOAD: - if(pi.op == _OP_LOAD && i._arg1 < 256) { - pi.op = _OP_DLOAD; - pi._arg2 = i._arg0; - pi._arg3 = (unsigned char)i._arg1; - return; - } - break; - case _OP_EQ:case _OP_NE: - if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) )) - { - pi.op = i.op; - pi._arg0 = i._arg0; - pi._arg1 = pi._arg1; - pi._arg2 = i._arg2; - pi._arg3 = MAX_FUNC_STACKSIZE; - return; - } - break; - case _OP_LOADNULLS: - if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) { - - pi._arg1 = pi._arg1 + 1; - pi.op = _OP_LOADNULLS; - return; - } - break; - case _OP_LINE: - if(pi.op == _OP_LINE) { - _instructions.pop_back(); - _lineinfos.pop_back(); - } - break; - } - } - _optimization = true; - _instructions.push_back(i); -} - -SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len) -{ - SQObjectPtr ns(SQString::Create(_sharedstate,s,len)); - _table(_strings)->NewSlot(ns,(SQInteger)1); - return ns; -} - -SQObject SQFuncState::CreateTable() -{ - SQObjectPtr nt(SQTable::Create(_sharedstate,0)); - _table(_strings)->NewSlot(nt,(SQInteger)1); - return nt; -} - -SQFunctionProto *SQFuncState::BuildProto() -{ - - SQFunctionProto *f=SQFunctionProto::Create(_ss,_instructions.size(), - _nliterals,_parameters.size(),_functions.size(),_outervalues.size(), - _lineinfos.size(),_localvarinfos.size(),_defaultparams.size()); - - SQObjectPtr refidx,key,val; - SQInteger idx; - - f->_stacksize = _stacksize; - f->_sourcename = _sourcename; - f->_bgenerator = _bgenerator; - f->_name = _name; - - while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) { - f->_literals[_integer(val)]=key; - refidx=idx; - } - - for(SQUnsignedInteger nf = 0; nf < _functions.size(); nf++) f->_functions[nf] = _functions[nf]; - for(SQUnsignedInteger np = 0; np < _parameters.size(); np++) f->_parameters[np] = _parameters[np]; - for(SQUnsignedInteger no = 0; no < _outervalues.size(); no++) f->_outervalues[no] = _outervalues[no]; - for(SQUnsignedInteger nl = 0; nl < _localvarinfos.size(); nl++) f->_localvarinfos[nl] = _localvarinfos[nl]; - for(SQUnsignedInteger ni = 0; ni < _lineinfos.size(); ni++) f->_lineinfos[ni] = _lineinfos[ni]; - for(SQUnsignedInteger nd = 0; nd < _defaultparams.size(); nd++) f->_defaultparams[nd] = _defaultparams[nd]; - - memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction)); - - f->_varparams = _varparams; - - return f; -} - -SQFuncState *SQFuncState::PushChildState(SQSharedState *ss) -{ - SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState)); - new (child) SQFuncState(ss,this,_errfunc,_errtarget); - _childstates.push_back(child); - return child; -} - -void SQFuncState::PopChildState() -{ - SQFuncState *child = _childstates.back(); - sq_delete(child,SQFuncState); - _childstates.pop_back(); -} - -SQFuncState::~SQFuncState() -{ - while(_childstates.size() > 0) - { - PopChildState(); - } -} - -#endif +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#ifndef NO_COMPILER +#include "sqcompiler.h" +#include "sqstring.h" +#include "sqfuncproto.h" +#include "sqtable.h" +#include "sqopcodes.h" +#include "sqfuncstate.h" + +#ifdef _DEBUG_DUMP +SQInstructionDesc g_InstrDesc[]={ + {_SC("_OP_LINE")}, + {_SC("_OP_LOAD")}, + {_SC("_OP_LOADINT")}, + {_SC("_OP_LOADFLOAT")}, + {_SC("_OP_DLOAD")}, + {_SC("_OP_TAILCALL")}, + {_SC("_OP_CALL")}, + {_SC("_OP_PREPCALL")}, + {_SC("_OP_PREPCALLK")}, + {_SC("_OP_GETK")}, + {_SC("_OP_MOVE")}, + {_SC("_OP_NEWSLOT")}, + {_SC("_OP_DELETE")}, + {_SC("_OP_SET")}, + {_SC("_OP_GET")}, + {_SC("_OP_EQ")}, + {_SC("_OP_NE")}, + {_SC("_OP_ADD")}, + {_SC("_OP_SUB")}, + {_SC("_OP_MUL")}, + {_SC("_OP_DIV")}, + {_SC("_OP_MOD")}, + {_SC("_OP_BITW")}, + {_SC("_OP_RETURN")}, + {_SC("_OP_LOADNULLS")}, + {_SC("_OP_LOADROOT")}, + {_SC("_OP_LOADBOOL")}, + {_SC("_OP_DMOVE")}, + {_SC("_OP_JMP")}, + {_SC("_OP_JCMP")}, + {_SC("_OP_JZ")}, + {_SC("_OP_SETOUTER")}, + {_SC("_OP_GETOUTER")}, + {_SC("_OP_NEWOBJ")}, + {_SC("_OP_APPENDARRAY")}, + {_SC("_OP_COMPARITH")}, + {_SC("_OP_INC")}, + {_SC("_OP_INCL")}, + {_SC("_OP_PINC")}, + {_SC("_OP_PINCL")}, + {_SC("_OP_CMP")}, + {_SC("_OP_EXISTS")}, + {_SC("_OP_INSTANCEOF")}, + {_SC("_OP_AND")}, + {_SC("_OP_OR")}, + {_SC("_OP_NEG")}, + {_SC("_OP_NOT")}, + {_SC("_OP_BWNOT")}, + {_SC("_OP_CLOSURE")}, + {_SC("_OP_YIELD")}, + {_SC("_OP_RESUME")}, + {_SC("_OP_FOREACH")}, + {_SC("_OP_POSTFOREACH")}, + {_SC("_OP_CLONE")}, + {_SC("_OP_TYPEOF")}, + {_SC("_OP_PUSHTRAP")}, + {_SC("_OP_POPTRAP")}, + {_SC("_OP_THROW")}, + {_SC("_OP_NEWSLOTA")}, + {_SC("_OP_GETBASE")}, + {_SC("_OP_CLOSE")}, + {_SC("_OP_JCMP")} +}; +#endif +void DumpLiteral(SQObjectPtr &o) +{ + switch(type(o)){ + case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break; + case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break; + case OT_INTEGER: scprintf(_SC("{") _PRINT_INT_FMT _SC("}"),_integer(o));break; + case OT_BOOL: scprintf(_SC("%s"),_integer(o)?_SC("true"):_SC("false"));break; + default: scprintf(_SC("(%s %p)"),GetTypeName(o),(void*)_rawval(o));break; break; //shut up compiler + } +} + +SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed) +{ + _nliterals = 0; + _literals = SQTable::Create(ss,0); + _strings = SQTable::Create(ss,0); + _sharedstate = ss; + _lastline = 0; + _optimization = true; + _parent = parent; + _stacksize = 0; + _traps = 0; + _returnexp = 0; + _varparams = false; + _errfunc = efunc; + _errtarget = ed; + _bgenerator = false; + _outers = 0; + _ss = ss; + +} + +void SQFuncState::Error(const SQChar *err) +{ + _errfunc(_errtarget,err); +} + +#ifdef _DEBUG_DUMP +void SQFuncState::Dump(SQFunctionProto *func) +{ + SQUnsignedInteger n=0,i; + SQInteger si; + scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction)); + scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject)); + scprintf(_SC("--------------------------------------------------------------------\n")); + scprintf(_SC("*****FUNCTION [%s]\n"),type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown")); + scprintf(_SC("-----LITERALS\n")); + SQObjectPtr refidx,key,val; + SQInteger idx; + SQObjectPtrVec templiterals; + templiterals.resize(_nliterals); + while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) { + refidx=idx; + templiterals[_integer(val)]=key; + } + for(i=0;i>\n")); + n=0; + for(i=0;i<_parameters.size();i++){ + scprintf(_SC("[%d] "),n); + DumpLiteral(_parameters[i]); + scprintf(_SC("\n")); + n++; + } + scprintf(_SC("-----LOCALS\n")); + for(si=0;si_nlocalvarinfos;si++){ + SQLocalVarInfo lvi=func->_localvarinfos[si]; + scprintf(_SC("[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op); + n++; + } + scprintf(_SC("-----LINE INFO\n")); + for(i=0;i<_lineinfos.size();i++){ + SQLineInfo li=_lineinfos[i]; + scprintf(_SC("op [%d] line [%d] \n"),li._op,li._line); + n++; + } + scprintf(_SC("-----dump\n")); + n=0; + for(i=0;i<_instructions.size();i++){ + SQInstruction &inst=_instructions[i]; + if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){ + + SQInteger lidx = inst._arg1; + scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0); + if(lidx >= 0xFFFFFFFF) + scprintf(_SC("null")); + else { + SQInteger refidx; + SQObjectPtr val,key,refo; + while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { + refo = refidx; + } + DumpLiteral(key); + } + if(inst.op != _OP_DLOAD) { + scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3); + } + else { + scprintf(_SC(" %d "),inst._arg2); + lidx = inst._arg3; + if(lidx >= 0xFFFFFFFF) + scprintf(_SC("null")); + else { + SQInteger refidx; + SQObjectPtr val,key,refo; + while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { + refo = refidx; + } + DumpLiteral(key); + scprintf(_SC("\n")); + } + } + } + else if(inst.op==_OP_LOADFLOAT) { + scprintf(_SC("[%03d] %15s %d %f %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3); + } + /* else if(inst.op==_OP_ARITH){ + scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); + }*/ + else { + scprintf(_SC("[%03d] %15s %d %d %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); + } + n++; + } + scprintf(_SC("-----\n")); + scprintf(_SC("stack size[%d]\n"),func->_stacksize); + scprintf(_SC("--------------------------------------------------------------------\n\n")); +} +#endif + +SQInteger SQFuncState::GetNumericConstant(const SQInteger cons) +{ + return GetConstant(SQObjectPtr(cons)); +} + +SQInteger SQFuncState::GetNumericConstant(const SQFloat cons) +{ + return GetConstant(SQObjectPtr(cons)); +} + +SQInteger SQFuncState::GetConstant(const SQObject &cons) +{ + SQObjectPtr val; + if(!_table(_literals)->Get(cons,val)) + { + val = _nliterals; + _table(_literals)->NewSlot(cons,val); + _nliterals++; + if(_nliterals > MAX_LITERALS) { + val.Null(); + Error(_SC("internal compiler error: too many literals")); + } + } + return _integer(val); +} + +void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3) +{ + _instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0); + _instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1); + _instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&arg2); + _instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3); +} + +void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val) +{ + switch(arg){ + case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break; + case 1:case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);break; + case 2:_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&val);break; + case 3:_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&val);break; + }; +} + +SQInteger SQFuncState::AllocStackPos() +{ + SQInteger npos=_vlocals.size(); + _vlocals.push_back(SQLocalVarInfo()); + if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) { + if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals")); + _stacksize=_vlocals.size(); + } + return npos; +} + +SQInteger SQFuncState::PushTarget(SQInteger n) +{ + if(n!=-1){ + _targetstack.push_back(n); + return n; + } + n=AllocStackPos(); + _targetstack.push_back(n); + return n; +} + +SQInteger SQFuncState::GetUpTarget(SQInteger n){ + return _targetstack[((_targetstack.size()-1)-n)]; +} + +SQInteger SQFuncState::TopTarget(){ + return _targetstack.back(); +} +SQInteger SQFuncState::PopTarget() +{ + SQInteger npos=_targetstack.back(); + SQLocalVarInfo &t=_vlocals[_targetstack.back()]; + if(type(t._name)==OT_NULL){ + _vlocals.pop_back(); + } + _targetstack.pop_back(); + return npos; +} + +SQInteger SQFuncState::GetStackSize() +{ + return _vlocals.size(); +} + +SQInteger SQFuncState::CountOuters(SQInteger stacksize) +{ + SQInteger outers = 0; + SQInteger k = _vlocals.size() - 1; + while(k >= stacksize) { + SQLocalVarInfo &lvi = _vlocals[k]; + k--; + if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer + outers++; + } + } + return outers; +} + +void SQFuncState::SetStackSize(SQInteger n) +{ + SQInteger size=_vlocals.size(); + while(size>n){ + size--; + SQLocalVarInfo lvi = _vlocals.back(); + if(type(lvi._name)!=OT_NULL){ + if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer + _outers--; + } + lvi._end_op = GetCurrentPos(); + _localvarinfos.push_back(lvi); + } + _vlocals.pop_back(); + } +} + +bool SQFuncState::IsConstant(const SQObject &name,SQObject &e) +{ + SQObjectPtr val; + if(_table(_sharedstate->_consts)->Get(name,val)) { + e = val; + return true; + } + return false; +} + +bool SQFuncState::IsLocal(SQUnsignedInteger stkpos) +{ + if(stkpos>=_vlocals.size())return false; + else if(type(_vlocals[stkpos]._name)!=OT_NULL)return true; + return false; +} + +SQInteger SQFuncState::PushLocalVariable(const SQObject &name) +{ + SQInteger pos=_vlocals.size(); + SQLocalVarInfo lvi; + lvi._name=name; + lvi._start_op=GetCurrentPos()+1; + lvi._pos=_vlocals.size(); + _vlocals.push_back(lvi); + if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size(); + return pos; +} + + + +SQInteger SQFuncState::GetLocalVariable(const SQObject &name) +{ + SQInteger locals=_vlocals.size(); + while(locals>=1){ + SQLocalVarInfo &lvi = _vlocals[locals-1]; + if(type(lvi._name)==OT_STRING && _string(lvi._name)==_string(name)){ + return locals-1; + } + locals--; + } + return -1; +} + +void SQFuncState::MarkLocalAsOuter(SQInteger pos) +{ + SQLocalVarInfo &lvi = _vlocals[pos]; + lvi._end_op = UINT_MINUS_ONE; + _outers++; +} + +SQInteger SQFuncState::GetOuterVariable(const SQObject &name) +{ + SQInteger outers = _outervalues.size(); + for(SQInteger i = 0; iGetLocalVariable(name); + if(pos == -1) { + pos = _parent->GetOuterVariable(name); + if(pos != -1) { + _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otOUTER)); //local + return _outervalues.size() - 1; + } + } + else { + _parent->MarkLocalAsOuter(pos); + _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local + return _outervalues.size() - 1; + + + } + } + return -1; +} + +void SQFuncState::AddParameter(const SQObject &name) +{ + PushLocalVariable(name); + _parameters.push_back(name); +} + +void SQFuncState::AddLineInfos(SQInteger line,bool lineop,bool force) +{ + if(_lastline!=line || force){ + SQLineInfo li; + li._line=line;li._op=(GetCurrentPos()+1); + if(lineop)AddInstruction(_OP_LINE,0,line); + if(_lastline!=line) { + _lineinfos.push_back(li); + } + _lastline=line; + } +} + +void SQFuncState::DiscardTarget() +{ + SQInteger discardedtarget = PopTarget(); + SQInteger size = _instructions.size(); + if(size > 0 && _optimization){ + SQInstruction &pi = _instructions[size-1];//previous instruction + switch(pi.op) { + case _OP_SET:case _OP_NEWSLOT:case _OP_SETOUTER:case _OP_CALL: + if(pi._arg0 == discardedtarget) { + pi._arg0 = 0xFF; + } + } + } +} + +void SQFuncState::AddInstruction(SQInstruction &i) +{ + SQInteger size = _instructions.size(); + if(size > 0 && _optimization){ //simple optimizer + SQInstruction &pi = _instructions[size-1];//previous instruction + switch(i.op) { + case _OP_JZ: + if( pi.op == _OP_CMP && pi._arg1 < 0xFF) { + pi.op = _OP_JCMP; + pi._arg0 = (unsigned char)pi._arg1; + pi._arg1 = i._arg1; + return; + } + case _OP_SET: + case _OP_NEWSLOT: + if(i._arg0 == i._arg3) { + i._arg0 = 0xFF; + } + break; + case _OP_SETOUTER: + if(i._arg0 == i._arg2) { + i._arg0 = 0xFF; + } + break; + case _OP_RETURN: + if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) { + pi.op = _OP_TAILCALL; + } else if(pi.op == _OP_CLOSE){ + pi = i; + return; + } + break; + case _OP_GET: + if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!IsLocal(pi._arg0))){ + pi._arg1 = pi._arg1; + pi._arg2 = (unsigned char)i._arg1; + pi.op = _OP_GETK; + pi._arg0 = i._arg0; + + return; + } + break; + case _OP_PREPCALL: + if( pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){ + pi.op = _OP_PREPCALLK; + pi._arg0 = i._arg0; + pi._arg1 = pi._arg1; + pi._arg2 = i._arg2; + pi._arg3 = i._arg3; + return; + } + break; + case _OP_APPENDARRAY: { + SQInteger aat = -1; + switch(pi.op) { + case _OP_LOAD: aat = AAT_LITERAL; break; + case _OP_LOADINT: aat = AAT_INT; break; + case _OP_LOADBOOL: aat = AAT_BOOL; break; + case _OP_LOADFLOAT: aat = AAT_FLOAT; break; + default: break; + } + if(aat != -1 && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){ + pi.op = _OP_APPENDARRAY; + pi._arg0 = i._arg0; + pi._arg1 = pi._arg1; + pi._arg2 = (unsigned char)aat; + pi._arg3 = MAX_FUNC_STACKSIZE; + return; + } + } + break; + case _OP_MOVE: + switch(pi.op) { + case _OP_GET: case _OP_ADD: case _OP_SUB: case _OP_MUL: case _OP_DIV: case _OP_MOD: case _OP_BITW: + case _OP_LOADINT: case _OP_LOADFLOAT: case _OP_LOADBOOL: case _OP_LOAD: + + if(pi._arg0 == i._arg1) + { + pi._arg0 = i._arg0; + _optimization = false; + //_result_elimination = false; + return; + } + } + + if(pi.op == _OP_MOVE) + { + pi.op = _OP_DMOVE; + pi._arg2 = i._arg0; + pi._arg3 = (unsigned char)i._arg1; + return; + } + break; + case _OP_LOAD: + if(pi.op == _OP_LOAD && i._arg1 < 256) { + pi.op = _OP_DLOAD; + pi._arg2 = i._arg0; + pi._arg3 = (unsigned char)i._arg1; + return; + } + break; + case _OP_EQ:case _OP_NE: + if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) )) + { + pi.op = i.op; + pi._arg0 = i._arg0; + pi._arg1 = pi._arg1; + pi._arg2 = i._arg2; + pi._arg3 = MAX_FUNC_STACKSIZE; + return; + } + break; + case _OP_LOADNULLS: + if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) { + + pi._arg1 = pi._arg1 + 1; + pi.op = _OP_LOADNULLS; + return; + } + break; + case _OP_LINE: + if(pi.op == _OP_LINE) { + _instructions.pop_back(); + _lineinfos.pop_back(); + } + break; + } + } + _optimization = true; + _instructions.push_back(i); +} + +SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len) +{ + SQObjectPtr ns(SQString::Create(_sharedstate,s,len)); + _table(_strings)->NewSlot(ns,(SQInteger)1); + return ns; +} + +SQObject SQFuncState::CreateTable() +{ + SQObjectPtr nt(SQTable::Create(_sharedstate,0)); + _table(_strings)->NewSlot(nt,(SQInteger)1); + return nt; +} + +SQFunctionProto *SQFuncState::BuildProto() +{ + + SQFunctionProto *f=SQFunctionProto::Create(_ss,_instructions.size(), + _nliterals,_parameters.size(),_functions.size(),_outervalues.size(), + _lineinfos.size(),_localvarinfos.size(),_defaultparams.size()); + + SQObjectPtr refidx,key,val; + SQInteger idx; + + f->_stacksize = _stacksize; + f->_sourcename = _sourcename; + f->_bgenerator = _bgenerator; + f->_name = _name; + + while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) { + f->_literals[_integer(val)]=key; + refidx=idx; + } + + for(SQUnsignedInteger nf = 0; nf < _functions.size(); nf++) f->_functions[nf] = _functions[nf]; + for(SQUnsignedInteger np = 0; np < _parameters.size(); np++) f->_parameters[np] = _parameters[np]; + for(SQUnsignedInteger no = 0; no < _outervalues.size(); no++) f->_outervalues[no] = _outervalues[no]; + for(SQUnsignedInteger nl = 0; nl < _localvarinfos.size(); nl++) f->_localvarinfos[nl] = _localvarinfos[nl]; + for(SQUnsignedInteger ni = 0; ni < _lineinfos.size(); ni++) f->_lineinfos[ni] = _lineinfos[ni]; + for(SQUnsignedInteger nd = 0; nd < _defaultparams.size(); nd++) f->_defaultparams[nd] = _defaultparams[nd]; + + memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction)); + + f->_varparams = _varparams; + + return f; +} + +SQFuncState *SQFuncState::PushChildState(SQSharedState *ss) +{ + SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState)); + new (child) SQFuncState(ss,this,_errfunc,_errtarget); + _childstates.push_back(child); + return child; +} + +void SQFuncState::PopChildState() +{ + SQFuncState *child = _childstates.back(); + sq_delete(child,SQFuncState); + _childstates.pop_back(); +} + +SQFuncState::~SQFuncState() +{ + while(_childstates.size() > 0) + { + PopChildState(); + } +} + +#endif diff --git a/squirrel_3_0_1_stable/squirrel/sqfuncstate.h b/squirrel_3_0_1_stable/squirrel/sqfuncstate.h index 1da13212a..2ae220087 100644 --- a/squirrel_3_0_1_stable/squirrel/sqfuncstate.h +++ b/squirrel_3_0_1_stable/squirrel/sqfuncstate.h @@ -1,91 +1,91 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQFUNCSTATE_H_ -#define _SQFUNCSTATE_H_ -/////////////////////////////////// -#include "squtils.h" - -struct SQFuncState -{ - SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed); - ~SQFuncState(); -#ifdef _DEBUG_DUMP - void Dump(SQFunctionProto *func); -#endif - void Error(const SQChar *err); - SQFuncState *PushChildState(SQSharedState *ss); - void PopChildState(); - void AddInstruction(SQOpcode _op,SQInteger arg0=0,SQInteger arg1=0,SQInteger arg2=0,SQInteger arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);} - void AddInstruction(SQInstruction &i); - void SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0); - void SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val); - SQInstruction &GetInstruction(SQInteger pos){return _instructions[pos];} - void PopInstructions(SQInteger size){for(SQInteger i=0;i _childstates; - SQInteger GetConstant(const SQObject &cons); -private: - CompilerErrorFunc _errfunc; - void *_errtarget; - SQSharedState *_ss; -}; - - -#endif //_SQFUNCSTATE_H_ - +/* see copyright notice in squirrel.h */ +#ifndef _SQFUNCSTATE_H_ +#define _SQFUNCSTATE_H_ +/////////////////////////////////// +#include "squtils.h" + +struct SQFuncState +{ + SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed); + ~SQFuncState(); +#ifdef _DEBUG_DUMP + void Dump(SQFunctionProto *func); +#endif + void Error(const SQChar *err); + SQFuncState *PushChildState(SQSharedState *ss); + void PopChildState(); + void AddInstruction(SQOpcode _op,SQInteger arg0=0,SQInteger arg1=0,SQInteger arg2=0,SQInteger arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);} + void AddInstruction(SQInstruction &i); + void SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0); + void SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val); + SQInstruction &GetInstruction(SQInteger pos){return _instructions[pos];} + void PopInstructions(SQInteger size){for(SQInteger i=0;i _childstates; + SQInteger GetConstant(const SQObject &cons); +private: + CompilerErrorFunc _errfunc; + void *_errtarget; + SQSharedState *_ss; +}; + + +#endif //_SQFUNCSTATE_H_ + diff --git a/squirrel_3_0_1_stable/squirrel/sqlexer.cpp b/squirrel_3_0_1_stable/squirrel/sqlexer.cpp index ab17ba619..ec1704b71 100644 --- a/squirrel_3_0_1_stable/squirrel/sqlexer.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqlexer.cpp @@ -1,489 +1,489 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#include -#include -#include "sqtable.h" -#include "sqstring.h" -#include "sqcompiler.h" -#include "sqlexer.h" - -#define CUR_CHAR (_currdata) -#define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;} -#define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB) -#define NEXT() {Next();_currentcolumn++;} -#define INIT_TEMP_STRING() { _longstr.resize(0);} -#define APPEND_CHAR(c) { _longstr.push_back(c);} -#define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));} -#define ADD_KEYWORD(key,id) _keywords->NewSlot( SQString::Create(ss, _SC(#key)) ,SQInteger(id)) - -SQLexer::SQLexer(){} -SQLexer::~SQLexer() -{ - _keywords->Release(); -} - -void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed) -{ - _errfunc = efunc; - _errtarget = ed; - _sharedstate = ss; - _keywords = SQTable::Create(ss, 26); - ADD_KEYWORD(while, TK_WHILE); - ADD_KEYWORD(do, TK_DO); - ADD_KEYWORD(if, TK_IF); - ADD_KEYWORD(else, TK_ELSE); - ADD_KEYWORD(break, TK_BREAK); - ADD_KEYWORD(continue, TK_CONTINUE); - ADD_KEYWORD(return, TK_RETURN); - ADD_KEYWORD(null, TK_NULL); - ADD_KEYWORD(function, TK_FUNCTION); - ADD_KEYWORD(local, TK_LOCAL); - ADD_KEYWORD(for, TK_FOR); - ADD_KEYWORD(foreach, TK_FOREACH); - ADD_KEYWORD(in, TK_IN); - ADD_KEYWORD(typeof, TK_TYPEOF); - ADD_KEYWORD(base, TK_BASE); - ADD_KEYWORD(delete, TK_DELETE); - ADD_KEYWORD(try, TK_TRY); - ADD_KEYWORD(catch, TK_CATCH); - ADD_KEYWORD(throw, TK_THROW); - ADD_KEYWORD(clone, TK_CLONE); - ADD_KEYWORD(yield, TK_YIELD); - ADD_KEYWORD(resume, TK_RESUME); - ADD_KEYWORD(switch, TK_SWITCH); - ADD_KEYWORD(case, TK_CASE); - ADD_KEYWORD(default, TK_DEFAULT); - ADD_KEYWORD(this, TK_THIS); - ADD_KEYWORD(class,TK_CLASS); - ADD_KEYWORD(extends,TK_EXTENDS); - ADD_KEYWORD(constructor,TK_CONSTRUCTOR); - ADD_KEYWORD(instanceof,TK_INSTANCEOF); - ADD_KEYWORD(true,TK_TRUE); - ADD_KEYWORD(false,TK_FALSE); - ADD_KEYWORD(static,TK_STATIC); - ADD_KEYWORD(enum,TK_ENUM); - ADD_KEYWORD(const,TK_CONST); - - _readf = rg; - _up = up; - _lasttokenline = _currentline = 1; - _currentcolumn = 0; - _prevtoken = -1; - _reached_eof = SQFalse; - Next(); -} - -void SQLexer::Error(const SQChar *err) -{ - _errfunc(_errtarget,err); -} - -void SQLexer::Next() -{ - SQInteger t = _readf(_up); - if(t > MAX_CHAR) Error(_SC("Invalid character")); - if(t != 0) { - _currdata = (LexChar)t; - return; - } - _currdata = SQUIRREL_EOB; - _reached_eof = SQTrue; -} - -const SQChar *SQLexer::Tok2Str(SQInteger tok) -{ - SQObjectPtr itr, key, val; - SQInteger nitr; - while((nitr = _keywords->Next(false,itr, key, val)) != -1) { - itr = (SQInteger)nitr; - if(((SQInteger)_integer(val)) == tok) - return _stringval(key); - } - return NULL; -} - -void SQLexer::LexBlockComment() -{ - bool done = false; - while(!done) { - switch(CUR_CHAR) { - case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue; - case _SC('\n'): _currentline++; NEXT(); continue; - case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment")); - default: NEXT(); - } - } -} -void SQLexer::LexLineComment() -{ - do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB())); -} - -SQInteger SQLexer::Lex() -{ - _lasttokenline = _currentline; - while(CUR_CHAR != SQUIRREL_EOB) { - switch(CUR_CHAR){ - case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue; - case _SC('\n'): - _currentline++; - _prevtoken=_curtoken; - _curtoken=_SC('\n'); - NEXT(); - _currentcolumn=1; - continue; - case _SC('#'): LexLineComment(); continue; - case _SC('/'): - NEXT(); - switch(CUR_CHAR){ - case _SC('*'): - NEXT(); - LexBlockComment(); - continue; - case _SC('/'): - LexLineComment(); - continue; - case _SC('='): - NEXT(); - RETURN_TOKEN(TK_DIVEQ); - continue; - case _SC('>'): - NEXT(); - RETURN_TOKEN(TK_ATTR_CLOSE); - continue; - default: - RETURN_TOKEN('/'); - } - case _SC('='): - NEXT(); - if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') } - else { NEXT(); RETURN_TOKEN(TK_EQ); } - case _SC('<'): - NEXT(); - switch(CUR_CHAR) { - case _SC('='): - NEXT(); - if(CUR_CHAR == _SC('>')) { - NEXT(); - RETURN_TOKEN(TK_3WAYSCMP); - } - RETURN_TOKEN(TK_LE) - break; - case _SC('-'): NEXT(); RETURN_TOKEN(TK_NEWSLOT); break; - case _SC('<'): NEXT(); RETURN_TOKEN(TK_SHIFTL); break; - case _SC('/'): NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); break; - } - RETURN_TOKEN('<'); - case _SC('>'): - NEXT(); - if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);} - else if(CUR_CHAR == _SC('>')){ - NEXT(); - if(CUR_CHAR == _SC('>')){ - NEXT(); - RETURN_TOKEN(TK_USHIFTR); - } - RETURN_TOKEN(TK_SHIFTR); - } - else { RETURN_TOKEN('>') } - case _SC('!'): - NEXT(); - if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')} - else { NEXT(); RETURN_TOKEN(TK_NE); } - case _SC('@'): { - SQInteger stype; - NEXT(); - if(CUR_CHAR != _SC('"')) { - RETURN_TOKEN('@'); - } - if((stype=ReadString('"',true))!=-1) { - RETURN_TOKEN(stype); - } - Error(_SC("error parsing the string")); - } - case _SC('"'): - case _SC('\''): { - SQInteger stype; - if((stype=ReadString(CUR_CHAR,false))!=-1){ - RETURN_TOKEN(stype); - } - Error(_SC("error parsing the string")); - } - case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'): - case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'): - {SQInteger ret = CUR_CHAR; - NEXT(); RETURN_TOKEN(ret); } - case _SC('.'): - NEXT(); - if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') } - NEXT(); - if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); } - NEXT(); - RETURN_TOKEN(TK_VARPARAMS); - case _SC('&'): - NEXT(); - if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') } - else { NEXT(); RETURN_TOKEN(TK_AND); } - case _SC('|'): - NEXT(); - if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') } - else { NEXT(); RETURN_TOKEN(TK_OR); } - case _SC(':'): - NEXT(); - if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') } - else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); } - case _SC('*'): - NEXT(); - if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);} - else RETURN_TOKEN('*'); - case _SC('%'): - NEXT(); - if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);} - else RETURN_TOKEN('%'); - case _SC('-'): - NEXT(); - if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);} - else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);} - else RETURN_TOKEN('-'); - case _SC('+'): - NEXT(); - if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);} - else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);} - else RETURN_TOKEN('+'); - case SQUIRREL_EOB: - return 0; - default:{ - if (scisdigit(CUR_CHAR)) { - SQInteger ret = ReadNumber(); - RETURN_TOKEN(ret); - } - else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) { - SQInteger t = ReadID(); - RETURN_TOKEN(t); - } - else { - SQInteger c = CUR_CHAR; - if (sciscntrl((int)c)) Error(_SC("unexpected character(control)")); - NEXT(); - RETURN_TOKEN(c); - } - RETURN_TOKEN(0); - } - } - } - return 0; -} - -SQInteger SQLexer::GetIDType(SQChar *s) -{ - SQObjectPtr t; - if(_keywords->Get(SQString::Create(_sharedstate, s), t)) { - return SQInteger(_integer(t)); - } - return TK_IDENTIFIER; -} - - -SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim) -{ - INIT_TEMP_STRING(); - NEXT(); - if(IS_EOB()) return -1; - for(;;) { - while(CUR_CHAR != ndelim) { - switch(CUR_CHAR) { - case SQUIRREL_EOB: - Error(_SC("unfinished string")); - return -1; - case _SC('\n'): - if(!verbatim) Error(_SC("newline in a constant")); - APPEND_CHAR(CUR_CHAR); NEXT(); - _currentline++; - break; - case _SC('\\'): - if(verbatim) { - APPEND_CHAR('\\'); NEXT(); - } - else { - NEXT(); - switch(CUR_CHAR) { - case _SC('x'): NEXT(); { - if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected")); - const SQInteger maxdigits = 4; - SQChar temp[maxdigits+1]; - SQInteger n = 0; - while(isxdigit(CUR_CHAR) && n < maxdigits) { - temp[n] = CUR_CHAR; - n++; - NEXT(); - } - temp[n] = 0; - SQChar *sTemp; - APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16)); - } - break; - case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break; - case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break; - case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break; - case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break; - case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break; - case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break; - case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break; - case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break; - case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break; - case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break; - case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break; - default: - Error(_SC("unrecognised escaper char")); - break; - } - } - break; - default: - APPEND_CHAR(CUR_CHAR); - NEXT(); - } - } - NEXT(); - if(verbatim && CUR_CHAR == '"') { //double quotation - APPEND_CHAR(CUR_CHAR); - NEXT(); - } - else { - break; - } - } - TERMINATE_BUFFER(); - SQInteger len = _longstr.size()-1; - if(ndelim == _SC('\'')) { - if(len == 0) Error(_SC("empty constant")); - if(len > 1) Error(_SC("constant too long")); - _nvalue = _longstr[0]; - return TK_INTEGER; - } - _svalue = &_longstr[0]; - return TK_STRING_LITERAL; -} - -void LexHexadecimal(const SQChar *s,SQUnsignedInteger *res) -{ - *res = 0; - while(*s != 0) - { - if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0'); - else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10); - else { assert(0); } - } -} - -void LexInteger(const SQChar *s,SQUnsignedInteger *res) -{ - *res = 0; - while(*s != 0) - { - *res = (*res)*10+((*s++)-'0'); - } -} - -SQInteger scisodigit(SQInteger c) { return c >= _SC('0') && c <= _SC('7'); } - -void LexOctal(const SQChar *s,SQUnsignedInteger *res) -{ - *res = 0; - while(*s != 0) - { - if(scisodigit(*s)) *res = (*res)*8+((*s++)-'0'); - else { assert(0); } - } -} - -SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; } - - -#define MAX_HEX_DIGITS (sizeof(SQInteger)*2) -SQInteger SQLexer::ReadNumber() -{ -#define TINT 1 -#define TFLOAT 2 -#define THEX 3 -#define TSCIENTIFIC 4 -#define TOCTAL 5 - SQInteger type = TINT, firstchar = CUR_CHAR; - SQChar *sTemp; - INIT_TEMP_STRING(); - NEXT(); - if(firstchar == _SC('0') && (toupper(CUR_CHAR) == _SC('X') || scisodigit(CUR_CHAR)) ) { - if(scisodigit(CUR_CHAR)) { - type = TOCTAL; - while(scisodigit(CUR_CHAR)) { - APPEND_CHAR(CUR_CHAR); - NEXT(); - } - if(scisdigit(CUR_CHAR)) Error(_SC("invalid octal number")); - } - else { - NEXT(); - type = THEX; - while(isxdigit(CUR_CHAR)) { - APPEND_CHAR(CUR_CHAR); - NEXT(); - } - if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number")); - } - } - else { - APPEND_CHAR((int)firstchar); - while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) { - if(CUR_CHAR == _SC('.')) type = TFLOAT; - if(isexponent(CUR_CHAR)) { - if(type != TFLOAT) Error(_SC("invalid numeric format")); - type = TSCIENTIFIC; - APPEND_CHAR(CUR_CHAR); - NEXT(); - if(CUR_CHAR == '+' || CUR_CHAR == '-'){ - APPEND_CHAR(CUR_CHAR); - NEXT(); - } - if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected")); - } - - APPEND_CHAR(CUR_CHAR); - NEXT(); - } - } - TERMINATE_BUFFER(); - switch(type) { - case TSCIENTIFIC: - case TFLOAT: - _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp); - return TK_FLOAT; - case TINT: - LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue); - return TK_INTEGER; - case THEX: - LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); - return TK_INTEGER; - case TOCTAL: - LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); - return TK_INTEGER; - } - return 0; -} - -SQInteger SQLexer::ReadID() -{ - SQInteger res; - INIT_TEMP_STRING(); - do { - APPEND_CHAR(CUR_CHAR); - NEXT(); - } while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_')); - TERMINATE_BUFFER(); - res = GetIDType(&_longstr[0]); - if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) { - _svalue = &_longstr[0]; - } - return res; -} +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include +#include +#include "sqtable.h" +#include "sqstring.h" +#include "sqcompiler.h" +#include "sqlexer.h" + +#define CUR_CHAR (_currdata) +#define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;} +#define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB) +#define NEXT() {Next();_currentcolumn++;} +#define INIT_TEMP_STRING() { _longstr.resize(0);} +#define APPEND_CHAR(c) { _longstr.push_back(c);} +#define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));} +#define ADD_KEYWORD(key,id) _keywords->NewSlot( SQString::Create(ss, _SC(#key)) ,SQInteger(id)) + +SQLexer::SQLexer(){} +SQLexer::~SQLexer() +{ + _keywords->Release(); +} + +void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed) +{ + _errfunc = efunc; + _errtarget = ed; + _sharedstate = ss; + _keywords = SQTable::Create(ss, 26); + ADD_KEYWORD(while, TK_WHILE); + ADD_KEYWORD(do, TK_DO); + ADD_KEYWORD(if, TK_IF); + ADD_KEYWORD(else, TK_ELSE); + ADD_KEYWORD(break, TK_BREAK); + ADD_KEYWORD(continue, TK_CONTINUE); + ADD_KEYWORD(return, TK_RETURN); + ADD_KEYWORD(null, TK_NULL); + ADD_KEYWORD(function, TK_FUNCTION); + ADD_KEYWORD(local, TK_LOCAL); + ADD_KEYWORD(for, TK_FOR); + ADD_KEYWORD(foreach, TK_FOREACH); + ADD_KEYWORD(in, TK_IN); + ADD_KEYWORD(typeof, TK_TYPEOF); + ADD_KEYWORD(base, TK_BASE); + ADD_KEYWORD(delete, TK_DELETE); + ADD_KEYWORD(try, TK_TRY); + ADD_KEYWORD(catch, TK_CATCH); + ADD_KEYWORD(throw, TK_THROW); + ADD_KEYWORD(clone, TK_CLONE); + ADD_KEYWORD(yield, TK_YIELD); + ADD_KEYWORD(resume, TK_RESUME); + ADD_KEYWORD(switch, TK_SWITCH); + ADD_KEYWORD(case, TK_CASE); + ADD_KEYWORD(default, TK_DEFAULT); + ADD_KEYWORD(this, TK_THIS); + ADD_KEYWORD(class,TK_CLASS); + ADD_KEYWORD(extends,TK_EXTENDS); + ADD_KEYWORD(constructor,TK_CONSTRUCTOR); + ADD_KEYWORD(instanceof,TK_INSTANCEOF); + ADD_KEYWORD(true,TK_TRUE); + ADD_KEYWORD(false,TK_FALSE); + ADD_KEYWORD(static,TK_STATIC); + ADD_KEYWORD(enum,TK_ENUM); + ADD_KEYWORD(const,TK_CONST); + + _readf = rg; + _up = up; + _lasttokenline = _currentline = 1; + _currentcolumn = 0; + _prevtoken = -1; + _reached_eof = SQFalse; + Next(); +} + +void SQLexer::Error(const SQChar *err) +{ + _errfunc(_errtarget,err); +} + +void SQLexer::Next() +{ + SQInteger t = _readf(_up); + if(t > MAX_CHAR) Error(_SC("Invalid character")); + if(t != 0) { + _currdata = (LexChar)t; + return; + } + _currdata = SQUIRREL_EOB; + _reached_eof = SQTrue; +} + +const SQChar *SQLexer::Tok2Str(SQInteger tok) +{ + SQObjectPtr itr, key, val; + SQInteger nitr; + while((nitr = _keywords->Next(false,itr, key, val)) != -1) { + itr = (SQInteger)nitr; + if(((SQInteger)_integer(val)) == tok) + return _stringval(key); + } + return NULL; +} + +void SQLexer::LexBlockComment() +{ + bool done = false; + while(!done) { + switch(CUR_CHAR) { + case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue; + case _SC('\n'): _currentline++; NEXT(); continue; + case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment")); + default: NEXT(); + } + } +} +void SQLexer::LexLineComment() +{ + do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB())); +} + +SQInteger SQLexer::Lex() +{ + _lasttokenline = _currentline; + while(CUR_CHAR != SQUIRREL_EOB) { + switch(CUR_CHAR){ + case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue; + case _SC('\n'): + _currentline++; + _prevtoken=_curtoken; + _curtoken=_SC('\n'); + NEXT(); + _currentcolumn=1; + continue; + case _SC('#'): LexLineComment(); continue; + case _SC('/'): + NEXT(); + switch(CUR_CHAR){ + case _SC('*'): + NEXT(); + LexBlockComment(); + continue; + case _SC('/'): + LexLineComment(); + continue; + case _SC('='): + NEXT(); + RETURN_TOKEN(TK_DIVEQ); + continue; + case _SC('>'): + NEXT(); + RETURN_TOKEN(TK_ATTR_CLOSE); + continue; + default: + RETURN_TOKEN('/'); + } + case _SC('='): + NEXT(); + if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') } + else { NEXT(); RETURN_TOKEN(TK_EQ); } + case _SC('<'): + NEXT(); + switch(CUR_CHAR) { + case _SC('='): + NEXT(); + if(CUR_CHAR == _SC('>')) { + NEXT(); + RETURN_TOKEN(TK_3WAYSCMP); + } + RETURN_TOKEN(TK_LE) + break; + case _SC('-'): NEXT(); RETURN_TOKEN(TK_NEWSLOT); break; + case _SC('<'): NEXT(); RETURN_TOKEN(TK_SHIFTL); break; + case _SC('/'): NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); break; + } + RETURN_TOKEN('<'); + case _SC('>'): + NEXT(); + if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);} + else if(CUR_CHAR == _SC('>')){ + NEXT(); + if(CUR_CHAR == _SC('>')){ + NEXT(); + RETURN_TOKEN(TK_USHIFTR); + } + RETURN_TOKEN(TK_SHIFTR); + } + else { RETURN_TOKEN('>') } + case _SC('!'): + NEXT(); + if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')} + else { NEXT(); RETURN_TOKEN(TK_NE); } + case _SC('@'): { + SQInteger stype; + NEXT(); + if(CUR_CHAR != _SC('"')) { + RETURN_TOKEN('@'); + } + if((stype=ReadString('"',true))!=-1) { + RETURN_TOKEN(stype); + } + Error(_SC("error parsing the string")); + } + case _SC('"'): + case _SC('\''): { + SQInteger stype; + if((stype=ReadString(CUR_CHAR,false))!=-1){ + RETURN_TOKEN(stype); + } + Error(_SC("error parsing the string")); + } + case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'): + case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'): + {SQInteger ret = CUR_CHAR; + NEXT(); RETURN_TOKEN(ret); } + case _SC('.'): + NEXT(); + if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') } + NEXT(); + if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); } + NEXT(); + RETURN_TOKEN(TK_VARPARAMS); + case _SC('&'): + NEXT(); + if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') } + else { NEXT(); RETURN_TOKEN(TK_AND); } + case _SC('|'): + NEXT(); + if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') } + else { NEXT(); RETURN_TOKEN(TK_OR); } + case _SC(':'): + NEXT(); + if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') } + else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); } + case _SC('*'): + NEXT(); + if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);} + else RETURN_TOKEN('*'); + case _SC('%'): + NEXT(); + if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);} + else RETURN_TOKEN('%'); + case _SC('-'): + NEXT(); + if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);} + else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);} + else RETURN_TOKEN('-'); + case _SC('+'): + NEXT(); + if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);} + else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);} + else RETURN_TOKEN('+'); + case SQUIRREL_EOB: + return 0; + default:{ + if (scisdigit(CUR_CHAR)) { + SQInteger ret = ReadNumber(); + RETURN_TOKEN(ret); + } + else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) { + SQInteger t = ReadID(); + RETURN_TOKEN(t); + } + else { + SQInteger c = CUR_CHAR; + if (sciscntrl((int)c)) Error(_SC("unexpected character(control)")); + NEXT(); + RETURN_TOKEN(c); + } + RETURN_TOKEN(0); + } + } + } + return 0; +} + +SQInteger SQLexer::GetIDType(SQChar *s) +{ + SQObjectPtr t; + if(_keywords->Get(SQString::Create(_sharedstate, s), t)) { + return SQInteger(_integer(t)); + } + return TK_IDENTIFIER; +} + + +SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim) +{ + INIT_TEMP_STRING(); + NEXT(); + if(IS_EOB()) return -1; + for(;;) { + while(CUR_CHAR != ndelim) { + switch(CUR_CHAR) { + case SQUIRREL_EOB: + Error(_SC("unfinished string")); + return -1; + case _SC('\n'): + if(!verbatim) Error(_SC("newline in a constant")); + APPEND_CHAR(CUR_CHAR); NEXT(); + _currentline++; + break; + case _SC('\\'): + if(verbatim) { + APPEND_CHAR('\\'); NEXT(); + } + else { + NEXT(); + switch(CUR_CHAR) { + case _SC('x'): NEXT(); { + if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected")); + const SQInteger maxdigits = 4; + SQChar temp[maxdigits+1]; + SQInteger n = 0; + while(isxdigit(CUR_CHAR) && n < maxdigits) { + temp[n] = CUR_CHAR; + n++; + NEXT(); + } + temp[n] = 0; + SQChar *sTemp; + APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16)); + } + break; + case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break; + case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break; + case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break; + case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break; + case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break; + case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break; + case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break; + case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break; + case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break; + case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break; + case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break; + default: + Error(_SC("unrecognised escaper char")); + break; + } + } + break; + default: + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + } + NEXT(); + if(verbatim && CUR_CHAR == '"') { //double quotation + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + else { + break; + } + } + TERMINATE_BUFFER(); + SQInteger len = _longstr.size()-1; + if(ndelim == _SC('\'')) { + if(len == 0) Error(_SC("empty constant")); + if(len > 1) Error(_SC("constant too long")); + _nvalue = _longstr[0]; + return TK_INTEGER; + } + _svalue = &_longstr[0]; + return TK_STRING_LITERAL; +} + +void LexHexadecimal(const SQChar *s,SQUnsignedInteger *res) +{ + *res = 0; + while(*s != 0) + { + if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0'); + else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10); + else { assert(0); } + } +} + +void LexInteger(const SQChar *s,SQUnsignedInteger *res) +{ + *res = 0; + while(*s != 0) + { + *res = (*res)*10+((*s++)-'0'); + } +} + +SQInteger scisodigit(SQInteger c) { return c >= _SC('0') && c <= _SC('7'); } + +void LexOctal(const SQChar *s,SQUnsignedInteger *res) +{ + *res = 0; + while(*s != 0) + { + if(scisodigit(*s)) *res = (*res)*8+((*s++)-'0'); + else { assert(0); } + } +} + +SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; } + + +#define MAX_HEX_DIGITS (sizeof(SQInteger)*2) +SQInteger SQLexer::ReadNumber() +{ +#define TINT 1 +#define TFLOAT 2 +#define THEX 3 +#define TSCIENTIFIC 4 +#define TOCTAL 5 + SQInteger type = TINT, firstchar = CUR_CHAR; + SQChar *sTemp; + INIT_TEMP_STRING(); + NEXT(); + if(firstchar == _SC('0') && (toupper(CUR_CHAR) == _SC('X') || scisodigit(CUR_CHAR)) ) { + if(scisodigit(CUR_CHAR)) { + type = TOCTAL; + while(scisodigit(CUR_CHAR)) { + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + if(scisdigit(CUR_CHAR)) Error(_SC("invalid octal number")); + } + else { + NEXT(); + type = THEX; + while(isxdigit(CUR_CHAR)) { + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number")); + } + } + else { + APPEND_CHAR((int)firstchar); + while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) { + if(CUR_CHAR == _SC('.')) type = TFLOAT; + if(isexponent(CUR_CHAR)) { + if(type != TFLOAT) Error(_SC("invalid numeric format")); + type = TSCIENTIFIC; + APPEND_CHAR(CUR_CHAR); + NEXT(); + if(CUR_CHAR == '+' || CUR_CHAR == '-'){ + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected")); + } + + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + } + TERMINATE_BUFFER(); + switch(type) { + case TSCIENTIFIC: + case TFLOAT: + _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp); + return TK_FLOAT; + case TINT: + LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue); + return TK_INTEGER; + case THEX: + LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); + return TK_INTEGER; + case TOCTAL: + LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); + return TK_INTEGER; + } + return 0; +} + +SQInteger SQLexer::ReadID() +{ + SQInteger res; + INIT_TEMP_STRING(); + do { + APPEND_CHAR(CUR_CHAR); + NEXT(); + } while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_')); + TERMINATE_BUFFER(); + res = GetIDType(&_longstr[0]); + if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) { + _svalue = &_longstr[0]; + } + return res; +} diff --git a/squirrel_3_0_1_stable/squirrel/sqlexer.h b/squirrel_3_0_1_stable/squirrel/sqlexer.h index d3283c6f7..49fadd90a 100644 --- a/squirrel_3_0_1_stable/squirrel/sqlexer.h +++ b/squirrel_3_0_1_stable/squirrel/sqlexer.h @@ -1,47 +1,47 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQLEXER_H_ -#define _SQLEXER_H_ - -#ifdef SQUNICODE -typedef SQChar LexChar; -#else -typedef unsigned char LexChar; -#endif - -struct SQLexer -{ - SQLexer(); - ~SQLexer(); - void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed); - void Error(const SQChar *err); - SQInteger Lex(); - const SQChar *Tok2Str(SQInteger tok); -private: - SQInteger GetIDType(SQChar *s); - SQInteger ReadString(SQInteger ndelim,bool verbatim); - SQInteger ReadNumber(); - void LexBlockComment(); - void LexLineComment(); - SQInteger ReadID(); - void Next(); - SQInteger _curtoken; - SQTable *_keywords; - SQBool _reached_eof; -public: - SQInteger _prevtoken; - SQInteger _currentline; - SQInteger _lasttokenline; - SQInteger _currentcolumn; - const SQChar *_svalue; - SQInteger _nvalue; - SQFloat _fvalue; - SQLEXREADFUNC _readf; - SQUserPointer _up; - LexChar _currdata; - SQSharedState *_sharedstate; - sqvector _longstr; - CompilerErrorFunc _errfunc; - void *_errtarget; -}; - -#endif +/* see copyright notice in squirrel.h */ +#ifndef _SQLEXER_H_ +#define _SQLEXER_H_ + +#ifdef SQUNICODE +typedef SQChar LexChar; +#else +typedef unsigned char LexChar; +#endif + +struct SQLexer +{ + SQLexer(); + ~SQLexer(); + void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed); + void Error(const SQChar *err); + SQInteger Lex(); + const SQChar *Tok2Str(SQInteger tok); +private: + SQInteger GetIDType(SQChar *s); + SQInteger ReadString(SQInteger ndelim,bool verbatim); + SQInteger ReadNumber(); + void LexBlockComment(); + void LexLineComment(); + SQInteger ReadID(); + void Next(); + SQInteger _curtoken; + SQTable *_keywords; + SQBool _reached_eof; +public: + SQInteger _prevtoken; + SQInteger _currentline; + SQInteger _lasttokenline; + SQInteger _currentcolumn; + const SQChar *_svalue; + SQInteger _nvalue; + SQFloat _fvalue; + SQLEXREADFUNC _readf; + SQUserPointer _up; + LexChar _currdata; + SQSharedState *_sharedstate; + sqvector _longstr; + CompilerErrorFunc _errfunc; + void *_errtarget; +}; + +#endif diff --git a/squirrel_3_0_1_stable/squirrel/sqmem.cpp b/squirrel_3_0_1_stable/squirrel/sqmem.cpp index 520f7eb76..6faf8165a 100644 --- a/squirrel_3_0_1_stable/squirrel/sqmem.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqmem.cpp @@ -1,9 +1,9 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -void *sq_vm_malloc(SQUnsignedInteger size){ return malloc(size); } - -void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size){ return realloc(p, size); } - -void sq_vm_free(void *p, SQUnsignedInteger size){ free(p); } +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +void *sq_vm_malloc(SQUnsignedInteger size){ return malloc(size); } + +void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size){ return realloc(p, size); } + +void sq_vm_free(void *p, SQUnsignedInteger size){ free(p); } diff --git a/squirrel_3_0_1_stable/squirrel/sqobject.cpp b/squirrel_3_0_1_stable/squirrel/sqobject.cpp index 418a6d656..e32cd72b9 100644 --- a/squirrel_3_0_1_stable/squirrel/sqobject.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqobject.cpp @@ -1,655 +1,655 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#include "sqvm.h" -#include "sqstring.h" -#include "sqarray.h" -#include "sqtable.h" -#include "squserdata.h" -#include "sqfuncproto.h" -#include "sqclass.h" -#include "sqclosure.h" - - -const SQChar *IdType2Name(SQObjectType type) -{ - switch(_RAW_TYPE(type)) - { - case _RT_NULL:return _SC("null"); - case _RT_INTEGER:return _SC("integer"); - case _RT_FLOAT:return _SC("float"); - case _RT_BOOL:return _SC("bool"); - case _RT_STRING:return _SC("string"); - case _RT_TABLE:return _SC("table"); - case _RT_ARRAY:return _SC("array"); - case _RT_GENERATOR:return _SC("generator"); - case _RT_CLOSURE: - case _RT_NATIVECLOSURE: - return _SC("function"); - case _RT_USERDATA: - case _RT_USERPOINTER: - return _SC("userdata"); - case _RT_THREAD: return _SC("thread"); - case _RT_FUNCPROTO: return _SC("function"); - case _RT_CLASS: return _SC("class"); - case _RT_INSTANCE: return _SC("instance"); - case _RT_WEAKREF: return _SC("weakref"); - case _RT_OUTER: return _SC("outer"); - default: - return NULL; - } -} - -const SQChar *GetTypeName(const SQObjectPtr &obj1) -{ - return IdType2Name(type(obj1)); -} - -SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len) -{ - SQString *str=ADD_STRING(ss,s,len); - return str; -} - -void SQString::Release() -{ - REMOVE_STRING(_sharedstate,this); -} - -SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) -{ - SQInteger idx = (SQInteger)TranslateIndex(refpos); - while(idx < _len){ - outkey = (SQInteger)idx; - outval = SQInteger(_val[idx]); - //return idx for the next iteration - return ++idx; - } - //nothing to iterate anymore - return -1; -} - -SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx) -{ - switch(type(idx)){ - case OT_NULL: - return 0; - case OT_INTEGER: - return (SQUnsignedInteger)_integer(idx); - default: assert(0); break; - } - return 0; -} - -SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type) -{ - if(!_weakref) { - sq_new(_weakref,SQWeakRef); - _weakref->_obj._type = type; - _weakref->_obj._unVal.pRefCounted = this; - } - return _weakref; -} - -SQRefCounted::~SQRefCounted() -{ - if(_weakref) { - _weakref->_obj._type = OT_NULL; - _weakref->_obj._unVal.pRefCounted = NULL; - } -} - -void SQWeakRef::Release() { - if(ISREFCOUNTED(_obj._type)) { - _obj._unVal.pRefCounted->_weakref = NULL; - } - sq_delete(this,SQWeakRef); -} - -bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) { - if(_delegate) { - return _delegate->Get((*_ss(v)->_metamethods)[mm],res); - } - return false; -} - -bool SQDelegable::SetDelegate(SQTable *mt) -{ - SQTable *temp = mt; - if(temp == this) return false; - while (temp) { - if (temp->_delegate == this) return false; //cycle detected - temp = temp->_delegate; - } - if (mt) __ObjAddRef(mt); - __ObjRelease(_delegate); - _delegate = mt; - return true; -} - -bool SQGenerator::Yield(SQVM *v,SQInteger target) -{ - if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator")); return false;} - if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; } - SQInteger size = v->_top-v->_stackbase; - - _stack.resize(size); - SQObject _this = v->_stack[v->_stackbase]; - _stack._vals[0] = ISREFCOUNTED(type(_this)) ? SQObjectPtr(_refcounted(_this)->GetWeakRef(type(_this))) : _this; - for(SQInteger n =1; n_stack[v->_stackbase+n]; - } - for(SQInteger j =0; j < size; j++) - { - v->_stack[v->_stackbase+j].Null(); - } - - _ci = *v->ci; - _ci._generator=NULL; - for(SQInteger i=0;i<_ci._etraps;i++) { - _etraps.push_back(v->_etraps.top()); - v->_etraps.pop_back(); - } - _state=eSuspended; - return true; -} - -bool SQGenerator::Resume(SQVM *v,SQObjectPtr &dest) -{ - if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; } - if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; } - SQInteger size = _stack.size(); - SQInteger target = &dest - &(v->_stack._vals[v->_stackbase]); - assert(target>=0 && target<=255); - if(!v->EnterFrame(v->_top, v->_top + size, false)) - return false; - v->ci->_generator = this; - v->ci->_target = (SQInt32)target; - v->ci->_closure = _ci._closure; - v->ci->_ip = _ci._ip; - v->ci->_literals = _ci._literals; - v->ci->_ncalls = _ci._ncalls; - v->ci->_etraps = _ci._etraps; - v->ci->_root = _ci._root; - - - for(SQInteger i=0;i<_ci._etraps;i++) { - v->_etraps.push_back(_etraps.top()); - _etraps.pop_back(); - } - SQObject _this = _stack._vals[0]; - v->_stack[v->_stackbase] = type(_this) == OT_WEAKREF ? _weakref(_this)->_obj : _this; - - for(SQInteger n = 1; n_stack[v->_stackbase+n] = _stack._vals[n]; - _stack._vals[n].Null(); - } - - _state=eRunning; - if (v->_debughook) - v->CallDebugHook(_SC('c')); - - return true; -} - -void SQArray::Extend(const SQArray *a){ - SQInteger xlen; - if((xlen=a->Size())) - for(SQInteger i=0;i_values[i]); -} - -const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop) -{ - SQUnsignedInteger nvars=_nlocalvarinfos; - const SQChar *res=NULL; - if(nvars>=nseq){ - for(SQUnsignedInteger i=0;i=nop) - { - if(nseq==0){ - vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]); - res=_stringval(_localvarinfos[i]._name); - break; - } - nseq--; - } - } - } - return res; -} - - -SQInteger SQFunctionProto::GetLine(SQInstruction *curr) -{ - SQInteger op = (SQInteger)(curr-_instructions); - SQInteger line=_lineinfos[0]._line; - SQInteger low = 0; - SQInteger high = _nlineinfos - 1; - SQInteger mid = 0; - while(low <= high) - { - mid = low + ((high - low) >> 1); - SQInteger curop = _lineinfos[mid]._op; - if(curop > op) - { - high = mid - 1; - } - else if(curop < op) { - if(mid < (_nlineinfos - 1) - && _lineinfos[mid + 1]._op >= op) { - break; - } - low = mid + 1; - } - else { //equal - break; - } - } - - line = _lineinfos[mid]._line; - return line; -} - -SQClosure::~SQClosure() -{ - __ObjRelease(_env); - __ObjRelease(_base); - REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); -} - -#define _CHECK_IO(exp) { if(!exp)return false; } -bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size) -{ - if(write(up,dest,size) != size) { - v->Raise_Error(_SC("io error (write function failure)")); - return false; - } - return true; -} - -bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size) -{ - if(size && read(up,dest,size) != size) { - v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated")); - return false; - } - return true; -} - -bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUnsignedInteger32 tag) -{ - return SafeWrite(v,write,up,&tag,sizeof(tag)); -} - -bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUnsignedInteger32 tag) -{ - SQUnsignedInteger32 t; - _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t))); - if(t != tag){ - v->Raise_Error(_SC("invalid or corrupted closure stream")); - return false; - } - return true; -} - -bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o) -{ - SQUnsignedInteger32 _type = (SQUnsignedInteger32)type(o); - _CHECK_IO(SafeWrite(v,write,up,&_type,sizeof(_type))); - switch(type(o)){ - case OT_STRING: - _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger))); - _CHECK_IO(SafeWrite(v,write,up,_stringval(o),rsl(_string(o)->_len))); - break; - case OT_INTEGER: - _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break; - case OT_FLOAT: - _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break; - case OT_NULL: - break; - default: - v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o)); - return false; - } - return true; -} - -bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o) -{ - SQUnsignedInteger32 _type; - _CHECK_IO(SafeRead(v,read,up,&_type,sizeof(_type))); - SQObjectType t = (SQObjectType)_type; - switch(t){ - case OT_STRING:{ - SQInteger len; - _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger))); - _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(rsl(len)),rsl(len))); - o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len); - } - break; - case OT_INTEGER:{ - SQInteger i; - _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break; - } - case OT_FLOAT:{ - SQFloat f; - _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break; - } - case OT_NULL: - o.Null(); - break; - default: - v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t)); - return false; - } - return true; -} - -bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) -{ - _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD)); - _CHECK_IO(WriteTag(v,write,up,sizeof(SQChar))); - _CHECK_IO(WriteTag(v,write,up,sizeof(SQInteger))); - _CHECK_IO(WriteTag(v,write,up,sizeof(SQFloat))); - _CHECK_IO(_function->Save(v,up,write)); - _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL)); - return true; -} - -bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret) -{ - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD)); - _CHECK_IO(CheckTag(v,read,up,sizeof(SQChar))); - _CHECK_IO(CheckTag(v,read,up,sizeof(SQInteger))); - _CHECK_IO(CheckTag(v,read,up,sizeof(SQFloat))); - SQObjectPtr func; - _CHECK_IO(SQFunctionProto::Load(v,up,read,func)); - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL)); - ret = SQClosure::Create(_ss(v),_funcproto(func)); - return true; -} - -SQFunctionProto::SQFunctionProto(SQSharedState *ss) -{ - _stacksize=0; - _bgenerator=false; - INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); -} - -SQFunctionProto::~SQFunctionProto() -{ - REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); -} - -bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) -{ - SQInteger i,nliterals = _nliterals,nparameters = _nparameters; - SQInteger noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos; - SQInteger nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions; - SQInteger ndefaultparams = _ndefaultparams; - _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(WriteObject(v,up,write,_sourcename)); - _CHECK_IO(WriteObject(v,up,write,_name)); - _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(SafeWrite(v,write,up,&nliterals,sizeof(nliterals))); - _CHECK_IO(SafeWrite(v,write,up,&nparameters,sizeof(nparameters))); - _CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues))); - _CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos))); - _CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos))); - _CHECK_IO(SafeWrite(v,write,up,&ndefaultparams,sizeof(ndefaultparams))); - _CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions))); - _CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions))); - _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); - for(i=0;iSave(v,up,write)); - } - _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize))); - _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator))); - _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams))); - return true; -} - -bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret) -{ - SQInteger i, nliterals,nparameters; - SQInteger noutervalues ,nlocalvarinfos ; - SQInteger nlineinfos,ninstructions ,nfunctions,ndefaultparams ; - SQObjectPtr sourcename, name; - SQObjectPtr o; - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(ReadObject(v, up, read, sourcename)); - _CHECK_IO(ReadObject(v, up, read, name)); - - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(SafeRead(v,read,up, &nliterals, sizeof(nliterals))); - _CHECK_IO(SafeRead(v,read,up, &nparameters, sizeof(nparameters))); - _CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues))); - _CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos))); - _CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos))); - _CHECK_IO(SafeRead(v,read,up, &ndefaultparams, sizeof(ndefaultparams))); - _CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions))); - _CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions))); - - - SQFunctionProto *f = SQFunctionProto::Create(_opt_ss(v),ninstructions,nliterals,nparameters, - nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams); - SQObjectPtr proto = f; //gets a ref in case of failure - f->_sourcename = sourcename; - f->_name = name; - - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - - for(i = 0;i < nliterals; i++){ - _CHECK_IO(ReadObject(v, up, read, o)); - f->_literals[i] = o; - } - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - - for(i = 0; i < nparameters; i++){ - _CHECK_IO(ReadObject(v, up, read, o)); - f->_parameters[i] = o; - } - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - - for(i = 0; i < noutervalues; i++){ - SQUnsignedInteger type; - SQObjectPtr name; - _CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger))); - _CHECK_IO(ReadObject(v, up, read, o)); - _CHECK_IO(ReadObject(v, up, read, name)); - f->_outervalues[i] = SQOuterVar(name,o, (SQOuterType)type); - } - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - - for(i = 0; i < nlocalvarinfos; i++){ - SQLocalVarInfo lvi; - _CHECK_IO(ReadObject(v, up, read, lvi._name)); - _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(SQUnsignedInteger))); - _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(SQUnsignedInteger))); - _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(SQUnsignedInteger))); - f->_localvarinfos[i] = lvi; - } - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(SQLineInfo)*nlineinfos)); - - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(SafeRead(v,read,up, f->_defaultparams, sizeof(SQInteger)*ndefaultparams)); - - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(SQInstruction)*ninstructions)); - - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - for(i = 0; i < nfunctions; i++){ - _CHECK_IO(_funcproto(o)->Load(v, up, read, o)); - f->_functions[i] = o; - } - _CHECK_IO(SafeRead(v,read,up, &f->_stacksize, sizeof(f->_stacksize))); - _CHECK_IO(SafeRead(v,read,up, &f->_bgenerator, sizeof(f->_bgenerator))); - _CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams))); - - ret = f; - return true; -} - -#ifndef NO_GARBAGE_COLLECTOR - -#define START_MARK() if(!(_uiRef&MARK_FLAG)){ \ - _uiRef|=MARK_FLAG; - -#define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \ - AddToChain(chain, this); } - -void SQVM::Mark(SQCollectable **chain) -{ - START_MARK() - SQSharedState::MarkObject(_lasterror,chain); - SQSharedState::MarkObject(_errorhandler,chain); - SQSharedState::MarkObject(_debughook_closure,chain); - SQSharedState::MarkObject(_roottable, chain); - SQSharedState::MarkObject(temp_reg, chain); - for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain); - for(SQInteger k = 0; k < _callsstacksize; k++) SQSharedState::MarkObject(_callsstack[k]._closure, chain); - END_MARK() -} - -void SQArray::Mark(SQCollectable **chain) -{ - START_MARK() - SQInteger len = _values.size(); - for(SQInteger i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain); - END_MARK() -} -void SQTable::Mark(SQCollectable **chain) -{ - START_MARK() - if(_delegate) _delegate->Mark(chain); - SQInteger len = _numofnodes; - for(SQInteger i = 0; i < len; i++){ - SQSharedState::MarkObject(_nodes[i].key, chain); - SQSharedState::MarkObject(_nodes[i].val, chain); - } - END_MARK() -} - -void SQClass::Mark(SQCollectable **chain) -{ - START_MARK() - _members->Mark(chain); - if(_base) _base->Mark(chain); - SQSharedState::MarkObject(_attributes, chain); - for(SQUnsignedInteger i =0; i< _defaultvalues.size(); i++) { - SQSharedState::MarkObject(_defaultvalues[i].val, chain); - SQSharedState::MarkObject(_defaultvalues[i].attrs, chain); - } - for(SQUnsignedInteger j =0; j< _methods.size(); j++) { - SQSharedState::MarkObject(_methods[j].val, chain); - SQSharedState::MarkObject(_methods[j].attrs, chain); - } - for(SQUnsignedInteger k =0; k< MT_LAST; k++) { - SQSharedState::MarkObject(_metamethods[k], chain); - } - END_MARK() -} - -void SQInstance::Mark(SQCollectable **chain) -{ - START_MARK() - _class->Mark(chain); - SQUnsignedInteger nvalues = _class->_defaultvalues.size(); - for(SQUnsignedInteger i =0; i< nvalues; i++) { - SQSharedState::MarkObject(_values[i], chain); - } - END_MARK() -} - -void SQGenerator::Mark(SQCollectable **chain) -{ - START_MARK() - for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain); - SQSharedState::MarkObject(_closure, chain); - END_MARK() -} - -void SQFunctionProto::Mark(SQCollectable **chain) -{ - START_MARK() - for(SQInteger i = 0; i < _nliterals; i++) SQSharedState::MarkObject(_literals[i], chain); - for(SQInteger k = 0; k < _nfunctions; k++) SQSharedState::MarkObject(_functions[k], chain); - END_MARK() -} - -void SQClosure::Mark(SQCollectable **chain) -{ - START_MARK() - if(_base) _base->Mark(chain); - SQFunctionProto *fp = _function; - fp->Mark(chain); - for(SQInteger i = 0; i < fp->_noutervalues; i++) SQSharedState::MarkObject(_outervalues[i], chain); - for(SQInteger k = 0; k < fp->_ndefaultparams; k++) SQSharedState::MarkObject(_defaultparams[k], chain); - END_MARK() -} - -void SQNativeClosure::Mark(SQCollectable **chain) -{ - START_MARK() - for(SQUnsignedInteger i = 0; i < _noutervalues; i++) SQSharedState::MarkObject(_outervalues[i], chain); - END_MARK() -} - -void SQOuter::Mark(SQCollectable **chain) -{ - START_MARK() - /* If the valptr points to a closed value, that value is alive */ - if(_valptr == &_value) { - SQSharedState::MarkObject(_value, chain); - } - END_MARK() -} - -void SQUserData::Mark(SQCollectable **chain){ - START_MARK() - if(_delegate) _delegate->Mark(chain); - END_MARK() -} - -void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; } - -#endif - +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqstring.h" +#include "sqarray.h" +#include "sqtable.h" +#include "squserdata.h" +#include "sqfuncproto.h" +#include "sqclass.h" +#include "sqclosure.h" + + +const SQChar *IdType2Name(SQObjectType type) +{ + switch(_RAW_TYPE(type)) + { + case _RT_NULL:return _SC("null"); + case _RT_INTEGER:return _SC("integer"); + case _RT_FLOAT:return _SC("float"); + case _RT_BOOL:return _SC("bool"); + case _RT_STRING:return _SC("string"); + case _RT_TABLE:return _SC("table"); + case _RT_ARRAY:return _SC("array"); + case _RT_GENERATOR:return _SC("generator"); + case _RT_CLOSURE: + case _RT_NATIVECLOSURE: + return _SC("function"); + case _RT_USERDATA: + case _RT_USERPOINTER: + return _SC("userdata"); + case _RT_THREAD: return _SC("thread"); + case _RT_FUNCPROTO: return _SC("function"); + case _RT_CLASS: return _SC("class"); + case _RT_INSTANCE: return _SC("instance"); + case _RT_WEAKREF: return _SC("weakref"); + case _RT_OUTER: return _SC("outer"); + default: + return NULL; + } +} + +const SQChar *GetTypeName(const SQObjectPtr &obj1) +{ + return IdType2Name(type(obj1)); +} + +SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len) +{ + SQString *str=ADD_STRING(ss,s,len); + return str; +} + +void SQString::Release() +{ + REMOVE_STRING(_sharedstate,this); +} + +SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) +{ + SQInteger idx = (SQInteger)TranslateIndex(refpos); + while(idx < _len){ + outkey = (SQInteger)idx; + outval = SQInteger(_val[idx]); + //return idx for the next iteration + return ++idx; + } + //nothing to iterate anymore + return -1; +} + +SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx) +{ + switch(type(idx)){ + case OT_NULL: + return 0; + case OT_INTEGER: + return (SQUnsignedInteger)_integer(idx); + default: assert(0); break; + } + return 0; +} + +SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type) +{ + if(!_weakref) { + sq_new(_weakref,SQWeakRef); + _weakref->_obj._type = type; + _weakref->_obj._unVal.pRefCounted = this; + } + return _weakref; +} + +SQRefCounted::~SQRefCounted() +{ + if(_weakref) { + _weakref->_obj._type = OT_NULL; + _weakref->_obj._unVal.pRefCounted = NULL; + } +} + +void SQWeakRef::Release() { + if(ISREFCOUNTED(_obj._type)) { + _obj._unVal.pRefCounted->_weakref = NULL; + } + sq_delete(this,SQWeakRef); +} + +bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) { + if(_delegate) { + return _delegate->Get((*_ss(v)->_metamethods)[mm],res); + } + return false; +} + +bool SQDelegable::SetDelegate(SQTable *mt) +{ + SQTable *temp = mt; + if(temp == this) return false; + while (temp) { + if (temp->_delegate == this) return false; //cycle detected + temp = temp->_delegate; + } + if (mt) __ObjAddRef(mt); + __ObjRelease(_delegate); + _delegate = mt; + return true; +} + +bool SQGenerator::Yield(SQVM *v,SQInteger target) +{ + if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator")); return false;} + if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; } + SQInteger size = v->_top-v->_stackbase; + + _stack.resize(size); + SQObject _this = v->_stack[v->_stackbase]; + _stack._vals[0] = ISREFCOUNTED(type(_this)) ? SQObjectPtr(_refcounted(_this)->GetWeakRef(type(_this))) : _this; + for(SQInteger n =1; n_stack[v->_stackbase+n]; + } + for(SQInteger j =0; j < size; j++) + { + v->_stack[v->_stackbase+j].Null(); + } + + _ci = *v->ci; + _ci._generator=NULL; + for(SQInteger i=0;i<_ci._etraps;i++) { + _etraps.push_back(v->_etraps.top()); + v->_etraps.pop_back(); + } + _state=eSuspended; + return true; +} + +bool SQGenerator::Resume(SQVM *v,SQObjectPtr &dest) +{ + if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; } + if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; } + SQInteger size = _stack.size(); + SQInteger target = &dest - &(v->_stack._vals[v->_stackbase]); + assert(target>=0 && target<=255); + if(!v->EnterFrame(v->_top, v->_top + size, false)) + return false; + v->ci->_generator = this; + v->ci->_target = (SQInt32)target; + v->ci->_closure = _ci._closure; + v->ci->_ip = _ci._ip; + v->ci->_literals = _ci._literals; + v->ci->_ncalls = _ci._ncalls; + v->ci->_etraps = _ci._etraps; + v->ci->_root = _ci._root; + + + for(SQInteger i=0;i<_ci._etraps;i++) { + v->_etraps.push_back(_etraps.top()); + _etraps.pop_back(); + } + SQObject _this = _stack._vals[0]; + v->_stack[v->_stackbase] = type(_this) == OT_WEAKREF ? _weakref(_this)->_obj : _this; + + for(SQInteger n = 1; n_stack[v->_stackbase+n] = _stack._vals[n]; + _stack._vals[n].Null(); + } + + _state=eRunning; + if (v->_debughook) + v->CallDebugHook(_SC('c')); + + return true; +} + +void SQArray::Extend(const SQArray *a){ + SQInteger xlen; + if((xlen=a->Size())) + for(SQInteger i=0;i_values[i]); +} + +const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop) +{ + SQUnsignedInteger nvars=_nlocalvarinfos; + const SQChar *res=NULL; + if(nvars>=nseq){ + for(SQUnsignedInteger i=0;i=nop) + { + if(nseq==0){ + vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]); + res=_stringval(_localvarinfos[i]._name); + break; + } + nseq--; + } + } + } + return res; +} + + +SQInteger SQFunctionProto::GetLine(SQInstruction *curr) +{ + SQInteger op = (SQInteger)(curr-_instructions); + SQInteger line=_lineinfos[0]._line; + SQInteger low = 0; + SQInteger high = _nlineinfos - 1; + SQInteger mid = 0; + while(low <= high) + { + mid = low + ((high - low) >> 1); + SQInteger curop = _lineinfos[mid]._op; + if(curop > op) + { + high = mid - 1; + } + else if(curop < op) { + if(mid < (_nlineinfos - 1) + && _lineinfos[mid + 1]._op >= op) { + break; + } + low = mid + 1; + } + else { //equal + break; + } + } + + line = _lineinfos[mid]._line; + return line; +} + +SQClosure::~SQClosure() +{ + __ObjRelease(_env); + __ObjRelease(_base); + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); +} + +#define _CHECK_IO(exp) { if(!exp)return false; } +bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size) +{ + if(write(up,dest,size) != size) { + v->Raise_Error(_SC("io error (write function failure)")); + return false; + } + return true; +} + +bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size) +{ + if(size && read(up,dest,size) != size) { + v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated")); + return false; + } + return true; +} + +bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUnsignedInteger32 tag) +{ + return SafeWrite(v,write,up,&tag,sizeof(tag)); +} + +bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUnsignedInteger32 tag) +{ + SQUnsignedInteger32 t; + _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t))); + if(t != tag){ + v->Raise_Error(_SC("invalid or corrupted closure stream")); + return false; + } + return true; +} + +bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o) +{ + SQUnsignedInteger32 _type = (SQUnsignedInteger32)type(o); + _CHECK_IO(SafeWrite(v,write,up,&_type,sizeof(_type))); + switch(type(o)){ + case OT_STRING: + _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger))); + _CHECK_IO(SafeWrite(v,write,up,_stringval(o),rsl(_string(o)->_len))); + break; + case OT_INTEGER: + _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break; + case OT_FLOAT: + _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break; + case OT_NULL: + break; + default: + v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o)); + return false; + } + return true; +} + +bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o) +{ + SQUnsignedInteger32 _type; + _CHECK_IO(SafeRead(v,read,up,&_type,sizeof(_type))); + SQObjectType t = (SQObjectType)_type; + switch(t){ + case OT_STRING:{ + SQInteger len; + _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger))); + _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(rsl(len)),rsl(len))); + o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len); + } + break; + case OT_INTEGER:{ + SQInteger i; + _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break; + } + case OT_FLOAT:{ + SQFloat f; + _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break; + } + case OT_NULL: + o.Null(); + break; + default: + v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t)); + return false; + } + return true; +} + +bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) +{ + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD)); + _CHECK_IO(WriteTag(v,write,up,sizeof(SQChar))); + _CHECK_IO(WriteTag(v,write,up,sizeof(SQInteger))); + _CHECK_IO(WriteTag(v,write,up,sizeof(SQFloat))); + _CHECK_IO(_function->Save(v,up,write)); + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL)); + return true; +} + +bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret) +{ + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD)); + _CHECK_IO(CheckTag(v,read,up,sizeof(SQChar))); + _CHECK_IO(CheckTag(v,read,up,sizeof(SQInteger))); + _CHECK_IO(CheckTag(v,read,up,sizeof(SQFloat))); + SQObjectPtr func; + _CHECK_IO(SQFunctionProto::Load(v,up,read,func)); + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL)); + ret = SQClosure::Create(_ss(v),_funcproto(func)); + return true; +} + +SQFunctionProto::SQFunctionProto(SQSharedState *ss) +{ + _stacksize=0; + _bgenerator=false; + INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); +} + +SQFunctionProto::~SQFunctionProto() +{ + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); +} + +bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) +{ + SQInteger i,nliterals = _nliterals,nparameters = _nparameters; + SQInteger noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos; + SQInteger nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions; + SQInteger ndefaultparams = _ndefaultparams; + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(WriteObject(v,up,write,_sourcename)); + _CHECK_IO(WriteObject(v,up,write,_name)); + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeWrite(v,write,up,&nliterals,sizeof(nliterals))); + _CHECK_IO(SafeWrite(v,write,up,&nparameters,sizeof(nparameters))); + _CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues))); + _CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos))); + _CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos))); + _CHECK_IO(SafeWrite(v,write,up,&ndefaultparams,sizeof(ndefaultparams))); + _CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions))); + _CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions))); + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); + for(i=0;iSave(v,up,write)); + } + _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize))); + _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator))); + _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams))); + return true; +} + +bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret) +{ + SQInteger i, nliterals,nparameters; + SQInteger noutervalues ,nlocalvarinfos ; + SQInteger nlineinfos,ninstructions ,nfunctions,ndefaultparams ; + SQObjectPtr sourcename, name; + SQObjectPtr o; + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(ReadObject(v, up, read, sourcename)); + _CHECK_IO(ReadObject(v, up, read, name)); + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeRead(v,read,up, &nliterals, sizeof(nliterals))); + _CHECK_IO(SafeRead(v,read,up, &nparameters, sizeof(nparameters))); + _CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues))); + _CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos))); + _CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos))); + _CHECK_IO(SafeRead(v,read,up, &ndefaultparams, sizeof(ndefaultparams))); + _CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions))); + _CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions))); + + + SQFunctionProto *f = SQFunctionProto::Create(_opt_ss(v),ninstructions,nliterals,nparameters, + nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams); + SQObjectPtr proto = f; //gets a ref in case of failure + f->_sourcename = sourcename; + f->_name = name; + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + + for(i = 0;i < nliterals; i++){ + _CHECK_IO(ReadObject(v, up, read, o)); + f->_literals[i] = o; + } + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + + for(i = 0; i < nparameters; i++){ + _CHECK_IO(ReadObject(v, up, read, o)); + f->_parameters[i] = o; + } + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + + for(i = 0; i < noutervalues; i++){ + SQUnsignedInteger type; + SQObjectPtr name; + _CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger))); + _CHECK_IO(ReadObject(v, up, read, o)); + _CHECK_IO(ReadObject(v, up, read, name)); + f->_outervalues[i] = SQOuterVar(name,o, (SQOuterType)type); + } + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + + for(i = 0; i < nlocalvarinfos; i++){ + SQLocalVarInfo lvi; + _CHECK_IO(ReadObject(v, up, read, lvi._name)); + _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(SQUnsignedInteger))); + _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(SQUnsignedInteger))); + _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(SQUnsignedInteger))); + f->_localvarinfos[i] = lvi; + } + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(SQLineInfo)*nlineinfos)); + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeRead(v,read,up, f->_defaultparams, sizeof(SQInteger)*ndefaultparams)); + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(SQInstruction)*ninstructions)); + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + for(i = 0; i < nfunctions; i++){ + _CHECK_IO(_funcproto(o)->Load(v, up, read, o)); + f->_functions[i] = o; + } + _CHECK_IO(SafeRead(v,read,up, &f->_stacksize, sizeof(f->_stacksize))); + _CHECK_IO(SafeRead(v,read,up, &f->_bgenerator, sizeof(f->_bgenerator))); + _CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams))); + + ret = f; + return true; +} + +#ifndef NO_GARBAGE_COLLECTOR + +#define START_MARK() if(!(_uiRef&MARK_FLAG)){ \ + _uiRef|=MARK_FLAG; + +#define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \ + AddToChain(chain, this); } + +void SQVM::Mark(SQCollectable **chain) +{ + START_MARK() + SQSharedState::MarkObject(_lasterror,chain); + SQSharedState::MarkObject(_errorhandler,chain); + SQSharedState::MarkObject(_debughook_closure,chain); + SQSharedState::MarkObject(_roottable, chain); + SQSharedState::MarkObject(temp_reg, chain); + for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain); + for(SQInteger k = 0; k < _callsstacksize; k++) SQSharedState::MarkObject(_callsstack[k]._closure, chain); + END_MARK() +} + +void SQArray::Mark(SQCollectable **chain) +{ + START_MARK() + SQInteger len = _values.size(); + for(SQInteger i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain); + END_MARK() +} +void SQTable::Mark(SQCollectable **chain) +{ + START_MARK() + if(_delegate) _delegate->Mark(chain); + SQInteger len = _numofnodes; + for(SQInteger i = 0; i < len; i++){ + SQSharedState::MarkObject(_nodes[i].key, chain); + SQSharedState::MarkObject(_nodes[i].val, chain); + } + END_MARK() +} + +void SQClass::Mark(SQCollectable **chain) +{ + START_MARK() + _members->Mark(chain); + if(_base) _base->Mark(chain); + SQSharedState::MarkObject(_attributes, chain); + for(SQUnsignedInteger i =0; i< _defaultvalues.size(); i++) { + SQSharedState::MarkObject(_defaultvalues[i].val, chain); + SQSharedState::MarkObject(_defaultvalues[i].attrs, chain); + } + for(SQUnsignedInteger j =0; j< _methods.size(); j++) { + SQSharedState::MarkObject(_methods[j].val, chain); + SQSharedState::MarkObject(_methods[j].attrs, chain); + } + for(SQUnsignedInteger k =0; k< MT_LAST; k++) { + SQSharedState::MarkObject(_metamethods[k], chain); + } + END_MARK() +} + +void SQInstance::Mark(SQCollectable **chain) +{ + START_MARK() + _class->Mark(chain); + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + for(SQUnsignedInteger i =0; i< nvalues; i++) { + SQSharedState::MarkObject(_values[i], chain); + } + END_MARK() +} + +void SQGenerator::Mark(SQCollectable **chain) +{ + START_MARK() + for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain); + SQSharedState::MarkObject(_closure, chain); + END_MARK() +} + +void SQFunctionProto::Mark(SQCollectable **chain) +{ + START_MARK() + for(SQInteger i = 0; i < _nliterals; i++) SQSharedState::MarkObject(_literals[i], chain); + for(SQInteger k = 0; k < _nfunctions; k++) SQSharedState::MarkObject(_functions[k], chain); + END_MARK() +} + +void SQClosure::Mark(SQCollectable **chain) +{ + START_MARK() + if(_base) _base->Mark(chain); + SQFunctionProto *fp = _function; + fp->Mark(chain); + for(SQInteger i = 0; i < fp->_noutervalues; i++) SQSharedState::MarkObject(_outervalues[i], chain); + for(SQInteger k = 0; k < fp->_ndefaultparams; k++) SQSharedState::MarkObject(_defaultparams[k], chain); + END_MARK() +} + +void SQNativeClosure::Mark(SQCollectable **chain) +{ + START_MARK() + for(SQUnsignedInteger i = 0; i < _noutervalues; i++) SQSharedState::MarkObject(_outervalues[i], chain); + END_MARK() +} + +void SQOuter::Mark(SQCollectable **chain) +{ + START_MARK() + /* If the valptr points to a closed value, that value is alive */ + if(_valptr == &_value) { + SQSharedState::MarkObject(_value, chain); + } + END_MARK() +} + +void SQUserData::Mark(SQCollectable **chain){ + START_MARK() + if(_delegate) _delegate->Mark(chain); + END_MARK() +} + +void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; } + +#endif + diff --git a/squirrel_3_0_1_stable/squirrel/sqobject.h b/squirrel_3_0_1_stable/squirrel/sqobject.h index a7d1e1ed3..2b85e24c3 100644 --- a/squirrel_3_0_1_stable/squirrel/sqobject.h +++ b/squirrel_3_0_1_stable/squirrel/sqobject.h @@ -1,354 +1,354 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQOBJECT_H_ -#define _SQOBJECT_H_ - -#include "squtils.h" - -#ifdef _SQ64 -#define UINT_MINUS_ONE (0xFFFFFFFFFFFFFFFF) -#else -#define UINT_MINUS_ONE (0xFFFFFFFF) -#endif - -#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R')) -#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T')) -#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L')) - -struct SQSharedState; - -enum SQMetaMethod{ - MT_ADD=0, - MT_SUB=1, - MT_MUL=2, - MT_DIV=3, - MT_UNM=4, - MT_MODULO=5, - MT_SET=6, - MT_GET=7, - MT_TYPEOF=8, - MT_NEXTI=9, - MT_CMP=10, - MT_CALL=11, - MT_CLONED=12, - MT_NEWSLOT=13, - MT_DELSLOT=14, - MT_TOSTRING=15, - MT_NEWMEMBER=16, - MT_INHERITED=17, - MT_LAST = 18 -}; - -#define MM_ADD _SC("_add") -#define MM_SUB _SC("_sub") -#define MM_MUL _SC("_mul") -#define MM_DIV _SC("_div") -#define MM_UNM _SC("_unm") -#define MM_MODULO _SC("_modulo") -#define MM_SET _SC("_set") -#define MM_GET _SC("_get") -#define MM_TYPEOF _SC("_typeof") -#define MM_NEXTI _SC("_nexti") -#define MM_CMP _SC("_cmp") -#define MM_CALL _SC("_call") -#define MM_CLONED _SC("_cloned") -#define MM_NEWSLOT _SC("_newslot") -#define MM_DELSLOT _SC("_delslot") -#define MM_TOSTRING _SC("_tostring") -#define MM_NEWMEMBER _SC("_newmember") -#define MM_INHERITED _SC("_inherited") - - -#define _CONSTRUCT_VECTOR(type,size,ptr) { \ - for(SQInteger n = 0; n < ((SQInteger)size); n++) { \ - new (&ptr[n]) type(); \ - } \ -} - -#define _DESTRUCT_VECTOR(type,size,ptr) { \ - for(SQInteger nl = 0; nl < ((SQInteger)size); nl++) { \ - ptr[nl].~type(); \ - } \ -} - -#define _COPY_VECTOR(dest,src,size) { \ - for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \ - dest[_n_] = src[_n_]; \ - } \ -} - -#define _NULL_SQOBJECT_VECTOR(vec,size) { \ - for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \ - vec[_n_].Null(); \ - } \ -} - -#define MINPOWER2 4 - -struct SQRefCounted -{ - SQUnsignedInteger _uiRef; - struct SQWeakRef *_weakref; - SQRefCounted() { _uiRef = 0; _weakref = NULL; } - virtual ~SQRefCounted(); - SQWeakRef *GetWeakRef(SQObjectType type); - virtual void Release()=0; - -}; - -struct SQWeakRef : SQRefCounted -{ - void Release(); - SQObject _obj; -}; - -#define _realval(o) (type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj) - -struct SQObjectPtr; - -#define __AddRef(type,unval) if(ISREFCOUNTED(type)) \ - { \ - unval.pRefCounted->_uiRef++; \ - } - -#define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)==0)) \ - { \ - unval.pRefCounted->Release(); \ - } - -#define __ObjRelease(obj) { \ - if((obj)) { \ - (obj)->_uiRef--; \ - if((obj)->_uiRef == 0) \ - (obj)->Release(); \ - (obj) = NULL; \ - } \ -} - -#define __ObjAddRef(obj) { \ - (obj)->_uiRef++; \ -} - -#define type(obj) ((obj)._type) -#define is_delegable(t) (type(t)&SQOBJECT_DELEGABLE) -#define raw_type(obj) _RAW_TYPE((obj)._type) - -#define _integer(obj) ((obj)._unVal.nInteger) -#define _float(obj) ((obj)._unVal.fFloat) -#define _string(obj) ((obj)._unVal.pString) -#define _table(obj) ((obj)._unVal.pTable) -#define _array(obj) ((obj)._unVal.pArray) -#define _closure(obj) ((obj)._unVal.pClosure) -#define _generator(obj) ((obj)._unVal.pGenerator) -#define _nativeclosure(obj) ((obj)._unVal.pNativeClosure) -#define _userdata(obj) ((obj)._unVal.pUserData) -#define _userpointer(obj) ((obj)._unVal.pUserPointer) -#define _thread(obj) ((obj)._unVal.pThread) -#define _funcproto(obj) ((obj)._unVal.pFunctionProto) -#define _class(obj) ((obj)._unVal.pClass) -#define _instance(obj) ((obj)._unVal.pInstance) -#define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable) -#define _weakref(obj) ((obj)._unVal.pWeakRef) -#define _outer(obj) ((obj)._unVal.pOuter) -#define _refcounted(obj) ((obj)._unVal.pRefCounted) -#define _rawval(obj) ((obj)._unVal.raw) - -#define _stringval(obj) (obj)._unVal.pString->_val -#define _userdataval(obj) ((SQUserPointer)sq_aligning((obj)._unVal.pUserData + 1)) - -#define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num)) -#define tointeger(num) ((type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num)) -///////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////// -#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64) -#define SQ_REFOBJECT_INIT() SQ_OBJECT_RAWINIT() -#else -#define SQ_REFOBJECT_INIT() -#endif - -#define _REF_TYPE_DECL(type,_class,sym) \ - SQObjectPtr(_class * x) \ - { \ - SQ_OBJECT_RAWINIT() \ - _type=type; \ - _unVal.sym = x; \ - assert(_unVal.pTable); \ - _unVal.pRefCounted->_uiRef++; \ - } \ - inline SQObjectPtr& operator=(_class *x) \ - { \ - SQObjectType tOldType; \ - SQObjectValue unOldVal; \ - tOldType=_type; \ - unOldVal=_unVal; \ - _type = type; \ - SQ_REFOBJECT_INIT() \ - _unVal.sym = x; \ - _unVal.pRefCounted->_uiRef++; \ - __Release(tOldType,unOldVal); \ - return *this; \ - } - -#define _SCALAR_TYPE_DECL(type,_class,sym) \ - SQObjectPtr(_class x) \ - { \ - SQ_OBJECT_RAWINIT() \ - _type=type; \ - _unVal.sym = x; \ - } \ - inline SQObjectPtr& operator=(_class x) \ - { \ - __Release(_type,_unVal); \ - _type = type; \ - SQ_OBJECT_RAWINIT() \ - _unVal.sym = x; \ - return *this; \ - } -struct SQObjectPtr : public SQObject -{ - SQObjectPtr() - { - SQ_OBJECT_RAWINIT() - _type=OT_NULL; - _unVal.pUserPointer=NULL; - } - SQObjectPtr(const SQObjectPtr &o) - { - //SQ_OBJECT_RAWINIT() - _type=o._type; - _unVal=o._unVal; - __AddRef(_type,_unVal); - } - SQObjectPtr(const SQObject &o) - { - //SQ_OBJECT_RAWINIT() - _type=o._type; - _unVal=o._unVal; - __AddRef(_type,_unVal); - } - _REF_TYPE_DECL(OT_TABLE,SQTable,pTable) - _REF_TYPE_DECL(OT_CLASS,SQClass,pClass) - _REF_TYPE_DECL(OT_INSTANCE,SQInstance,pInstance) - _REF_TYPE_DECL(OT_ARRAY,SQArray,pArray) - _REF_TYPE_DECL(OT_CLOSURE,SQClosure,pClosure) - _REF_TYPE_DECL(OT_NATIVECLOSURE,SQNativeClosure,pNativeClosure) - _REF_TYPE_DECL(OT_OUTER,SQOuter,pOuter) - _REF_TYPE_DECL(OT_GENERATOR,SQGenerator,pGenerator) - _REF_TYPE_DECL(OT_STRING,SQString,pString) - _REF_TYPE_DECL(OT_USERDATA,SQUserData,pUserData) - _REF_TYPE_DECL(OT_WEAKREF,SQWeakRef,pWeakRef) - _REF_TYPE_DECL(OT_THREAD,SQVM,pThread) - _REF_TYPE_DECL(OT_FUNCPROTO,SQFunctionProto,pFunctionProto) - - _SCALAR_TYPE_DECL(OT_INTEGER,SQInteger,nInteger) - _SCALAR_TYPE_DECL(OT_FLOAT,SQFloat,fFloat) - _SCALAR_TYPE_DECL(OT_USERPOINTER,SQUserPointer,pUserPointer) - - SQObjectPtr(bool bBool) - { - SQ_OBJECT_RAWINIT() - _type = OT_BOOL; - _unVal.nInteger = bBool?1:0; - } - inline SQObjectPtr& operator=(bool b) - { - __Release(_type,_unVal); - SQ_OBJECT_RAWINIT() - _type = OT_BOOL; - _unVal.nInteger = b?1:0; - return *this; - } - - ~SQObjectPtr() - { - __Release(_type,_unVal); - } - - inline SQObjectPtr& operator=(const SQObjectPtr& obj) - { - SQObjectType tOldType; - SQObjectValue unOldVal; - tOldType=_type; - unOldVal=_unVal; - _unVal = obj._unVal; - _type = obj._type; - __AddRef(_type,_unVal); - __Release(tOldType,unOldVal); - return *this; - } - inline SQObjectPtr& operator=(const SQObject& obj) - { - SQObjectType tOldType; - SQObjectValue unOldVal; - tOldType=_type; - unOldVal=_unVal; - _unVal = obj._unVal; - _type = obj._type; - __AddRef(_type,_unVal); - __Release(tOldType,unOldVal); - return *this; - } - inline void Null() - { - __Release(_type ,_unVal); - _type = OT_NULL; - _unVal.raw = NULL; - } - private: - SQObjectPtr(const SQChar *){} //safety -}; - - -inline void _Swap(SQObject &a,SQObject &b) -{ - SQObjectType tOldType = a._type; - SQObjectValue unOldVal = a._unVal; - a._type = b._type; - a._unVal = b._unVal; - b._type = tOldType; - b._unVal = unOldVal; -} - -///////////////////////////////////////////////////////////////////////////////////// -#ifndef NO_GARBAGE_COLLECTOR -#define MARK_FLAG 0x80000000 -struct SQCollectable : public SQRefCounted { - SQCollectable *_next; - SQCollectable *_prev; - SQSharedState *_sharedstate; - virtual SQObjectType GetType()=0; - virtual void Release()=0; - virtual void Mark(SQCollectable **chain)=0; - void UnMark(); - virtual void Finalize()=0; - static void AddToChain(SQCollectable **chain,SQCollectable *c); - static void RemoveFromChain(SQCollectable **chain,SQCollectable *c); -}; - - -#define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj) -#define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);} -#define CHAINABLE_OBJ SQCollectable -#define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;} -#else - -#define ADD_TO_CHAIN(chain,obj) ((void)0) -#define REMOVE_FROM_CHAIN(chain,obj) ((void)0) -#define CHAINABLE_OBJ SQRefCounted -#define INIT_CHAIN() ((void)0) -#endif - -struct SQDelegable : public CHAINABLE_OBJ { - bool SetDelegate(SQTable *m); - virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res); - SQTable *_delegate; -}; - -SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx); -typedef sqvector SQObjectPtrVec; -typedef sqvector SQIntVec; -const SQChar *GetTypeName(const SQObjectPtr &obj1); -const SQChar *IdType2Name(SQObjectType type); - - - -#endif //_SQOBJECT_H_ +/* see copyright notice in squirrel.h */ +#ifndef _SQOBJECT_H_ +#define _SQOBJECT_H_ + +#include "squtils.h" + +#ifdef _SQ64 +#define UINT_MINUS_ONE (0xFFFFFFFFFFFFFFFF) +#else +#define UINT_MINUS_ONE (0xFFFFFFFF) +#endif + +#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R')) +#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T')) +#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L')) + +struct SQSharedState; + +enum SQMetaMethod{ + MT_ADD=0, + MT_SUB=1, + MT_MUL=2, + MT_DIV=3, + MT_UNM=4, + MT_MODULO=5, + MT_SET=6, + MT_GET=7, + MT_TYPEOF=8, + MT_NEXTI=9, + MT_CMP=10, + MT_CALL=11, + MT_CLONED=12, + MT_NEWSLOT=13, + MT_DELSLOT=14, + MT_TOSTRING=15, + MT_NEWMEMBER=16, + MT_INHERITED=17, + MT_LAST = 18 +}; + +#define MM_ADD _SC("_add") +#define MM_SUB _SC("_sub") +#define MM_MUL _SC("_mul") +#define MM_DIV _SC("_div") +#define MM_UNM _SC("_unm") +#define MM_MODULO _SC("_modulo") +#define MM_SET _SC("_set") +#define MM_GET _SC("_get") +#define MM_TYPEOF _SC("_typeof") +#define MM_NEXTI _SC("_nexti") +#define MM_CMP _SC("_cmp") +#define MM_CALL _SC("_call") +#define MM_CLONED _SC("_cloned") +#define MM_NEWSLOT _SC("_newslot") +#define MM_DELSLOT _SC("_delslot") +#define MM_TOSTRING _SC("_tostring") +#define MM_NEWMEMBER _SC("_newmember") +#define MM_INHERITED _SC("_inherited") + + +#define _CONSTRUCT_VECTOR(type,size,ptr) { \ + for(SQInteger n = 0; n < ((SQInteger)size); n++) { \ + new (&ptr[n]) type(); \ + } \ +} + +#define _DESTRUCT_VECTOR(type,size,ptr) { \ + for(SQInteger nl = 0; nl < ((SQInteger)size); nl++) { \ + ptr[nl].~type(); \ + } \ +} + +#define _COPY_VECTOR(dest,src,size) { \ + for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \ + dest[_n_] = src[_n_]; \ + } \ +} + +#define _NULL_SQOBJECT_VECTOR(vec,size) { \ + for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \ + vec[_n_].Null(); \ + } \ +} + +#define MINPOWER2 4 + +struct SQRefCounted +{ + SQUnsignedInteger _uiRef; + struct SQWeakRef *_weakref; + SQRefCounted() { _uiRef = 0; _weakref = NULL; } + virtual ~SQRefCounted(); + SQWeakRef *GetWeakRef(SQObjectType type); + virtual void Release()=0; + +}; + +struct SQWeakRef : SQRefCounted +{ + void Release(); + SQObject _obj; +}; + +#define _realval(o) (type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj) + +struct SQObjectPtr; + +#define __AddRef(type,unval) if(ISREFCOUNTED(type)) \ + { \ + unval.pRefCounted->_uiRef++; \ + } + +#define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)==0)) \ + { \ + unval.pRefCounted->Release(); \ + } + +#define __ObjRelease(obj) { \ + if((obj)) { \ + (obj)->_uiRef--; \ + if((obj)->_uiRef == 0) \ + (obj)->Release(); \ + (obj) = NULL; \ + } \ +} + +#define __ObjAddRef(obj) { \ + (obj)->_uiRef++; \ +} + +#define type(obj) ((obj)._type) +#define is_delegable(t) (type(t)&SQOBJECT_DELEGABLE) +#define raw_type(obj) _RAW_TYPE((obj)._type) + +#define _integer(obj) ((obj)._unVal.nInteger) +#define _float(obj) ((obj)._unVal.fFloat) +#define _string(obj) ((obj)._unVal.pString) +#define _table(obj) ((obj)._unVal.pTable) +#define _array(obj) ((obj)._unVal.pArray) +#define _closure(obj) ((obj)._unVal.pClosure) +#define _generator(obj) ((obj)._unVal.pGenerator) +#define _nativeclosure(obj) ((obj)._unVal.pNativeClosure) +#define _userdata(obj) ((obj)._unVal.pUserData) +#define _userpointer(obj) ((obj)._unVal.pUserPointer) +#define _thread(obj) ((obj)._unVal.pThread) +#define _funcproto(obj) ((obj)._unVal.pFunctionProto) +#define _class(obj) ((obj)._unVal.pClass) +#define _instance(obj) ((obj)._unVal.pInstance) +#define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable) +#define _weakref(obj) ((obj)._unVal.pWeakRef) +#define _outer(obj) ((obj)._unVal.pOuter) +#define _refcounted(obj) ((obj)._unVal.pRefCounted) +#define _rawval(obj) ((obj)._unVal.raw) + +#define _stringval(obj) (obj)._unVal.pString->_val +#define _userdataval(obj) ((SQUserPointer)sq_aligning((obj)._unVal.pUserData + 1)) + +#define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num)) +#define tointeger(num) ((type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num)) +///////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////// +#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64) +#define SQ_REFOBJECT_INIT() SQ_OBJECT_RAWINIT() +#else +#define SQ_REFOBJECT_INIT() +#endif + +#define _REF_TYPE_DECL(type,_class,sym) \ + SQObjectPtr(_class * x) \ + { \ + SQ_OBJECT_RAWINIT() \ + _type=type; \ + _unVal.sym = x; \ + assert(_unVal.pTable); \ + _unVal.pRefCounted->_uiRef++; \ + } \ + inline SQObjectPtr& operator=(_class *x) \ + { \ + SQObjectType tOldType; \ + SQObjectValue unOldVal; \ + tOldType=_type; \ + unOldVal=_unVal; \ + _type = type; \ + SQ_REFOBJECT_INIT() \ + _unVal.sym = x; \ + _unVal.pRefCounted->_uiRef++; \ + __Release(tOldType,unOldVal); \ + return *this; \ + } + +#define _SCALAR_TYPE_DECL(type,_class,sym) \ + SQObjectPtr(_class x) \ + { \ + SQ_OBJECT_RAWINIT() \ + _type=type; \ + _unVal.sym = x; \ + } \ + inline SQObjectPtr& operator=(_class x) \ + { \ + __Release(_type,_unVal); \ + _type = type; \ + SQ_OBJECT_RAWINIT() \ + _unVal.sym = x; \ + return *this; \ + } +struct SQObjectPtr : public SQObject +{ + SQObjectPtr() + { + SQ_OBJECT_RAWINIT() + _type=OT_NULL; + _unVal.pUserPointer=NULL; + } + SQObjectPtr(const SQObjectPtr &o) + { + //SQ_OBJECT_RAWINIT() + _type=o._type; + _unVal=o._unVal; + __AddRef(_type,_unVal); + } + SQObjectPtr(const SQObject &o) + { + //SQ_OBJECT_RAWINIT() + _type=o._type; + _unVal=o._unVal; + __AddRef(_type,_unVal); + } + _REF_TYPE_DECL(OT_TABLE,SQTable,pTable) + _REF_TYPE_DECL(OT_CLASS,SQClass,pClass) + _REF_TYPE_DECL(OT_INSTANCE,SQInstance,pInstance) + _REF_TYPE_DECL(OT_ARRAY,SQArray,pArray) + _REF_TYPE_DECL(OT_CLOSURE,SQClosure,pClosure) + _REF_TYPE_DECL(OT_NATIVECLOSURE,SQNativeClosure,pNativeClosure) + _REF_TYPE_DECL(OT_OUTER,SQOuter,pOuter) + _REF_TYPE_DECL(OT_GENERATOR,SQGenerator,pGenerator) + _REF_TYPE_DECL(OT_STRING,SQString,pString) + _REF_TYPE_DECL(OT_USERDATA,SQUserData,pUserData) + _REF_TYPE_DECL(OT_WEAKREF,SQWeakRef,pWeakRef) + _REF_TYPE_DECL(OT_THREAD,SQVM,pThread) + _REF_TYPE_DECL(OT_FUNCPROTO,SQFunctionProto,pFunctionProto) + + _SCALAR_TYPE_DECL(OT_INTEGER,SQInteger,nInteger) + _SCALAR_TYPE_DECL(OT_FLOAT,SQFloat,fFloat) + _SCALAR_TYPE_DECL(OT_USERPOINTER,SQUserPointer,pUserPointer) + + SQObjectPtr(bool bBool) + { + SQ_OBJECT_RAWINIT() + _type = OT_BOOL; + _unVal.nInteger = bBool?1:0; + } + inline SQObjectPtr& operator=(bool b) + { + __Release(_type,_unVal); + SQ_OBJECT_RAWINIT() + _type = OT_BOOL; + _unVal.nInteger = b?1:0; + return *this; + } + + ~SQObjectPtr() + { + __Release(_type,_unVal); + } + + inline SQObjectPtr& operator=(const SQObjectPtr& obj) + { + SQObjectType tOldType; + SQObjectValue unOldVal; + tOldType=_type; + unOldVal=_unVal; + _unVal = obj._unVal; + _type = obj._type; + __AddRef(_type,_unVal); + __Release(tOldType,unOldVal); + return *this; + } + inline SQObjectPtr& operator=(const SQObject& obj) + { + SQObjectType tOldType; + SQObjectValue unOldVal; + tOldType=_type; + unOldVal=_unVal; + _unVal = obj._unVal; + _type = obj._type; + __AddRef(_type,_unVal); + __Release(tOldType,unOldVal); + return *this; + } + inline void Null() + { + __Release(_type ,_unVal); + _type = OT_NULL; + _unVal.raw = NULL; + } + private: + SQObjectPtr(const SQChar *){} //safety +}; + + +inline void _Swap(SQObject &a,SQObject &b) +{ + SQObjectType tOldType = a._type; + SQObjectValue unOldVal = a._unVal; + a._type = b._type; + a._unVal = b._unVal; + b._type = tOldType; + b._unVal = unOldVal; +} + +///////////////////////////////////////////////////////////////////////////////////// +#ifndef NO_GARBAGE_COLLECTOR +#define MARK_FLAG 0x80000000 +struct SQCollectable : public SQRefCounted { + SQCollectable *_next; + SQCollectable *_prev; + SQSharedState *_sharedstate; + virtual SQObjectType GetType()=0; + virtual void Release()=0; + virtual void Mark(SQCollectable **chain)=0; + void UnMark(); + virtual void Finalize()=0; + static void AddToChain(SQCollectable **chain,SQCollectable *c); + static void RemoveFromChain(SQCollectable **chain,SQCollectable *c); +}; + + +#define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj) +#define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);} +#define CHAINABLE_OBJ SQCollectable +#define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;} +#else + +#define ADD_TO_CHAIN(chain,obj) ((void)0) +#define REMOVE_FROM_CHAIN(chain,obj) ((void)0) +#define CHAINABLE_OBJ SQRefCounted +#define INIT_CHAIN() ((void)0) +#endif + +struct SQDelegable : public CHAINABLE_OBJ { + bool SetDelegate(SQTable *m); + virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res); + SQTable *_delegate; +}; + +SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx); +typedef sqvector SQObjectPtrVec; +typedef sqvector SQIntVec; +const SQChar *GetTypeName(const SQObjectPtr &obj1); +const SQChar *IdType2Name(SQObjectType type); + + + +#endif //_SQOBJECT_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqopcodes.h b/squirrel_3_0_1_stable/squirrel/sqopcodes.h index 4d179812f..f5f5697c9 100644 --- a/squirrel_3_0_1_stable/squirrel/sqopcodes.h +++ b/squirrel_3_0_1_stable/squirrel/sqopcodes.h @@ -1,132 +1,132 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQOPCODES_H_ -#define _SQOPCODES_H_ - -#define MAX_FUNC_STACKSIZE 0xFF -#define MAX_LITERALS ((SQInteger)0x7FFFFFFF) - -enum BitWiseOP { - BW_AND = 0, - BW_OR = 2, - BW_XOR = 3, - BW_SHIFTL = 4, - BW_SHIFTR = 5, - BW_USHIFTR = 6 -}; - -enum CmpOP { - CMP_G = 0, - CMP_GE = 2, - CMP_L = 3, - CMP_LE = 4, - CMP_3W = 5 -}; - -enum NewObjectType { - NOT_TABLE = 0, - NOT_ARRAY = 1, - NOT_CLASS = 2 -}; - -enum AppendArrayType { - AAT_STACK = 0, - AAT_LITERAL = 1, - AAT_INT = 2, - AAT_FLOAT = 3, - AAT_BOOL = 4 -}; - -enum SQOpcode -{ - _OP_LINE= 0x00, - _OP_LOAD= 0x01, - _OP_LOADINT= 0x02, - _OP_LOADFLOAT= 0x03, - _OP_DLOAD= 0x04, - _OP_TAILCALL= 0x05, - _OP_CALL= 0x06, - _OP_PREPCALL= 0x07, - _OP_PREPCALLK= 0x08, - _OP_GETK= 0x09, - _OP_MOVE= 0x0A, - _OP_NEWSLOT= 0x0B, - _OP_DELETE= 0x0C, - _OP_SET= 0x0D, - _OP_GET= 0x0E, - _OP_EQ= 0x0F, - _OP_NE= 0x10, - _OP_ADD= 0x11, - _OP_SUB= 0x12, - _OP_MUL= 0x13, - _OP_DIV= 0x14, - _OP_MOD= 0x15, - _OP_BITW= 0x16, - _OP_RETURN= 0x17, - _OP_LOADNULLS= 0x18, - _OP_LOADROOT= 0x19, - _OP_LOADBOOL= 0x1A, - _OP_DMOVE= 0x1B, - _OP_JMP= 0x1C, - //_OP_JNZ= 0x1D, - _OP_JCMP= 0x1D, - _OP_JZ= 0x1E, - _OP_SETOUTER= 0x1F, - _OP_GETOUTER= 0x20, - _OP_NEWOBJ= 0x21, - _OP_APPENDARRAY= 0x22, - _OP_COMPARITH= 0x23, - _OP_INC= 0x24, - _OP_INCL= 0x25, - _OP_PINC= 0x26, - _OP_PINCL= 0x27, - _OP_CMP= 0x28, - _OP_EXISTS= 0x29, - _OP_INSTANCEOF= 0x2A, - _OP_AND= 0x2B, - _OP_OR= 0x2C, - _OP_NEG= 0x2D, - _OP_NOT= 0x2E, - _OP_BWNOT= 0x2F, - _OP_CLOSURE= 0x30, - _OP_YIELD= 0x31, - _OP_RESUME= 0x32, - _OP_FOREACH= 0x33, - _OP_POSTFOREACH= 0x34, - _OP_CLONE= 0x35, - _OP_TYPEOF= 0x36, - _OP_PUSHTRAP= 0x37, - _OP_POPTRAP= 0x38, - _OP_THROW= 0x39, - _OP_NEWSLOTA= 0x3A, - _OP_GETBASE= 0x3B, - _OP_CLOSE= 0x3C, -}; - -struct SQInstructionDesc { - const SQChar *name; -}; - -struct SQInstruction -{ - SQInstruction(){}; - SQInstruction(SQOpcode _op,SQInteger a0=0,SQInteger a1=0,SQInteger a2=0,SQInteger a3=0) - { op = _op; - _arg0 = (unsigned char)a0;_arg1 = (SQInt32)a1; - _arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3; - } - - - SQInt32 _arg1; - unsigned char op; - unsigned char _arg0; - unsigned char _arg2; - unsigned char _arg3; -}; - -#include "squtils.h" -typedef sqvector SQInstructionVec; - -#define NEW_SLOT_ATTRIBUTES_FLAG 0x01 -#define NEW_SLOT_STATIC_FLAG 0x02 - -#endif // _SQOPCODES_H_ +/* see copyright notice in squirrel.h */ +#ifndef _SQOPCODES_H_ +#define _SQOPCODES_H_ + +#define MAX_FUNC_STACKSIZE 0xFF +#define MAX_LITERALS ((SQInteger)0x7FFFFFFF) + +enum BitWiseOP { + BW_AND = 0, + BW_OR = 2, + BW_XOR = 3, + BW_SHIFTL = 4, + BW_SHIFTR = 5, + BW_USHIFTR = 6 +}; + +enum CmpOP { + CMP_G = 0, + CMP_GE = 2, + CMP_L = 3, + CMP_LE = 4, + CMP_3W = 5 +}; + +enum NewObjectType { + NOT_TABLE = 0, + NOT_ARRAY = 1, + NOT_CLASS = 2 +}; + +enum AppendArrayType { + AAT_STACK = 0, + AAT_LITERAL = 1, + AAT_INT = 2, + AAT_FLOAT = 3, + AAT_BOOL = 4 +}; + +enum SQOpcode +{ + _OP_LINE= 0x00, + _OP_LOAD= 0x01, + _OP_LOADINT= 0x02, + _OP_LOADFLOAT= 0x03, + _OP_DLOAD= 0x04, + _OP_TAILCALL= 0x05, + _OP_CALL= 0x06, + _OP_PREPCALL= 0x07, + _OP_PREPCALLK= 0x08, + _OP_GETK= 0x09, + _OP_MOVE= 0x0A, + _OP_NEWSLOT= 0x0B, + _OP_DELETE= 0x0C, + _OP_SET= 0x0D, + _OP_GET= 0x0E, + _OP_EQ= 0x0F, + _OP_NE= 0x10, + _OP_ADD= 0x11, + _OP_SUB= 0x12, + _OP_MUL= 0x13, + _OP_DIV= 0x14, + _OP_MOD= 0x15, + _OP_BITW= 0x16, + _OP_RETURN= 0x17, + _OP_LOADNULLS= 0x18, + _OP_LOADROOT= 0x19, + _OP_LOADBOOL= 0x1A, + _OP_DMOVE= 0x1B, + _OP_JMP= 0x1C, + //_OP_JNZ= 0x1D, + _OP_JCMP= 0x1D, + _OP_JZ= 0x1E, + _OP_SETOUTER= 0x1F, + _OP_GETOUTER= 0x20, + _OP_NEWOBJ= 0x21, + _OP_APPENDARRAY= 0x22, + _OP_COMPARITH= 0x23, + _OP_INC= 0x24, + _OP_INCL= 0x25, + _OP_PINC= 0x26, + _OP_PINCL= 0x27, + _OP_CMP= 0x28, + _OP_EXISTS= 0x29, + _OP_INSTANCEOF= 0x2A, + _OP_AND= 0x2B, + _OP_OR= 0x2C, + _OP_NEG= 0x2D, + _OP_NOT= 0x2E, + _OP_BWNOT= 0x2F, + _OP_CLOSURE= 0x30, + _OP_YIELD= 0x31, + _OP_RESUME= 0x32, + _OP_FOREACH= 0x33, + _OP_POSTFOREACH= 0x34, + _OP_CLONE= 0x35, + _OP_TYPEOF= 0x36, + _OP_PUSHTRAP= 0x37, + _OP_POPTRAP= 0x38, + _OP_THROW= 0x39, + _OP_NEWSLOTA= 0x3A, + _OP_GETBASE= 0x3B, + _OP_CLOSE= 0x3C, +}; + +struct SQInstructionDesc { + const SQChar *name; +}; + +struct SQInstruction +{ + SQInstruction(){}; + SQInstruction(SQOpcode _op,SQInteger a0=0,SQInteger a1=0,SQInteger a2=0,SQInteger a3=0) + { op = _op; + _arg0 = (unsigned char)a0;_arg1 = (SQInt32)a1; + _arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3; + } + + + SQInt32 _arg1; + unsigned char op; + unsigned char _arg0; + unsigned char _arg2; + unsigned char _arg3; +}; + +#include "squtils.h" +typedef sqvector SQInstructionVec; + +#define NEW_SLOT_ATTRIBUTES_FLAG 0x01 +#define NEW_SLOT_STATIC_FLAG 0x02 + +#endif // _SQOPCODES_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqpcheader.h b/squirrel_3_0_1_stable/squirrel/sqpcheader.h index f0e5cf2df..a3fb037e4 100644 --- a/squirrel_3_0_1_stable/squirrel/sqpcheader.h +++ b/squirrel_3_0_1_stable/squirrel/sqpcheader.h @@ -1,19 +1,19 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQPCHEADER_H_ -#define _SQPCHEADER_H_ - -#if defined(_MSC_VER) && defined(_DEBUG) -#include -#endif - -#include -#include -#include -#include -#include -//squirrel stuff -#include -#include "sqobject.h" -#include "sqstate.h" - -#endif //_SQPCHEADER_H_ +/* see copyright notice in squirrel.h */ +#ifndef _SQPCHEADER_H_ +#define _SQPCHEADER_H_ + +#if defined(_MSC_VER) && defined(_DEBUG) +#include +#endif + +#include +#include +#include +#include +#include +//squirrel stuff +#include +#include "sqobject.h" +#include "sqstate.h" + +#endif //_SQPCHEADER_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqstate.cpp b/squirrel_3_0_1_stable/squirrel/sqstate.cpp index 0bee40661..8e77900f3 100644 --- a/squirrel_3_0_1_stable/squirrel/sqstate.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqstate.cpp @@ -1,648 +1,648 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#include "sqopcodes.h" -#include "sqvm.h" -#include "sqfuncproto.h" -#include "sqclosure.h" -#include "sqstring.h" -#include "sqtable.h" -#include "sqarray.h" -#include "squserdata.h" -#include "sqclass.h" - -//SQObjectPtr _null_; -//SQObjectPtr _true_(true); -//SQObjectPtr _false_(false); -//SQObjectPtr _one_((SQInteger)1); -//SQObjectPtr _minusone_((SQInteger)-1); - -SQSharedState::SQSharedState() -{ - _compilererrorhandler = NULL; - _printfunc = NULL; - _errorfunc = NULL; - _debuginfo = false; - _notifyallexceptions = false; -} - -#define newsysstring(s) { \ - _systemstrings->push_back(SQString::Create(this,s)); \ - } - -#define newmetamethod(s) { \ - _metamethods->push_back(SQString::Create(this,s)); \ - _table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \ - } - -bool CompileTypemask(SQIntVec &res,const SQChar *typemask) -{ - SQInteger i = 0; - - SQInteger mask = 0; - while(typemask[i] != 0) { - - switch(typemask[i]){ - case 'o': mask |= _RT_NULL; break; - case 'i': mask |= _RT_INTEGER; break; - case 'f': mask |= _RT_FLOAT; break; - case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break; - case 's': mask |= _RT_STRING; break; - case 't': mask |= _RT_TABLE; break; - case 'a': mask |= _RT_ARRAY; break; - case 'u': mask |= _RT_USERDATA; break; - case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break; - case 'b': mask |= _RT_BOOL; break; - case 'g': mask |= _RT_GENERATOR; break; - case 'p': mask |= _RT_USERPOINTER; break; - case 'v': mask |= _RT_THREAD; break; - case 'x': mask |= _RT_INSTANCE; break; - case 'y': mask |= _RT_CLASS; break; - case 'r': mask |= _RT_WEAKREF; break; - case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue; - case ' ': i++; continue; //ignores spaces - default: - return false; - } - i++; - if(typemask[i] == '|') { - i++; - if(typemask[i] == 0) - return false; - continue; - } - res.push_back(mask); - mask = 0; - - } - return true; -} - -SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz) -{ - SQInteger i=0; - SQTable *t=SQTable::Create(ss,0); - while(funcz[i].name!=0){ - SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f,0); - nc->_nparamscheck = funcz[i].nparamscheck; - nc->_name = SQString::Create(ss,funcz[i].name); - if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask)) - return NULL; - t->NewSlot(SQString::Create(ss,funcz[i].name),nc); - i++; - } - return t; -} - -void SQSharedState::Init() -{ - _scratchpad=NULL; - _scratchpadsize=0; -#ifndef NO_GARBAGE_COLLECTOR - _gc_chain=NULL; -#endif - _stringtable = (SQStringTable*)SQ_MALLOC(sizeof(SQStringTable)); - new (_stringtable) SQStringTable(this); - sq_new(_metamethods,SQObjectPtrVec); - sq_new(_systemstrings,SQObjectPtrVec); - sq_new(_types,SQObjectPtrVec); - _metamethodsmap = SQTable::Create(this,MT_LAST-1); - //adding type strings to avoid memory trashing - //types names - newsysstring(_SC("null")); - newsysstring(_SC("table")); - newsysstring(_SC("array")); - newsysstring(_SC("closure")); - newsysstring(_SC("string")); - newsysstring(_SC("userdata")); - newsysstring(_SC("integer")); - newsysstring(_SC("float")); - newsysstring(_SC("userpointer")); - newsysstring(_SC("function")); - newsysstring(_SC("generator")); - newsysstring(_SC("thread")); - newsysstring(_SC("class")); - newsysstring(_SC("instance")); - newsysstring(_SC("bool")); - //meta methods - newmetamethod(MM_ADD); - newmetamethod(MM_SUB); - newmetamethod(MM_MUL); - newmetamethod(MM_DIV); - newmetamethod(MM_UNM); - newmetamethod(MM_MODULO); - newmetamethod(MM_SET); - newmetamethod(MM_GET); - newmetamethod(MM_TYPEOF); - newmetamethod(MM_NEXTI); - newmetamethod(MM_CMP); - newmetamethod(MM_CALL); - newmetamethod(MM_CLONED); - newmetamethod(MM_NEWSLOT); - newmetamethod(MM_DELSLOT); - newmetamethod(MM_TOSTRING); - newmetamethod(MM_NEWMEMBER); - newmetamethod(MM_INHERITED); - - _constructoridx = SQString::Create(this,_SC("constructor")); - _registry = SQTable::Create(this,0); - _consts = SQTable::Create(this,0); - _table_default_delegate = CreateDefaultDelegate(this,_table_default_delegate_funcz); - _array_default_delegate = CreateDefaultDelegate(this,_array_default_delegate_funcz); - _string_default_delegate = CreateDefaultDelegate(this,_string_default_delegate_funcz); - _number_default_delegate = CreateDefaultDelegate(this,_number_default_delegate_funcz); - _closure_default_delegate = CreateDefaultDelegate(this,_closure_default_delegate_funcz); - _generator_default_delegate = CreateDefaultDelegate(this,_generator_default_delegate_funcz); - _thread_default_delegate = CreateDefaultDelegate(this,_thread_default_delegate_funcz); - _class_default_delegate = CreateDefaultDelegate(this,_class_default_delegate_funcz); - _instance_default_delegate = CreateDefaultDelegate(this,_instance_default_delegate_funcz); - _weakref_default_delegate = CreateDefaultDelegate(this,_weakref_default_delegate_funcz); - -} - -SQSharedState::~SQSharedState() -{ - _constructoridx.Null(); - _table(_registry)->Finalize(); - _table(_consts)->Finalize(); - _table(_metamethodsmap)->Finalize(); - _registry.Null(); - _consts.Null(); - _metamethodsmap.Null(); - while(!_systemstrings->empty()) { - _systemstrings->back().Null(); - _systemstrings->pop_back(); - } - _thread(_root_vm)->Finalize(); - _root_vm.Null(); - _table_default_delegate.Null(); - _array_default_delegate.Null(); - _string_default_delegate.Null(); - _number_default_delegate.Null(); - _closure_default_delegate.Null(); - _generator_default_delegate.Null(); - _thread_default_delegate.Null(); - _class_default_delegate.Null(); - _instance_default_delegate.Null(); - _weakref_default_delegate.Null(); - _refs_table.Finalize(); -#ifndef NO_GARBAGE_COLLECTOR - SQCollectable *t = _gc_chain; - SQCollectable *nx = NULL; - while(t) { - t->_uiRef++; - t->Finalize(); - nx = t->_next; - if(--t->_uiRef == 0) - t->Release(); - t=nx; - } - assert(_gc_chain==NULL); //just to proove a theory - while(_gc_chain){ - _gc_chain->_uiRef++; - _gc_chain->Release(); - } -#endif - - sq_delete(_types,SQObjectPtrVec); - sq_delete(_systemstrings,SQObjectPtrVec); - sq_delete(_metamethods,SQObjectPtrVec); - sq_delete(_stringtable,SQStringTable); - if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize); -} - - -SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name) -{ - if(type(name) != OT_STRING) - return -1; - SQObjectPtr ret; - if(_table(_metamethodsmap)->Get(name,ret)) { - return _integer(ret); - } - return -1; -} - -#ifndef NO_GARBAGE_COLLECTOR - -void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain) -{ - switch(type(o)){ - case OT_TABLE:_table(o)->Mark(chain);break; - case OT_ARRAY:_array(o)->Mark(chain);break; - case OT_USERDATA:_userdata(o)->Mark(chain);break; - case OT_CLOSURE:_closure(o)->Mark(chain);break; - case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break; - case OT_GENERATOR:_generator(o)->Mark(chain);break; - case OT_THREAD:_thread(o)->Mark(chain);break; - case OT_CLASS:_class(o)->Mark(chain);break; - case OT_INSTANCE:_instance(o)->Mark(chain);break; - case OT_OUTER:_outer(o)->Mark(chain);break; - case OT_FUNCPROTO:_funcproto(o)->Mark(chain);break; - default: break; //shutup compiler - } -} - - -void SQSharedState::RunMark(SQVM *vm,SQCollectable **tchain) -{ - SQVM *vms = _thread(_root_vm); - - vms->Mark(tchain); - - _refs_table.Mark(tchain); - MarkObject(_registry,tchain); - MarkObject(_consts,tchain); - MarkObject(_metamethodsmap,tchain); - MarkObject(_table_default_delegate,tchain); - MarkObject(_array_default_delegate,tchain); - MarkObject(_string_default_delegate,tchain); - MarkObject(_number_default_delegate,tchain); - MarkObject(_generator_default_delegate,tchain); - MarkObject(_thread_default_delegate,tchain); - MarkObject(_closure_default_delegate,tchain); - MarkObject(_class_default_delegate,tchain); - MarkObject(_instance_default_delegate,tchain); - MarkObject(_weakref_default_delegate,tchain); - -} - -SQInteger SQSharedState::ResurrectUnreachable(SQVM *vm) -{ - SQInteger n=0; - SQCollectable *tchain=NULL; - - RunMark(vm,&tchain); - - SQCollectable *resurrected = _gc_chain; - SQCollectable *t = resurrected; - //SQCollectable *nx = NULL; - - _gc_chain = tchain; - - SQArray *ret = NULL; - if(resurrected) { - ret = SQArray::Create(this,0); - SQCollectable *rlast = NULL; - while(t) { - rlast = t; - SQObjectType type = t->GetType(); - if(type != OT_FUNCPROTO && type != OT_OUTER) { - SQObject sqo; - sqo._type = type; - sqo._unVal.pRefCounted = t; - ret->Append(sqo); - } - t = t->_next; - n++; - } - - assert(rlast->_next == NULL); - rlast->_next = _gc_chain; - if(_gc_chain) - { - _gc_chain->_prev = rlast; - } - _gc_chain = resurrected; - } - - t = _gc_chain; - while(t) { - t->UnMark(); - t = t->_next; - } - - if(ret) { - SQObjectPtr temp = ret; - vm->Push(temp); - } - else { - vm->PushNull(); - } - return n; -} - -SQInteger SQSharedState::CollectGarbage(SQVM *vm) -{ - SQInteger n=0; - SQCollectable *tchain=NULL; - - RunMark(vm,&tchain); - - SQCollectable *t = _gc_chain; - SQCollectable *nx = NULL; - while(t) { - t->_uiRef++; - t->Finalize(); - nx = t->_next; - if(--t->_uiRef == 0) - t->Release(); - t = nx; - n++; - } - - t = tchain; - while(t) { - t->UnMark(); - t = t->_next; - } - _gc_chain = tchain; - - return n; -} -#endif - -#ifndef NO_GARBAGE_COLLECTOR -void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c) -{ - c->_prev = NULL; - c->_next = *chain; - if(*chain) (*chain)->_prev = c; - *chain = c; -} - -void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c) -{ - if(c->_prev) c->_prev->_next = c->_next; - else *chain = c->_next; - if(c->_next) - c->_next->_prev = c->_prev; - c->_next = NULL; - c->_prev = NULL; -} -#endif - -SQChar* SQSharedState::GetScratchPad(SQInteger size) -{ - SQInteger newsize; - if(size>0) { - if(_scratchpadsize < size) { - newsize = size + (size>>1); - _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); - _scratchpadsize = newsize; - - }else if(_scratchpadsize >= (size<<5)) { - newsize = _scratchpadsize >> 1; - _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); - _scratchpadsize = newsize; - } - } - return _scratchpad; -} - -RefTable::RefTable() -{ - AllocNodes(4); -} - -void RefTable::Finalize() -{ - RefNode *nodes = _nodes; - for(SQUnsignedInteger n = 0; n < _numofslots; n++) { - nodes->obj.Null(); - nodes++; - } -} - -RefTable::~RefTable() -{ - SQ_FREE(_buckets,(_numofslots * sizeof(RefNode *)) + (_numofslots * sizeof(RefNode))); -} - -#ifndef NO_GARBAGE_COLLECTOR -void RefTable::Mark(SQCollectable **chain) -{ - RefNode *nodes = (RefNode *)_nodes; - for(SQUnsignedInteger n = 0; n < _numofslots; n++) { - if(type(nodes->obj) != OT_NULL) { - SQSharedState::MarkObject(nodes->obj,chain); - } - nodes++; - } -} -#endif - -void RefTable::AddRef(SQObject &obj) -{ - SQHash mainpos; - RefNode *prev; - RefNode *ref = Get(obj,mainpos,&prev,true); - ref->refs++; -} - -SQUnsignedInteger RefTable::GetRefCount(SQObject &obj) -{ - SQHash mainpos; - RefNode *prev; - RefNode *ref = Get(obj,mainpos,&prev,true); - return ref->refs; -} - - -SQBool RefTable::Release(SQObject &obj) -{ - SQHash mainpos; - RefNode *prev; - RefNode *ref = Get(obj,mainpos,&prev,false); - if(ref) { - if(--ref->refs == 0) { - SQObjectPtr o = ref->obj; - if(prev) { - prev->next = ref->next; - } - else { - _buckets[mainpos] = ref->next; - } - ref->next = _freelist; - _freelist = ref; - _slotused--; - ref->obj.Null(); - //<>test for shrink? - return SQTrue; - } - } - else { - assert(0); - } - return SQFalse; -} - -void RefTable::Resize(SQUnsignedInteger size) -{ - RefNode **oldbucks = _buckets; - RefNode *t = _nodes; - SQUnsignedInteger oldnumofslots = _numofslots; - AllocNodes(size); - //rehash - SQUnsignedInteger nfound = 0; - for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) { - if(type(t->obj) != OT_NULL) { - //add back; - assert(t->refs != 0); - RefNode *nn = Add(::HashObj(t->obj)&(_numofslots-1),t->obj); - nn->refs = t->refs; - t->obj.Null(); - nfound++; - } - t++; - } - assert(nfound == oldnumofslots); - SQ_FREE(oldbucks,(oldnumofslots * sizeof(RefNode *)) + (oldnumofslots * sizeof(RefNode))); -} - -RefTable::RefNode *RefTable::Add(SQHash mainpos,SQObject &obj) -{ - RefNode *t = _buckets[mainpos]; - RefNode *newnode = _freelist; - newnode->obj = obj; - _buckets[mainpos] = newnode; - _freelist = _freelist->next; - newnode->next = t; - assert(newnode->refs == 0); - _slotused++; - return newnode; -} - -RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add) -{ - RefNode *ref; - mainpos = ::HashObj(obj)&(_numofslots-1); - *prev = NULL; - for (ref = _buckets[mainpos]; ref; ) { - if(_rawval(ref->obj) == _rawval(obj) && type(ref->obj) == type(obj)) - break; - *prev = ref; - ref = ref->next; - } - if(ref == NULL && add) { - if(_numofslots == _slotused) { - assert(_freelist == 0); - Resize(_numofslots*2); - mainpos = ::HashObj(obj)&(_numofslots-1); - } - ref = Add(mainpos,obj); - } - return ref; -} - -void RefTable::AllocNodes(SQUnsignedInteger size) -{ - RefNode **bucks; - RefNode *nodes; - bucks = (RefNode **)SQ_MALLOC((size * sizeof(RefNode *)) + (size * sizeof(RefNode))); - nodes = (RefNode *)&bucks[size]; - RefNode *temp = nodes; - SQUnsignedInteger n; - for(n = 0; n < size - 1; n++) { - bucks[n] = NULL; - temp->refs = 0; - new (&temp->obj) SQObjectPtr; - temp->next = temp+1; - temp++; - } - bucks[n] = NULL; - temp->refs = 0; - new (&temp->obj) SQObjectPtr; - temp->next = NULL; - _freelist = nodes; - _nodes = nodes; - _buckets = bucks; - _slotused = 0; - _numofslots = size; -} -////////////////////////////////////////////////////////////////////////// -//SQStringTable -/* -* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.) -* http://www.lua.org/copyright.html#4 -* http://www.lua.org/source/4.0.1/src_lstring.c.html -*/ - -SQStringTable::SQStringTable(SQSharedState *ss) -{ - _sharedstate = ss; - AllocNodes(4); - _slotused = 0; -} - -SQStringTable::~SQStringTable() -{ - SQ_FREE(_strings,sizeof(SQString*)*_numofslots); - _strings = NULL; -} - -void SQStringTable::AllocNodes(SQInteger size) -{ - _numofslots = size; - _strings = (SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots); - memset(_strings,0,sizeof(SQString*)*_numofslots); -} - -SQString *SQStringTable::Add(const SQChar *news,SQInteger len) -{ - if(len<0) - len = (SQInteger)scstrlen(news); - SQHash h = ::_hashstr(news,len)&(_numofslots-1); - SQString *s; - for (s = _strings[h]; s; s = s->_next){ - if(s->_len == len && (!memcmp(news,s->_val,rsl(len)))) - return s; //found - } - - SQString *t=(SQString *)SQ_MALLOC(rsl(len)+sizeof(SQString)); - new (t) SQString; - t->_sharedstate = _sharedstate; - memcpy(t->_val,news,rsl(len)); - t->_val[len] = _SC('\0'); - t->_len = len; - t->_hash = ::_hashstr(news,len); - t->_next = _strings[h]; - _strings[h] = t; - _slotused++; - if (_slotused > _numofslots) /* too crowded? */ - Resize(_numofslots*2); - return t; -} - -void SQStringTable::Resize(SQInteger size) -{ - SQInteger oldsize=_numofslots; - SQString **oldtable=_strings; - AllocNodes(size); - for (SQInteger i=0; i_next; - SQHash h = p->_hash&(_numofslots-1); - p->_next = _strings[h]; - _strings[h] = p; - p = next; - } - } - SQ_FREE(oldtable,oldsize*sizeof(SQString*)); -} - -void SQStringTable::Remove(SQString *bs) -{ - SQString *s; - SQString *prev=NULL; - SQHash h = bs->_hash&(_numofslots - 1); - - for (s = _strings[h]; s; ){ - if(s == bs){ - if(prev) - prev->_next = s->_next; - else - _strings[h] = s->_next; - _slotused--; - SQInteger slen = s->_len; - s->~SQString(); - SQ_FREE(s,sizeof(SQString) + rsl(slen)); - return; - } - prev = s; - s = s->_next; - } - assert(0);//if this fail something is wrong -} +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqopcodes.h" +#include "sqvm.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "sqstring.h" +#include "sqtable.h" +#include "sqarray.h" +#include "squserdata.h" +#include "sqclass.h" + +//SQObjectPtr _null_; +//SQObjectPtr _true_(true); +//SQObjectPtr _false_(false); +//SQObjectPtr _one_((SQInteger)1); +//SQObjectPtr _minusone_((SQInteger)-1); + +SQSharedState::SQSharedState() +{ + _compilererrorhandler = NULL; + _printfunc = NULL; + _errorfunc = NULL; + _debuginfo = false; + _notifyallexceptions = false; +} + +#define newsysstring(s) { \ + _systemstrings->push_back(SQString::Create(this,s)); \ + } + +#define newmetamethod(s) { \ + _metamethods->push_back(SQString::Create(this,s)); \ + _table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \ + } + +bool CompileTypemask(SQIntVec &res,const SQChar *typemask) +{ + SQInteger i = 0; + + SQInteger mask = 0; + while(typemask[i] != 0) { + + switch(typemask[i]){ + case 'o': mask |= _RT_NULL; break; + case 'i': mask |= _RT_INTEGER; break; + case 'f': mask |= _RT_FLOAT; break; + case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break; + case 's': mask |= _RT_STRING; break; + case 't': mask |= _RT_TABLE; break; + case 'a': mask |= _RT_ARRAY; break; + case 'u': mask |= _RT_USERDATA; break; + case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break; + case 'b': mask |= _RT_BOOL; break; + case 'g': mask |= _RT_GENERATOR; break; + case 'p': mask |= _RT_USERPOINTER; break; + case 'v': mask |= _RT_THREAD; break; + case 'x': mask |= _RT_INSTANCE; break; + case 'y': mask |= _RT_CLASS; break; + case 'r': mask |= _RT_WEAKREF; break; + case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue; + case ' ': i++; continue; //ignores spaces + default: + return false; + } + i++; + if(typemask[i] == '|') { + i++; + if(typemask[i] == 0) + return false; + continue; + } + res.push_back(mask); + mask = 0; + + } + return true; +} + +SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz) +{ + SQInteger i=0; + SQTable *t=SQTable::Create(ss,0); + while(funcz[i].name!=0){ + SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f,0); + nc->_nparamscheck = funcz[i].nparamscheck; + nc->_name = SQString::Create(ss,funcz[i].name); + if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask)) + return NULL; + t->NewSlot(SQString::Create(ss,funcz[i].name),nc); + i++; + } + return t; +} + +void SQSharedState::Init() +{ + _scratchpad=NULL; + _scratchpadsize=0; +#ifndef NO_GARBAGE_COLLECTOR + _gc_chain=NULL; +#endif + _stringtable = (SQStringTable*)SQ_MALLOC(sizeof(SQStringTable)); + new (_stringtable) SQStringTable(this); + sq_new(_metamethods,SQObjectPtrVec); + sq_new(_systemstrings,SQObjectPtrVec); + sq_new(_types,SQObjectPtrVec); + _metamethodsmap = SQTable::Create(this,MT_LAST-1); + //adding type strings to avoid memory trashing + //types names + newsysstring(_SC("null")); + newsysstring(_SC("table")); + newsysstring(_SC("array")); + newsysstring(_SC("closure")); + newsysstring(_SC("string")); + newsysstring(_SC("userdata")); + newsysstring(_SC("integer")); + newsysstring(_SC("float")); + newsysstring(_SC("userpointer")); + newsysstring(_SC("function")); + newsysstring(_SC("generator")); + newsysstring(_SC("thread")); + newsysstring(_SC("class")); + newsysstring(_SC("instance")); + newsysstring(_SC("bool")); + //meta methods + newmetamethod(MM_ADD); + newmetamethod(MM_SUB); + newmetamethod(MM_MUL); + newmetamethod(MM_DIV); + newmetamethod(MM_UNM); + newmetamethod(MM_MODULO); + newmetamethod(MM_SET); + newmetamethod(MM_GET); + newmetamethod(MM_TYPEOF); + newmetamethod(MM_NEXTI); + newmetamethod(MM_CMP); + newmetamethod(MM_CALL); + newmetamethod(MM_CLONED); + newmetamethod(MM_NEWSLOT); + newmetamethod(MM_DELSLOT); + newmetamethod(MM_TOSTRING); + newmetamethod(MM_NEWMEMBER); + newmetamethod(MM_INHERITED); + + _constructoridx = SQString::Create(this,_SC("constructor")); + _registry = SQTable::Create(this,0); + _consts = SQTable::Create(this,0); + _table_default_delegate = CreateDefaultDelegate(this,_table_default_delegate_funcz); + _array_default_delegate = CreateDefaultDelegate(this,_array_default_delegate_funcz); + _string_default_delegate = CreateDefaultDelegate(this,_string_default_delegate_funcz); + _number_default_delegate = CreateDefaultDelegate(this,_number_default_delegate_funcz); + _closure_default_delegate = CreateDefaultDelegate(this,_closure_default_delegate_funcz); + _generator_default_delegate = CreateDefaultDelegate(this,_generator_default_delegate_funcz); + _thread_default_delegate = CreateDefaultDelegate(this,_thread_default_delegate_funcz); + _class_default_delegate = CreateDefaultDelegate(this,_class_default_delegate_funcz); + _instance_default_delegate = CreateDefaultDelegate(this,_instance_default_delegate_funcz); + _weakref_default_delegate = CreateDefaultDelegate(this,_weakref_default_delegate_funcz); + +} + +SQSharedState::~SQSharedState() +{ + _constructoridx.Null(); + _table(_registry)->Finalize(); + _table(_consts)->Finalize(); + _table(_metamethodsmap)->Finalize(); + _registry.Null(); + _consts.Null(); + _metamethodsmap.Null(); + while(!_systemstrings->empty()) { + _systemstrings->back().Null(); + _systemstrings->pop_back(); + } + _thread(_root_vm)->Finalize(); + _root_vm.Null(); + _table_default_delegate.Null(); + _array_default_delegate.Null(); + _string_default_delegate.Null(); + _number_default_delegate.Null(); + _closure_default_delegate.Null(); + _generator_default_delegate.Null(); + _thread_default_delegate.Null(); + _class_default_delegate.Null(); + _instance_default_delegate.Null(); + _weakref_default_delegate.Null(); + _refs_table.Finalize(); +#ifndef NO_GARBAGE_COLLECTOR + SQCollectable *t = _gc_chain; + SQCollectable *nx = NULL; + while(t) { + t->_uiRef++; + t->Finalize(); + nx = t->_next; + if(--t->_uiRef == 0) + t->Release(); + t=nx; + } + assert(_gc_chain==NULL); //just to proove a theory + while(_gc_chain){ + _gc_chain->_uiRef++; + _gc_chain->Release(); + } +#endif + + sq_delete(_types,SQObjectPtrVec); + sq_delete(_systemstrings,SQObjectPtrVec); + sq_delete(_metamethods,SQObjectPtrVec); + sq_delete(_stringtable,SQStringTable); + if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize); +} + + +SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name) +{ + if(type(name) != OT_STRING) + return -1; + SQObjectPtr ret; + if(_table(_metamethodsmap)->Get(name,ret)) { + return _integer(ret); + } + return -1; +} + +#ifndef NO_GARBAGE_COLLECTOR + +void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain) +{ + switch(type(o)){ + case OT_TABLE:_table(o)->Mark(chain);break; + case OT_ARRAY:_array(o)->Mark(chain);break; + case OT_USERDATA:_userdata(o)->Mark(chain);break; + case OT_CLOSURE:_closure(o)->Mark(chain);break; + case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break; + case OT_GENERATOR:_generator(o)->Mark(chain);break; + case OT_THREAD:_thread(o)->Mark(chain);break; + case OT_CLASS:_class(o)->Mark(chain);break; + case OT_INSTANCE:_instance(o)->Mark(chain);break; + case OT_OUTER:_outer(o)->Mark(chain);break; + case OT_FUNCPROTO:_funcproto(o)->Mark(chain);break; + default: break; //shutup compiler + } +} + + +void SQSharedState::RunMark(SQVM *vm,SQCollectable **tchain) +{ + SQVM *vms = _thread(_root_vm); + + vms->Mark(tchain); + + _refs_table.Mark(tchain); + MarkObject(_registry,tchain); + MarkObject(_consts,tchain); + MarkObject(_metamethodsmap,tchain); + MarkObject(_table_default_delegate,tchain); + MarkObject(_array_default_delegate,tchain); + MarkObject(_string_default_delegate,tchain); + MarkObject(_number_default_delegate,tchain); + MarkObject(_generator_default_delegate,tchain); + MarkObject(_thread_default_delegate,tchain); + MarkObject(_closure_default_delegate,tchain); + MarkObject(_class_default_delegate,tchain); + MarkObject(_instance_default_delegate,tchain); + MarkObject(_weakref_default_delegate,tchain); + +} + +SQInteger SQSharedState::ResurrectUnreachable(SQVM *vm) +{ + SQInteger n=0; + SQCollectable *tchain=NULL; + + RunMark(vm,&tchain); + + SQCollectable *resurrected = _gc_chain; + SQCollectable *t = resurrected; + //SQCollectable *nx = NULL; + + _gc_chain = tchain; + + SQArray *ret = NULL; + if(resurrected) { + ret = SQArray::Create(this,0); + SQCollectable *rlast = NULL; + while(t) { + rlast = t; + SQObjectType type = t->GetType(); + if(type != OT_FUNCPROTO && type != OT_OUTER) { + SQObject sqo; + sqo._type = type; + sqo._unVal.pRefCounted = t; + ret->Append(sqo); + } + t = t->_next; + n++; + } + + assert(rlast->_next == NULL); + rlast->_next = _gc_chain; + if(_gc_chain) + { + _gc_chain->_prev = rlast; + } + _gc_chain = resurrected; + } + + t = _gc_chain; + while(t) { + t->UnMark(); + t = t->_next; + } + + if(ret) { + SQObjectPtr temp = ret; + vm->Push(temp); + } + else { + vm->PushNull(); + } + return n; +} + +SQInteger SQSharedState::CollectGarbage(SQVM *vm) +{ + SQInteger n=0; + SQCollectable *tchain=NULL; + + RunMark(vm,&tchain); + + SQCollectable *t = _gc_chain; + SQCollectable *nx = NULL; + while(t) { + t->_uiRef++; + t->Finalize(); + nx = t->_next; + if(--t->_uiRef == 0) + t->Release(); + t = nx; + n++; + } + + t = tchain; + while(t) { + t->UnMark(); + t = t->_next; + } + _gc_chain = tchain; + + return n; +} +#endif + +#ifndef NO_GARBAGE_COLLECTOR +void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c) +{ + c->_prev = NULL; + c->_next = *chain; + if(*chain) (*chain)->_prev = c; + *chain = c; +} + +void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c) +{ + if(c->_prev) c->_prev->_next = c->_next; + else *chain = c->_next; + if(c->_next) + c->_next->_prev = c->_prev; + c->_next = NULL; + c->_prev = NULL; +} +#endif + +SQChar* SQSharedState::GetScratchPad(SQInteger size) +{ + SQInteger newsize; + if(size>0) { + if(_scratchpadsize < size) { + newsize = size + (size>>1); + _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); + _scratchpadsize = newsize; + + }else if(_scratchpadsize >= (size<<5)) { + newsize = _scratchpadsize >> 1; + _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); + _scratchpadsize = newsize; + } + } + return _scratchpad; +} + +RefTable::RefTable() +{ + AllocNodes(4); +} + +void RefTable::Finalize() +{ + RefNode *nodes = _nodes; + for(SQUnsignedInteger n = 0; n < _numofslots; n++) { + nodes->obj.Null(); + nodes++; + } +} + +RefTable::~RefTable() +{ + SQ_FREE(_buckets,(_numofslots * sizeof(RefNode *)) + (_numofslots * sizeof(RefNode))); +} + +#ifndef NO_GARBAGE_COLLECTOR +void RefTable::Mark(SQCollectable **chain) +{ + RefNode *nodes = (RefNode *)_nodes; + for(SQUnsignedInteger n = 0; n < _numofslots; n++) { + if(type(nodes->obj) != OT_NULL) { + SQSharedState::MarkObject(nodes->obj,chain); + } + nodes++; + } +} +#endif + +void RefTable::AddRef(SQObject &obj) +{ + SQHash mainpos; + RefNode *prev; + RefNode *ref = Get(obj,mainpos,&prev,true); + ref->refs++; +} + +SQUnsignedInteger RefTable::GetRefCount(SQObject &obj) +{ + SQHash mainpos; + RefNode *prev; + RefNode *ref = Get(obj,mainpos,&prev,true); + return ref->refs; +} + + +SQBool RefTable::Release(SQObject &obj) +{ + SQHash mainpos; + RefNode *prev; + RefNode *ref = Get(obj,mainpos,&prev,false); + if(ref) { + if(--ref->refs == 0) { + SQObjectPtr o = ref->obj; + if(prev) { + prev->next = ref->next; + } + else { + _buckets[mainpos] = ref->next; + } + ref->next = _freelist; + _freelist = ref; + _slotused--; + ref->obj.Null(); + //<>test for shrink? + return SQTrue; + } + } + else { + assert(0); + } + return SQFalse; +} + +void RefTable::Resize(SQUnsignedInteger size) +{ + RefNode **oldbucks = _buckets; + RefNode *t = _nodes; + SQUnsignedInteger oldnumofslots = _numofslots; + AllocNodes(size); + //rehash + SQUnsignedInteger nfound = 0; + for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) { + if(type(t->obj) != OT_NULL) { + //add back; + assert(t->refs != 0); + RefNode *nn = Add(::HashObj(t->obj)&(_numofslots-1),t->obj); + nn->refs = t->refs; + t->obj.Null(); + nfound++; + } + t++; + } + assert(nfound == oldnumofslots); + SQ_FREE(oldbucks,(oldnumofslots * sizeof(RefNode *)) + (oldnumofslots * sizeof(RefNode))); +} + +RefTable::RefNode *RefTable::Add(SQHash mainpos,SQObject &obj) +{ + RefNode *t = _buckets[mainpos]; + RefNode *newnode = _freelist; + newnode->obj = obj; + _buckets[mainpos] = newnode; + _freelist = _freelist->next; + newnode->next = t; + assert(newnode->refs == 0); + _slotused++; + return newnode; +} + +RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add) +{ + RefNode *ref; + mainpos = ::HashObj(obj)&(_numofslots-1); + *prev = NULL; + for (ref = _buckets[mainpos]; ref; ) { + if(_rawval(ref->obj) == _rawval(obj) && type(ref->obj) == type(obj)) + break; + *prev = ref; + ref = ref->next; + } + if(ref == NULL && add) { + if(_numofslots == _slotused) { + assert(_freelist == 0); + Resize(_numofslots*2); + mainpos = ::HashObj(obj)&(_numofslots-1); + } + ref = Add(mainpos,obj); + } + return ref; +} + +void RefTable::AllocNodes(SQUnsignedInteger size) +{ + RefNode **bucks; + RefNode *nodes; + bucks = (RefNode **)SQ_MALLOC((size * sizeof(RefNode *)) + (size * sizeof(RefNode))); + nodes = (RefNode *)&bucks[size]; + RefNode *temp = nodes; + SQUnsignedInteger n; + for(n = 0; n < size - 1; n++) { + bucks[n] = NULL; + temp->refs = 0; + new (&temp->obj) SQObjectPtr; + temp->next = temp+1; + temp++; + } + bucks[n] = NULL; + temp->refs = 0; + new (&temp->obj) SQObjectPtr; + temp->next = NULL; + _freelist = nodes; + _nodes = nodes; + _buckets = bucks; + _slotused = 0; + _numofslots = size; +} +////////////////////////////////////////////////////////////////////////// +//SQStringTable +/* +* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.) +* http://www.lua.org/copyright.html#4 +* http://www.lua.org/source/4.0.1/src_lstring.c.html +*/ + +SQStringTable::SQStringTable(SQSharedState *ss) +{ + _sharedstate = ss; + AllocNodes(4); + _slotused = 0; +} + +SQStringTable::~SQStringTable() +{ + SQ_FREE(_strings,sizeof(SQString*)*_numofslots); + _strings = NULL; +} + +void SQStringTable::AllocNodes(SQInteger size) +{ + _numofslots = size; + _strings = (SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots); + memset(_strings,0,sizeof(SQString*)*_numofslots); +} + +SQString *SQStringTable::Add(const SQChar *news,SQInteger len) +{ + if(len<0) + len = (SQInteger)scstrlen(news); + SQHash h = ::_hashstr(news,len)&(_numofslots-1); + SQString *s; + for (s = _strings[h]; s; s = s->_next){ + if(s->_len == len && (!memcmp(news,s->_val,rsl(len)))) + return s; //found + } + + SQString *t=(SQString *)SQ_MALLOC(rsl(len)+sizeof(SQString)); + new (t) SQString; + t->_sharedstate = _sharedstate; + memcpy(t->_val,news,rsl(len)); + t->_val[len] = _SC('\0'); + t->_len = len; + t->_hash = ::_hashstr(news,len); + t->_next = _strings[h]; + _strings[h] = t; + _slotused++; + if (_slotused > _numofslots) /* too crowded? */ + Resize(_numofslots*2); + return t; +} + +void SQStringTable::Resize(SQInteger size) +{ + SQInteger oldsize=_numofslots; + SQString **oldtable=_strings; + AllocNodes(size); + for (SQInteger i=0; i_next; + SQHash h = p->_hash&(_numofslots-1); + p->_next = _strings[h]; + _strings[h] = p; + p = next; + } + } + SQ_FREE(oldtable,oldsize*sizeof(SQString*)); +} + +void SQStringTable::Remove(SQString *bs) +{ + SQString *s; + SQString *prev=NULL; + SQHash h = bs->_hash&(_numofslots - 1); + + for (s = _strings[h]; s; ){ + if(s == bs){ + if(prev) + prev->_next = s->_next; + else + _strings[h] = s->_next; + _slotused--; + SQInteger slen = s->_len; + s->~SQString(); + SQ_FREE(s,sizeof(SQString) + rsl(slen)); + return; + } + prev = s; + s = s->_next; + } + assert(0);//if this fail something is wrong +} diff --git a/squirrel_3_0_1_stable/squirrel/sqstate.h b/squirrel_3_0_1_stable/squirrel/sqstate.h index 3ed3307d7..ee652e786 100644 --- a/squirrel_3_0_1_stable/squirrel/sqstate.h +++ b/squirrel_3_0_1_stable/squirrel/sqstate.h @@ -1,144 +1,144 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTATE_H_ -#define _SQSTATE_H_ - -#include "squtils.h" -#include "sqobject.h" -struct SQString; -struct SQTable; -//max number of character for a printed number -#define NUMBER_MAX_CHAR 50 - -struct SQStringTable -{ - SQStringTable(SQSharedState*ss); - ~SQStringTable(); - SQString *Add(const SQChar *,SQInteger len); - void Remove(SQString *); -private: - void Resize(SQInteger size); - void AllocNodes(SQInteger size); - SQString **_strings; - SQUnsignedInteger _numofslots; - SQUnsignedInteger _slotused; - SQSharedState *_sharedstate; -}; - -struct RefTable { - struct RefNode { - SQObjectPtr obj; - SQUnsignedInteger refs; - struct RefNode *next; - }; - RefTable(); - ~RefTable(); - void AddRef(SQObject &obj); - SQBool Release(SQObject &obj); - SQUnsignedInteger GetRefCount(SQObject &obj); -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **chain); -#endif - void Finalize(); -private: - RefNode *Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add); - RefNode *Add(SQHash mainpos,SQObject &obj); - void Resize(SQUnsignedInteger size); - void AllocNodes(SQUnsignedInteger size); - SQUnsignedInteger _numofslots; - SQUnsignedInteger _slotused; - RefNode *_nodes; - RefNode *_freelist; - RefNode **_buckets; -}; - -#define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len) -#define REMOVE_STRING(ss,bstr) ss->_stringtable->Remove(bstr) - -struct SQObjectPtr; - -struct SQSharedState -{ - SQSharedState(); - ~SQSharedState(); - void Init(); -public: - SQChar* GetScratchPad(SQInteger size); - SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name); -#ifndef NO_GARBAGE_COLLECTOR - SQInteger CollectGarbage(SQVM *vm); - void RunMark(SQVM *vm,SQCollectable **tchain); - SQInteger ResurrectUnreachable(SQVM *vm); - static void MarkObject(SQObjectPtr &o,SQCollectable **chain); -#endif - SQObjectPtrVec *_metamethods; - SQObjectPtr _metamethodsmap; - SQObjectPtrVec *_systemstrings; - SQObjectPtrVec *_types; - SQStringTable *_stringtable; - RefTable _refs_table; - SQObjectPtr _registry; - SQObjectPtr _consts; - SQObjectPtr _constructoridx; -#ifndef NO_GARBAGE_COLLECTOR - SQCollectable *_gc_chain; -#endif - SQObjectPtr _root_vm; - SQObjectPtr _table_default_delegate; - static SQRegFunction _table_default_delegate_funcz[]; - SQObjectPtr _array_default_delegate; - static SQRegFunction _array_default_delegate_funcz[]; - SQObjectPtr _string_default_delegate; - static SQRegFunction _string_default_delegate_funcz[]; - SQObjectPtr _number_default_delegate; - static SQRegFunction _number_default_delegate_funcz[]; - SQObjectPtr _generator_default_delegate; - static SQRegFunction _generator_default_delegate_funcz[]; - SQObjectPtr _closure_default_delegate; - static SQRegFunction _closure_default_delegate_funcz[]; - SQObjectPtr _thread_default_delegate; - static SQRegFunction _thread_default_delegate_funcz[]; - SQObjectPtr _class_default_delegate; - static SQRegFunction _class_default_delegate_funcz[]; - SQObjectPtr _instance_default_delegate; - static SQRegFunction _instance_default_delegate_funcz[]; - SQObjectPtr _weakref_default_delegate; - static SQRegFunction _weakref_default_delegate_funcz[]; - - SQCOMPILERERROR _compilererrorhandler; - SQPRINTFUNCTION _printfunc; - SQPRINTFUNCTION _errorfunc; - bool _debuginfo; - bool _notifyallexceptions; -private: - SQChar *_scratchpad; - SQInteger _scratchpadsize; -}; - -#define _sp(s) (_sharedstate->GetScratchPad(s)) -#define _spval (_sharedstate->GetScratchPad(-1)) - -#define _table_ddel _table(_sharedstate->_table_default_delegate) -#define _array_ddel _table(_sharedstate->_array_default_delegate) -#define _string_ddel _table(_sharedstate->_string_default_delegate) -#define _number_ddel _table(_sharedstate->_number_default_delegate) -#define _generator_ddel _table(_sharedstate->_generator_default_delegate) -#define _closure_ddel _table(_sharedstate->_closure_default_delegate) -#define _thread_ddel _table(_sharedstate->_thread_default_delegate) -#define _class_ddel _table(_sharedstate->_class_default_delegate) -#define _instance_ddel _table(_sharedstate->_instance_default_delegate) -#define _weakref_ddel _table(_sharedstate->_weakref_default_delegate) - -#ifdef SQUNICODE //rsl REAL STRING LEN -#define rsl(l) ((l)<<1) -#else -#define rsl(l) (l) -#endif - -//extern SQObjectPtr _null_; - -bool CompileTypemask(SQIntVec &res,const SQChar *typemask); - -void *sq_vm_malloc(SQUnsignedInteger size); -void *sq_vm_realloc(void *p,SQUnsignedInteger oldsize,SQUnsignedInteger size); -void sq_vm_free(void *p,SQUnsignedInteger size); -#endif //_SQSTATE_H_ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTATE_H_ +#define _SQSTATE_H_ + +#include "squtils.h" +#include "sqobject.h" +struct SQString; +struct SQTable; +//max number of character for a printed number +#define NUMBER_MAX_CHAR 50 + +struct SQStringTable +{ + SQStringTable(SQSharedState*ss); + ~SQStringTable(); + SQString *Add(const SQChar *,SQInteger len); + void Remove(SQString *); +private: + void Resize(SQInteger size); + void AllocNodes(SQInteger size); + SQString **_strings; + SQUnsignedInteger _numofslots; + SQUnsignedInteger _slotused; + SQSharedState *_sharedstate; +}; + +struct RefTable { + struct RefNode { + SQObjectPtr obj; + SQUnsignedInteger refs; + struct RefNode *next; + }; + RefTable(); + ~RefTable(); + void AddRef(SQObject &obj); + SQBool Release(SQObject &obj); + SQUnsignedInteger GetRefCount(SQObject &obj); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); +#endif + void Finalize(); +private: + RefNode *Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add); + RefNode *Add(SQHash mainpos,SQObject &obj); + void Resize(SQUnsignedInteger size); + void AllocNodes(SQUnsignedInteger size); + SQUnsignedInteger _numofslots; + SQUnsignedInteger _slotused; + RefNode *_nodes; + RefNode *_freelist; + RefNode **_buckets; +}; + +#define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len) +#define REMOVE_STRING(ss,bstr) ss->_stringtable->Remove(bstr) + +struct SQObjectPtr; + +struct SQSharedState +{ + SQSharedState(); + ~SQSharedState(); + void Init(); +public: + SQChar* GetScratchPad(SQInteger size); + SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name); +#ifndef NO_GARBAGE_COLLECTOR + SQInteger CollectGarbage(SQVM *vm); + void RunMark(SQVM *vm,SQCollectable **tchain); + SQInteger ResurrectUnreachable(SQVM *vm); + static void MarkObject(SQObjectPtr &o,SQCollectable **chain); +#endif + SQObjectPtrVec *_metamethods; + SQObjectPtr _metamethodsmap; + SQObjectPtrVec *_systemstrings; + SQObjectPtrVec *_types; + SQStringTable *_stringtable; + RefTable _refs_table; + SQObjectPtr _registry; + SQObjectPtr _consts; + SQObjectPtr _constructoridx; +#ifndef NO_GARBAGE_COLLECTOR + SQCollectable *_gc_chain; +#endif + SQObjectPtr _root_vm; + SQObjectPtr _table_default_delegate; + static SQRegFunction _table_default_delegate_funcz[]; + SQObjectPtr _array_default_delegate; + static SQRegFunction _array_default_delegate_funcz[]; + SQObjectPtr _string_default_delegate; + static SQRegFunction _string_default_delegate_funcz[]; + SQObjectPtr _number_default_delegate; + static SQRegFunction _number_default_delegate_funcz[]; + SQObjectPtr _generator_default_delegate; + static SQRegFunction _generator_default_delegate_funcz[]; + SQObjectPtr _closure_default_delegate; + static SQRegFunction _closure_default_delegate_funcz[]; + SQObjectPtr _thread_default_delegate; + static SQRegFunction _thread_default_delegate_funcz[]; + SQObjectPtr _class_default_delegate; + static SQRegFunction _class_default_delegate_funcz[]; + SQObjectPtr _instance_default_delegate; + static SQRegFunction _instance_default_delegate_funcz[]; + SQObjectPtr _weakref_default_delegate; + static SQRegFunction _weakref_default_delegate_funcz[]; + + SQCOMPILERERROR _compilererrorhandler; + SQPRINTFUNCTION _printfunc; + SQPRINTFUNCTION _errorfunc; + bool _debuginfo; + bool _notifyallexceptions; +private: + SQChar *_scratchpad; + SQInteger _scratchpadsize; +}; + +#define _sp(s) (_sharedstate->GetScratchPad(s)) +#define _spval (_sharedstate->GetScratchPad(-1)) + +#define _table_ddel _table(_sharedstate->_table_default_delegate) +#define _array_ddel _table(_sharedstate->_array_default_delegate) +#define _string_ddel _table(_sharedstate->_string_default_delegate) +#define _number_ddel _table(_sharedstate->_number_default_delegate) +#define _generator_ddel _table(_sharedstate->_generator_default_delegate) +#define _closure_ddel _table(_sharedstate->_closure_default_delegate) +#define _thread_ddel _table(_sharedstate->_thread_default_delegate) +#define _class_ddel _table(_sharedstate->_class_default_delegate) +#define _instance_ddel _table(_sharedstate->_instance_default_delegate) +#define _weakref_ddel _table(_sharedstate->_weakref_default_delegate) + +#ifdef SQUNICODE //rsl REAL STRING LEN +#define rsl(l) ((l)<<1) +#else +#define rsl(l) (l) +#endif + +//extern SQObjectPtr _null_; + +bool CompileTypemask(SQIntVec &res,const SQChar *typemask); + +void *sq_vm_malloc(SQUnsignedInteger size); +void *sq_vm_realloc(void *p,SQUnsignedInteger oldsize,SQUnsignedInteger size); +void sq_vm_free(void *p,SQUnsignedInteger size); +#endif //_SQSTATE_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqstring.h b/squirrel_3_0_1_stable/squirrel/sqstring.h index 235d19059..14f09e1b0 100644 --- a/squirrel_3_0_1_stable/squirrel/sqstring.h +++ b/squirrel_3_0_1_stable/squirrel/sqstring.h @@ -1,31 +1,31 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTRING_H_ -#define _SQSTRING_H_ - -inline SQHash _hashstr (const SQChar *s, size_t l) -{ - SQHash h = (SQHash)l; /* seed */ - size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */ - for (; l>=step; l-=step) - h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++)); - return h; -} - -struct SQString : public SQRefCounted -{ - SQString(){} - ~SQString(){} -public: - static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 ); - SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); - void Release(); - SQSharedState *_sharedstate; - SQString *_next; //chain for the string table - SQInteger _len; - SQHash _hash; - SQChar _val[1]; -}; - - - -#endif //_SQSTRING_H_ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTRING_H_ +#define _SQSTRING_H_ + +inline SQHash _hashstr (const SQChar *s, size_t l) +{ + SQHash h = (SQHash)l; /* seed */ + size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */ + for (; l>=step; l-=step) + h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++)); + return h; +} + +struct SQString : public SQRefCounted +{ + SQString(){} + ~SQString(){} +public: + static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 ); + SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); + void Release(); + SQSharedState *_sharedstate; + SQString *_next; //chain for the string table + SQInteger _len; + SQHash _hash; + SQChar _val[1]; +}; + + + +#endif //_SQSTRING_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqtable.cpp b/squirrel_3_0_1_stable/squirrel/sqtable.cpp index fe3d5f2a1..bc43124a3 100644 --- a/squirrel_3_0_1_stable/squirrel/sqtable.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqtable.cpp @@ -1,220 +1,220 @@ -/* -see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#include "sqvm.h" -#include "sqtable.h" -#include "sqfuncproto.h" -#include "sqclosure.h" - -SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize) -{ - SQInteger pow2size=MINPOWER2; - while(nInitialSize>pow2size)pow2size=pow2size<<1; - AllocNodes(pow2size); - _usednodes = 0; - _delegate = NULL; - INIT_CHAIN(); - ADD_TO_CHAIN(&_sharedstate->_gc_chain,this); -} - -void SQTable::Remove(const SQObjectPtr &key) -{ - - _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); - if (n) { - n->val.Null(); - n->key.Null(); - _usednodes--; - Rehash(false); - } -} - -void SQTable::AllocNodes(SQInteger nSize) -{ - _HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize); - for(SQInteger i=0;i= oldsize-oldsize/4) /* using more than 3/4? */ - AllocNodes(oldsize*2); - else if (nelems <= oldsize/4 && /* less than 1/4? */ - oldsize > MINPOWER2) - AllocNodes(oldsize/2); - else if(force) - AllocNodes(oldsize); - else - return; - _usednodes = 0; - for (SQInteger i=0; ikey) != OT_NULL) - NewSlot(old->key,old->val); - } - for(SQInteger k=0;k_nodes; - _HashNode *src = _nodes; - _HashNode *dst = nt->_nodes; - SQInteger n = 0; - for(n = 0; n < _numofnodes; n++) { - dst->key = src->key; - dst->val = src->val; - if(src->next) { - assert(src->next > basesrc); - dst->next = basedst + (src->next - basesrc); - assert(dst != dst->next); - } - dst++; - src++; - } - assert(_firstfree > basesrc); - assert(_firstfree != NULL); - nt->_firstfree = basedst + (_firstfree - basesrc); -#else - SQInteger ridx=0; - SQObjectPtr key,val; - while((ridx=Next(true,ridx,key,val))!=-1){ - nt->NewSlot(key,val); - } -#endif - nt->SetDelegate(_delegate); - return nt; -} - -bool SQTable::Get(const SQObjectPtr &key,SQObjectPtr &val) -{ - if(type(key) == OT_NULL) - return false; - _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); - if (n) { - val = _realval(n->val); - return true; - } - return false; -} -bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val) -{ - assert(type(key) != OT_NULL); - SQHash h = HashObj(key) & (_numofnodes - 1); - _HashNode *n = _Get(key, h); - if (n) { - n->val = val; - return false; - } - _HashNode *mp = &_nodes[h]; - n = mp; - - - //key not found I'll insert it - //main pos is not free - - if(type(mp->key) != OT_NULL) { - n = _firstfree; /* get a free place */ - SQHash mph = HashObj(mp->key) & (_numofnodes - 1); - _HashNode *othern; /* main position of colliding node */ - - if (mp > n && (othern = &_nodes[mph]) != mp){ - /* yes; move colliding node into free position */ - while (othern->next != mp){ - assert(othern->next != NULL); - othern = othern->next; /* find previous */ - } - othern->next = n; /* redo the chain with `n' in place of `mp' */ - n->key = mp->key; - n->val = mp->val;/* copy colliding node into free pos. (mp->next also goes) */ - n->next = mp->next; - mp->key.Null(); - mp->val.Null(); - mp->next = NULL; /* now `mp' is free */ - } - else{ - /* new node will go into free position */ - n->next = mp->next; /* chain new position */ - mp->next = n; - mp = n; - } - } - mp->key = key; - - for (;;) { /* correct `firstfree' */ - if (type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) { - mp->val = val; - _usednodes++; - return true; /* OK; table still has a free place */ - } - else if (_firstfree == _nodes) break; /* cannot decrement from here */ - else (_firstfree)--; - } - Rehash(true); - return NewSlot(key, val); -} - -SQInteger SQTable::Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) -{ - SQInteger idx = (SQInteger)TranslateIndex(refpos); - while (idx < _numofnodes) { - if(type(_nodes[idx].key) != OT_NULL) { - //first found - _HashNode &n = _nodes[idx]; - outkey = n.key; - outval = getweakrefs?(SQObject)n.val:_realval(n.val); - //return idx for the next iteration - return ++idx; - } - ++idx; - } - //nothing to iterate anymore - return -1; -} - - -bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val) -{ - _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); - if (n) { - n->val = val; - return true; - } - return false; -} - -void SQTable::_ClearNodes() -{ - for(SQInteger i = 0;i < _numofnodes; i++) { _HashNode &n = _nodes[i]; n.key.Null(); n.val.Null(); } -} - -void SQTable::Finalize() -{ - _ClearNodes(); - SetDelegate(NULL); -} - -void SQTable::Clear() -{ - _ClearNodes(); - _usednodes = 0; - Rehash(true); -} +/* +see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqtable.h" +#include "sqfuncproto.h" +#include "sqclosure.h" + +SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize) +{ + SQInteger pow2size=MINPOWER2; + while(nInitialSize>pow2size)pow2size=pow2size<<1; + AllocNodes(pow2size); + _usednodes = 0; + _delegate = NULL; + INIT_CHAIN(); + ADD_TO_CHAIN(&_sharedstate->_gc_chain,this); +} + +void SQTable::Remove(const SQObjectPtr &key) +{ + + _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); + if (n) { + n->val.Null(); + n->key.Null(); + _usednodes--; + Rehash(false); + } +} + +void SQTable::AllocNodes(SQInteger nSize) +{ + _HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize); + for(SQInteger i=0;i= oldsize-oldsize/4) /* using more than 3/4? */ + AllocNodes(oldsize*2); + else if (nelems <= oldsize/4 && /* less than 1/4? */ + oldsize > MINPOWER2) + AllocNodes(oldsize/2); + else if(force) + AllocNodes(oldsize); + else + return; + _usednodes = 0; + for (SQInteger i=0; ikey) != OT_NULL) + NewSlot(old->key,old->val); + } + for(SQInteger k=0;k_nodes; + _HashNode *src = _nodes; + _HashNode *dst = nt->_nodes; + SQInteger n = 0; + for(n = 0; n < _numofnodes; n++) { + dst->key = src->key; + dst->val = src->val; + if(src->next) { + assert(src->next > basesrc); + dst->next = basedst + (src->next - basesrc); + assert(dst != dst->next); + } + dst++; + src++; + } + assert(_firstfree > basesrc); + assert(_firstfree != NULL); + nt->_firstfree = basedst + (_firstfree - basesrc); +#else + SQInteger ridx=0; + SQObjectPtr key,val; + while((ridx=Next(true,ridx,key,val))!=-1){ + nt->NewSlot(key,val); + } +#endif + nt->SetDelegate(_delegate); + return nt; +} + +bool SQTable::Get(const SQObjectPtr &key,SQObjectPtr &val) +{ + if(type(key) == OT_NULL) + return false; + _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); + if (n) { + val = _realval(n->val); + return true; + } + return false; +} +bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val) +{ + assert(type(key) != OT_NULL); + SQHash h = HashObj(key) & (_numofnodes - 1); + _HashNode *n = _Get(key, h); + if (n) { + n->val = val; + return false; + } + _HashNode *mp = &_nodes[h]; + n = mp; + + + //key not found I'll insert it + //main pos is not free + + if(type(mp->key) != OT_NULL) { + n = _firstfree; /* get a free place */ + SQHash mph = HashObj(mp->key) & (_numofnodes - 1); + _HashNode *othern; /* main position of colliding node */ + + if (mp > n && (othern = &_nodes[mph]) != mp){ + /* yes; move colliding node into free position */ + while (othern->next != mp){ + assert(othern->next != NULL); + othern = othern->next; /* find previous */ + } + othern->next = n; /* redo the chain with `n' in place of `mp' */ + n->key = mp->key; + n->val = mp->val;/* copy colliding node into free pos. (mp->next also goes) */ + n->next = mp->next; + mp->key.Null(); + mp->val.Null(); + mp->next = NULL; /* now `mp' is free */ + } + else{ + /* new node will go into free position */ + n->next = mp->next; /* chain new position */ + mp->next = n; + mp = n; + } + } + mp->key = key; + + for (;;) { /* correct `firstfree' */ + if (type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) { + mp->val = val; + _usednodes++; + return true; /* OK; table still has a free place */ + } + else if (_firstfree == _nodes) break; /* cannot decrement from here */ + else (_firstfree)--; + } + Rehash(true); + return NewSlot(key, val); +} + +SQInteger SQTable::Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) +{ + SQInteger idx = (SQInteger)TranslateIndex(refpos); + while (idx < _numofnodes) { + if(type(_nodes[idx].key) != OT_NULL) { + //first found + _HashNode &n = _nodes[idx]; + outkey = n.key; + outval = getweakrefs?(SQObject)n.val:_realval(n.val); + //return idx for the next iteration + return ++idx; + } + ++idx; + } + //nothing to iterate anymore + return -1; +} + + +bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val) +{ + _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); + if (n) { + n->val = val; + return true; + } + return false; +} + +void SQTable::_ClearNodes() +{ + for(SQInteger i = 0;i < _numofnodes; i++) { _HashNode &n = _nodes[i]; n.key.Null(); n.val.Null(); } +} + +void SQTable::Finalize() +{ + _ClearNodes(); + SetDelegate(NULL); +} + +void SQTable::Clear() +{ + _ClearNodes(); + _usednodes = 0; + Rehash(true); +} diff --git a/squirrel_3_0_1_stable/squirrel/sqtable.h b/squirrel_3_0_1_stable/squirrel/sqtable.h index 2f6487023..b2ba0ba98 100644 --- a/squirrel_3_0_1_stable/squirrel/sqtable.h +++ b/squirrel_3_0_1_stable/squirrel/sqtable.h @@ -1,92 +1,92 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQTABLE_H_ -#define _SQTABLE_H_ -/* -* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.) -* http://www.lua.org/copyright.html#4 -* http://www.lua.org/source/4.0.1/src_ltable.c.html -*/ - -#include "sqstring.h" - - -#define hashptr(p) ((SQHash)(((SQInteger)p) >> 3)) - -inline SQHash HashObj(const SQObjectPtr &key) -{ - switch(type(key)) { - case OT_STRING: return _string(key)->_hash; - case OT_FLOAT: return (SQHash)((SQInteger)_float(key)); - case OT_BOOL: case OT_INTEGER: return (SQHash)((SQInteger)_integer(key)); - default: return hashptr(key._unVal.pRefCounted); - } -} - -struct SQTable : public SQDelegable -{ -private: - struct _HashNode - { - _HashNode() { next = NULL; } - SQObjectPtr val; - SQObjectPtr key; - _HashNode *next; - }; - _HashNode *_firstfree; - _HashNode *_nodes; - SQInteger _numofnodes; - SQInteger _usednodes; - -/////////////////////////// - void AllocNodes(SQInteger nSize); - void Rehash(bool force); - SQTable(SQSharedState *ss, SQInteger nInitialSize); - void _ClearNodes(); -public: - static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize) - { - SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable)); - new (newtable) SQTable(ss, nInitialSize); - newtable->_delegate = NULL; - return newtable; - } - void Finalize(); - SQTable *Clone(); - ~SQTable() - { - SetDelegate(NULL); - REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); - for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode(); - SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode)); - } -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **chain); - SQObjectType GetType() {return OT_TABLE;} -#endif - inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash) - { - _HashNode *n = &_nodes[hash]; - do{ - if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){ - return n; - } - }while((n = n->next)); - return NULL; - } - bool Get(const SQObjectPtr &key,SQObjectPtr &val); - void Remove(const SQObjectPtr &key); - bool Set(const SQObjectPtr &key, const SQObjectPtr &val); - //returns true if a new slot has been created false if it was already present - bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val); - SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); - - SQInteger CountUsed(){ return _usednodes;} - void Clear(); - void Release() - { - sq_delete(this, SQTable); - } - -}; - -#endif //_SQTABLE_H_ +/* see copyright notice in squirrel.h */ +#ifndef _SQTABLE_H_ +#define _SQTABLE_H_ +/* +* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.) +* http://www.lua.org/copyright.html#4 +* http://www.lua.org/source/4.0.1/src_ltable.c.html +*/ + +#include "sqstring.h" + + +#define hashptr(p) ((SQHash)(((SQInteger)p) >> 3)) + +inline SQHash HashObj(const SQObjectPtr &key) +{ + switch(type(key)) { + case OT_STRING: return _string(key)->_hash; + case OT_FLOAT: return (SQHash)((SQInteger)_float(key)); + case OT_BOOL: case OT_INTEGER: return (SQHash)((SQInteger)_integer(key)); + default: return hashptr(key._unVal.pRefCounted); + } +} + +struct SQTable : public SQDelegable +{ +private: + struct _HashNode + { + _HashNode() { next = NULL; } + SQObjectPtr val; + SQObjectPtr key; + _HashNode *next; + }; + _HashNode *_firstfree; + _HashNode *_nodes; + SQInteger _numofnodes; + SQInteger _usednodes; + +/////////////////////////// + void AllocNodes(SQInteger nSize); + void Rehash(bool force); + SQTable(SQSharedState *ss, SQInteger nInitialSize); + void _ClearNodes(); +public: + static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize) + { + SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable)); + new (newtable) SQTable(ss, nInitialSize); + newtable->_delegate = NULL; + return newtable; + } + void Finalize(); + SQTable *Clone(); + ~SQTable() + { + SetDelegate(NULL); + REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); + for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode(); + SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode)); + } +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + SQObjectType GetType() {return OT_TABLE;} +#endif + inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash) + { + _HashNode *n = &_nodes[hash]; + do{ + if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){ + return n; + } + }while((n = n->next)); + return NULL; + } + bool Get(const SQObjectPtr &key,SQObjectPtr &val); + void Remove(const SQObjectPtr &key); + bool Set(const SQObjectPtr &key, const SQObjectPtr &val); + //returns true if a new slot has been created false if it was already present + bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val); + SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); + + SQInteger CountUsed(){ return _usednodes;} + void Clear(); + void Release() + { + sq_delete(this, SQTable); + } + +}; + +#endif //_SQTABLE_H_ diff --git a/squirrel_3_0_1_stable/squirrel/squserdata.h b/squirrel_3_0_1_stable/squirrel/squserdata.h index dea27ae78..2bf1b0709 100644 --- a/squirrel_3_0_1_stable/squirrel/squserdata.h +++ b/squirrel_3_0_1_stable/squirrel/squserdata.h @@ -1,40 +1,40 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQUSERDATA_H_ -#define _SQUSERDATA_H_ - -struct SQUserData : SQDelegable -{ - SQUserData(SQSharedState *ss){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); } - ~SQUserData() - { - REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this); - SetDelegate(NULL); - } - static SQUserData* Create(SQSharedState *ss, SQInteger size) - { - SQUserData* ud = (SQUserData*)SQ_MALLOC(sq_aligning(sizeof(SQUserData))+size); - new (ud) SQUserData(ss); - ud->_size = size; - ud->_typetag = 0; - return ud; - } -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **chain); - void Finalize(){SetDelegate(NULL);} - SQObjectType GetType(){ return OT_USERDATA;} -#endif - void Release() { - if (_hook) _hook((SQUserPointer)sq_aligning(this + 1),_size); - SQInteger tsize = _size; - this->~SQUserData(); - SQ_FREE(this, sq_aligning(sizeof(SQUserData)) + tsize); - } - - - SQInteger _size; - SQRELEASEHOOK _hook; - SQUserPointer _typetag; - //SQChar _val[1]; -}; - -#endif //_SQUSERDATA_H_ +/* see copyright notice in squirrel.h */ +#ifndef _SQUSERDATA_H_ +#define _SQUSERDATA_H_ + +struct SQUserData : SQDelegable +{ + SQUserData(SQSharedState *ss){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); } + ~SQUserData() + { + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this); + SetDelegate(NULL); + } + static SQUserData* Create(SQSharedState *ss, SQInteger size) + { + SQUserData* ud = (SQUserData*)SQ_MALLOC(sq_aligning(sizeof(SQUserData))+size); + new (ud) SQUserData(ss); + ud->_size = size; + ud->_typetag = 0; + return ud; + } +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize(){SetDelegate(NULL);} + SQObjectType GetType(){ return OT_USERDATA;} +#endif + void Release() { + if (_hook) _hook((SQUserPointer)sq_aligning(this + 1),_size); + SQInteger tsize = _size; + this->~SQUserData(); + SQ_FREE(this, sq_aligning(sizeof(SQUserData)) + tsize); + } + + + SQInteger _size; + SQRELEASEHOOK _hook; + SQUserPointer _typetag; + //SQChar _val[1]; +}; + +#endif //_SQUSERDATA_H_ diff --git a/squirrel_3_0_1_stable/squirrel/squtils.h b/squirrel_3_0_1_stable/squirrel/squtils.h index bff7d24bb..f3510beea 100644 --- a/squirrel_3_0_1_stable/squirrel/squtils.h +++ b/squirrel_3_0_1_stable/squirrel/squtils.h @@ -1,112 +1,112 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQUTILS_H_ -#define _SQUTILS_H_ - -#define sq_new(__ptr,__type) {__ptr=(__type *)sq_vm_malloc(sizeof(__type));new (__ptr) __type;} -#define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));} -#define SQ_MALLOC(__size) sq_vm_malloc((__size)); -#define SQ_FREE(__ptr,__size) sq_vm_free((__ptr),(__size)); -#define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc((__ptr),(__oldsize),(__size)); - -#define sq_aligning(v) (((size_t)(v) + (SQ_ALIGNMENT-1)) & (~(SQ_ALIGNMENT-1))) - -//sqvector mini vector class, supports objects by value -template class sqvector -{ -public: - sqvector() - { - _vals = NULL; - _size = 0; - _allocated = 0; - } - sqvector(const sqvector& v) - { - copy(v); - } - void copy(const sqvector& v) - { - if(_size) { - resize(0); //destroys all previous stuff - } - //resize(v._size); - if(v._size > _allocated) { - _realloc(v._size); - } - for(SQUnsignedInteger i = 0; i < v._size; i++) { - new ((void *)&_vals[i]) T(v._vals[i]); - } - _size = v._size; - } - ~sqvector() - { - if(_allocated) { - for(SQUnsignedInteger i = 0; i < _size; i++) - _vals[i].~T(); - SQ_FREE(_vals, (_allocated * sizeof(T))); - } - } - void reserve(SQUnsignedInteger newsize) { _realloc(newsize); } - void resize(SQUnsignedInteger newsize, const T& fill = T()) - { - if(newsize > _allocated) - _realloc(newsize); - if(newsize > _size) { - while(_size < newsize) { - new ((void *)&_vals[_size]) T(fill); - _size++; - } - } - else{ - for(SQUnsignedInteger i = newsize; i < _size; i++) { - _vals[i].~T(); - } - _size = newsize; - } - } - void shrinktofit() { if(_size > 4) { _realloc(_size); } } - T& top() const { return _vals[_size - 1]; } - inline SQUnsignedInteger size() const { return _size; } - bool empty() const { return (_size <= 0); } - inline T &push_back(const T& val = T()) - { - if(_allocated <= _size) - _realloc(_size * 2); - return *(new ((void *)&_vals[_size++]) T(val)); - } - inline void pop_back() - { - _size--; _vals[_size].~T(); - } - void insert(SQUnsignedInteger idx, const T& val) - { - resize(_size + 1); - for(SQUnsignedInteger i = _size - 1; i > idx; i--) { - _vals[i] = _vals[i - 1]; - } - _vals[idx] = val; - } - void remove(SQUnsignedInteger idx) - { - _vals[idx].~T(); - if(idx < (_size - 1)) { - memcpy(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1)); - } - _size--; - } - SQUnsignedInteger capacity() { return _allocated; } - inline T &back() const { return _vals[_size - 1]; } - inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; } - T* _vals; -private: - void _realloc(SQUnsignedInteger newsize) - { - newsize = (newsize > 0)?newsize:4; - _vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T)); - _allocated = newsize; - } - SQUnsignedInteger _size; - SQUnsignedInteger _allocated; -}; - -#endif //_SQUTILS_H_ +/* see copyright notice in squirrel.h */ +#ifndef _SQUTILS_H_ +#define _SQUTILS_H_ + +#define sq_new(__ptr,__type) {__ptr=(__type *)sq_vm_malloc(sizeof(__type));new (__ptr) __type;} +#define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));} +#define SQ_MALLOC(__size) sq_vm_malloc((__size)); +#define SQ_FREE(__ptr,__size) sq_vm_free((__ptr),(__size)); +#define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc((__ptr),(__oldsize),(__size)); + +#define sq_aligning(v) (((size_t)(v) + (SQ_ALIGNMENT-1)) & (~(SQ_ALIGNMENT-1))) + +//sqvector mini vector class, supports objects by value +template class sqvector +{ +public: + sqvector() + { + _vals = NULL; + _size = 0; + _allocated = 0; + } + sqvector(const sqvector& v) + { + copy(v); + } + void copy(const sqvector& v) + { + if(_size) { + resize(0); //destroys all previous stuff + } + //resize(v._size); + if(v._size > _allocated) { + _realloc(v._size); + } + for(SQUnsignedInteger i = 0; i < v._size; i++) { + new ((void *)&_vals[i]) T(v._vals[i]); + } + _size = v._size; + } + ~sqvector() + { + if(_allocated) { + for(SQUnsignedInteger i = 0; i < _size; i++) + _vals[i].~T(); + SQ_FREE(_vals, (_allocated * sizeof(T))); + } + } + void reserve(SQUnsignedInteger newsize) { _realloc(newsize); } + void resize(SQUnsignedInteger newsize, const T& fill = T()) + { + if(newsize > _allocated) + _realloc(newsize); + if(newsize > _size) { + while(_size < newsize) { + new ((void *)&_vals[_size]) T(fill); + _size++; + } + } + else{ + for(SQUnsignedInteger i = newsize; i < _size; i++) { + _vals[i].~T(); + } + _size = newsize; + } + } + void shrinktofit() { if(_size > 4) { _realloc(_size); } } + T& top() const { return _vals[_size - 1]; } + inline SQUnsignedInteger size() const { return _size; } + bool empty() const { return (_size <= 0); } + inline T &push_back(const T& val = T()) + { + if(_allocated <= _size) + _realloc(_size * 2); + return *(new ((void *)&_vals[_size++]) T(val)); + } + inline void pop_back() + { + _size--; _vals[_size].~T(); + } + void insert(SQUnsignedInteger idx, const T& val) + { + resize(_size + 1); + for(SQUnsignedInteger i = _size - 1; i > idx; i--) { + _vals[i] = _vals[i - 1]; + } + _vals[idx] = val; + } + void remove(SQUnsignedInteger idx) + { + _vals[idx].~T(); + if(idx < (_size - 1)) { + memcpy(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1)); + } + _size--; + } + SQUnsignedInteger capacity() { return _allocated; } + inline T &back() const { return _vals[_size - 1]; } + inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; } + T* _vals; +private: + void _realloc(SQUnsignedInteger newsize) + { + newsize = (newsize > 0)?newsize:4; + _vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T)); + _allocated = newsize; + } + SQUnsignedInteger _size; + SQUnsignedInteger _allocated; +}; + +#endif //_SQUTILS_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqvm.cpp b/squirrel_3_0_1_stable/squirrel/sqvm.cpp index bd8ebcc1a..b6ad21836 100644 --- a/squirrel_3_0_1_stable/squirrel/sqvm.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqvm.cpp @@ -1,1714 +1,1714 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#include -#include -#include "sqopcodes.h" -#include "sqvm.h" -#include "sqfuncproto.h" -#include "sqclosure.h" -#include "sqstring.h" -#include "sqtable.h" -#include "squserdata.h" -#include "sqarray.h" -#include "sqclass.h" - -#define TOP() (_stack._vals[_top-1]) - -bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2) -{ - SQInteger res; - if((type(o1)|type(o2)) == OT_INTEGER) - { - SQInteger i1 = _integer(o1), i2 = _integer(o2); - switch(op) { - case BW_AND: res = i1 & i2; break; - case BW_OR: res = i1 | i2; break; - case BW_XOR: res = i1 ^ i2; break; - case BW_SHIFTL: res = i1 << i2; break; - case BW_SHIFTR: res = i1 >> i2; break; - case BW_USHIFTR:res = (SQInteger)(*((SQUnsignedInteger*)&i1) >> i2); break; - default: { Raise_Error(_SC("internal vm error bitwise op failed")); return false; } - } - } - else { Raise_Error(_SC("bitwise op between '%s' and '%s'"),GetTypeName(o1),GetTypeName(o2)); return false;} - trg = res; - return true; -} - -#define _ARITH_(op,trg,o1,o2) \ -{ \ - SQInteger tmask = type(o1)|type(o2); \ - switch(tmask) { \ - case OT_INTEGER: trg = _integer(o1) op _integer(o2);break; \ - case (OT_FLOAT|OT_INTEGER): \ - case (OT_FLOAT): trg = tofloat(o1) op tofloat(o2); break;\ - default: _GUARD(ARITH_OP((#op)[0],trg,o1,o2)); break;\ - } \ -} - -#define _ARITH_NOZERO(op,trg,o1,o2,err) \ -{ \ - SQInteger tmask = type(o1)|type(o2); \ - switch(tmask) { \ - case OT_INTEGER: { SQInteger i2 = _integer(o2); if(i2 == 0) { Raise_Error(err); SQ_THROW(); } trg = _integer(o1) op i2; } break;\ - case (OT_FLOAT|OT_INTEGER): \ - case (OT_FLOAT): trg = tofloat(o1) op tofloat(o2); break;\ - default: _GUARD(ARITH_OP((#op)[0],trg,o1,o2)); break;\ - } \ -} - -bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2) -{ - SQInteger tmask = type(o1)|type(o2); - switch(tmask) { - case OT_INTEGER:{ - SQInteger res, i1 = _integer(o1), i2 = _integer(o2); - switch(op) { - case '+': res = i1 + i2; break; - case '-': res = i1 - i2; break; - case '/': if(i2 == 0) { Raise_Error(_SC("division by zero")); return false; } - res = i1 / i2; - break; - case '*': res = i1 * i2; break; - case '%': if(i2 == 0) { Raise_Error(_SC("modulo by zero")); return false; } - res = i1 % i2; - break; - default: res = 0xDEADBEEF; - } - trg = res; } - break; - case (OT_FLOAT|OT_INTEGER): - case (OT_FLOAT):{ - SQFloat res, f1 = tofloat(o1), f2 = tofloat(o2); - switch(op) { - case '+': res = f1 + f2; break; - case '-': res = f1 - f2; break; - case '/': res = f1 / f2; break; - case '*': res = f1 * f2; break; - case '%': res = SQFloat(fmod((double)f1,(double)f2)); break; - default: res = 0x0f; - } - trg = res; } - break; - default: - if(op == '+' && (tmask & _RT_STRING)){ - if(!StringCat(o1, o2, trg)) return false; - } - else if(!ArithMetaMethod(op,o1,o2,trg)) { - return false; - } - } - return true; -} - -SQVM::SQVM(SQSharedState *ss) -{ - _sharedstate=ss; - _suspended = SQFalse; - _suspended_target = -1; - _suspended_root = SQFalse; - _suspended_traps = -1; - _foreignptr = NULL; - _nnativecalls = 0; - _nmetamethodscall = 0; - _lasterror.Null(); - _errorhandler.Null(); - _debughook = false; - _debughook_native = NULL; - _debughook_closure.Null(); - _openouters = NULL; - ci = NULL; - INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); -} - -void SQVM::Finalize() -{ - if(_openouters) CloseOuters(&_stack._vals[0]); - _roottable.Null(); - _lasterror.Null(); - _errorhandler.Null(); - _debughook = false; - _debughook_native = NULL; - _debughook_closure.Null(); - temp_reg.Null(); - _callstackdata.resize(0); - SQInteger size=_stack.size(); - for(SQInteger i=0;i_gc_chain,this); -} - -bool SQVM::ArithMetaMethod(SQInteger op,const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &dest) -{ - SQMetaMethod mm; - switch(op){ - case _SC('+'): mm=MT_ADD; break; - case _SC('-'): mm=MT_SUB; break; - case _SC('/'): mm=MT_DIV; break; - case _SC('*'): mm=MT_MUL; break; - case _SC('%'): mm=MT_MODULO; break; - default: mm = MT_ADD; assert(0); break; //shutup compiler - } - if(is_delegable(o1) && _delegable(o1)->_delegate) { - - SQObjectPtr closure; - if(_delegable(o1)->GetMetaMethod(this, mm, closure)) { - Push(o1);Push(o2); - return CallMetaMethod(closure,mm,2,dest); - } - } - Raise_Error(_SC("arith op %c on between '%s' and '%s'"),op,GetTypeName(o1),GetTypeName(o2)); - return false; -} - -bool SQVM::NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o) -{ - - switch(type(o)) { - case OT_INTEGER: - trg = -_integer(o); - return true; - case OT_FLOAT: - trg = -_float(o); - return true; - case OT_TABLE: - case OT_USERDATA: - case OT_INSTANCE: - if(_delegable(o)->_delegate) { - SQObjectPtr closure; - if(_delegable(o)->GetMetaMethod(this, MT_UNM, closure)) { - Push(o); - if(!CallMetaMethod(closure, MT_UNM, 1, temp_reg)) return false; - _Swap(trg,temp_reg); - return true; - - } - } - default:break; //shutup compiler - } - Raise_Error(_SC("attempt to negate a %s"), GetTypeName(o)); - return false; -} - -#define _RET_SUCCEED(exp) { result = (exp); return true; } -bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result) -{ - SQObjectType t1 = type(o1), t2 = type(o2); - if(t1 == t2){ - if(_rawval(o1)==_rawval(o2))_RET_SUCCEED(0); - SQObjectPtr res; - switch(t1){ - case OT_STRING: - _RET_SUCCEED(scstrcmp(_stringval(o1),_stringval(o2))); - case OT_INTEGER: - _RET_SUCCEED(_integer(o1)-_integer(o2)); - case OT_FLOAT: - _RET_SUCCEED((_float(o1)<_float(o2))?-1:1); - case OT_TABLE: - case OT_USERDATA: - case OT_INSTANCE: - if(_delegable(o1)->_delegate) { - SQObjectPtr closure; - if(_delegable(o1)->GetMetaMethod(this, MT_CMP, closure)) { - Push(o1);Push(o2); - if(!CallMetaMethod(closure,MT_CMP,2,res)) return false; - } - break; - } - //continues through (no break needed) - default: - _RET_SUCCEED( _userpointer(o1) < _userpointer(o2)?-1:1 ); - } - if(type(res)!=OT_INTEGER) { Raise_CompareError(o1,o2); return false; } - _RET_SUCCEED(_integer(res)); - - } - else{ - if(sq_isnumeric(o1) && sq_isnumeric(o2)){ - if((t1==OT_INTEGER) && (t2==OT_FLOAT)) { - if( _integer(o1)==_float(o2) ) { _RET_SUCCEED(0); } - else if( _integer(o1)<_float(o2) ) { _RET_SUCCEED(-1); } - _RET_SUCCEED(1); - } - else{ - if( _float(o1)==_integer(o2) ) { _RET_SUCCEED(0); } - else if( _float(o1)<_integer(o2) ) { _RET_SUCCEED(-1); } - _RET_SUCCEED(1); - } - } - else if(t1==OT_NULL) {_RET_SUCCEED(-1);} - else if(t2==OT_NULL) {_RET_SUCCEED(1);} - else { Raise_CompareError(o1,o2); return false; } - - } - assert(0); - _RET_SUCCEED(0); //cannot happen -} - -bool SQVM::CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res) -{ - SQInteger r; - if(ObjCmp(o1,o2,r)) { - switch(op) { - case CMP_G: res = (r > 0); return true; - case CMP_GE: res = (r >= 0); return true; - case CMP_L: res = (r < 0); return true; - case CMP_LE: res = (r <= 0); return true; - case CMP_3W: res = r; return true; - } - assert(0); - } - return false; -} - -bool SQVM::ToString(const SQObjectPtr &o,SQObjectPtr &res) -{ - switch(type(o)) { - case OT_STRING: - res = o; - return true; - case OT_FLOAT: - scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_SC("%g"),_float(o)); - break; - case OT_INTEGER: - scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_PRINT_INT_FMT,_integer(o)); - break; - case OT_BOOL: - scsprintf(_sp(rsl(6)),_integer(o)?_SC("true"):_SC("false")); - break; - case OT_TABLE: - case OT_USERDATA: - case OT_INSTANCE: - if(_delegable(o)->_delegate) { - SQObjectPtr closure; - if(_delegable(o)->GetMetaMethod(this, MT_TOSTRING, closure)) { - Push(o); - if(CallMetaMethod(closure,MT_TOSTRING,1,res)) {; - if(type(res) == OT_STRING) - return true; - } - else { - return false; - } - } - } - default: - scsprintf(_sp(rsl(sizeof(void*)+20)),_SC("(%s : 0x%p)"),GetTypeName(o),(void*)_rawval(o)); - } - res = SQString::Create(_ss(this),_spval); - return true; -} - - -bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr &dest) -{ - SQObjectPtr a, b; - if(!ToString(str, a)) return false; - if(!ToString(obj, b)) return false; - SQInteger l = _string(a)->_len , ol = _string(b)->_len; - SQChar *s = _sp(rsl(l + ol + 1)); - memcpy(s, _stringval(a), rsl(l)); - memcpy(s + l, _stringval(b), rsl(ol)); - dest = SQString::Create(_ss(this), _spval, l + ol); - return true; -} - -bool SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest) -{ - if(is_delegable(obj1) && _delegable(obj1)->_delegate) { - SQObjectPtr closure; - if(_delegable(obj1)->GetMetaMethod(this, MT_TYPEOF, closure)) { - Push(obj1); - return CallMetaMethod(closure,MT_TYPEOF,1,dest); - } - } - dest = SQString::Create(_ss(this),GetTypeName(obj1)); - return true; -} - -bool SQVM::Init(SQVM *friendvm, SQInteger stacksize) -{ - _stack.resize(stacksize); - _alloccallsstacksize = 4; - _callstackdata.resize(_alloccallsstacksize); - _callsstacksize = 0; - _callsstack = &_callstackdata[0]; - _stackbase = 0; - _top = 0; - if(!friendvm) - _roottable = SQTable::Create(_ss(this), 0); - else { - _roottable = friendvm->_roottable; - _errorhandler = friendvm->_errorhandler; - _debughook = friendvm->_debughook; - _debughook_native = friendvm->_debughook_native; - _debughook_closure = friendvm->_debughook_closure; - } - - sq_base_register(this); - return true; -} - - -bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQInteger stackbase,bool tailcall) -{ - SQFunctionProto *func = closure->_function; - - SQInteger paramssize = func->_nparameters; - const SQInteger newtop = stackbase + func->_stacksize; - SQInteger nargs = args; - if(func->_varparams) - { - paramssize--; - if (nargs < paramssize) { - Raise_Error(_SC("wrong number of parameters")); - return false; - } - - //dumpstack(stackbase); - SQInteger nvargs = nargs - paramssize; - SQArray *arr = SQArray::Create(_ss(this),nvargs); - SQInteger pbase = stackbase+paramssize; - for(SQInteger n = 0; n < nvargs; n++) { - arr->_values[n] = _stack._vals[pbase]; - _stack._vals[pbase].Null(); - pbase++; - - } - _stack._vals[stackbase+paramssize] = arr; - //dumpstack(stackbase); - } - else if (paramssize != nargs) { - SQInteger ndef = func->_ndefaultparams; - SQInteger diff; - if(ndef && nargs < paramssize && (diff = paramssize - nargs) <= ndef) { - for(SQInteger n = ndef - diff; n < ndef; n++) { - _stack._vals[stackbase + (nargs++)] = closure->_defaultparams[n]; - } - } - else { - Raise_Error(_SC("wrong number of parameters")); - return false; - } - } - - if(closure->_env) { - _stack._vals[stackbase] = closure->_env->_obj; - } - - if(!EnterFrame(stackbase, newtop, tailcall)) return false; - - ci->_closure = closure; - ci->_literals = func->_literals; - ci->_ip = func->_instructions; - ci->_target = (SQInt32)target; - - if (_debughook) { - CallDebugHook(_SC('c')); - } - - if (closure->_function->_bgenerator) { - SQFunctionProto *f = closure->_function; - SQGenerator *gen = SQGenerator::Create(_ss(this), closure); - if(!gen->Yield(this,f->_stacksize)) - return false; - SQObjectPtr temp; - Return(1, target, temp); - STK(target) = gen; - } - - - return true; -} - -bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval) -{ - SQBool _isroot = ci->_root; - SQInteger callerbase = _stackbase - ci->_prevstkbase; - - if (_debughook) { - for(SQInteger i=0; i_ncalls; i++) { - CallDebugHook(_SC('r')); - } - } - - SQObjectPtr *dest; - if (_isroot) { - dest = &(retval); - } else if (ci->_target == -1) { - dest = NULL; - } else { - dest = &_stack._vals[callerbase + ci->_target]; - } - if (dest) { - if(_arg0 != 0xFF) { - *dest = _stack._vals[_stackbase+_arg1]; - } - else { - dest->Null(); - } - //*dest = (_arg0 != 0xFF) ? _stack._vals[_stackbase+_arg1] : _null_; - } - LeaveFrame(); - return _isroot ? true : false; -} - -#define _RET_ON_FAIL(exp) { if(!exp) return false; } - -bool SQVM::PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr) -{ - SQObjectPtr trg; - _RET_ON_FAIL(ARITH_OP( op , trg, a, incr)); - target = a; - a = trg; - return true; -} - -bool SQVM::DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix,SQInteger selfidx) -{ - SQObjectPtr tmp, tself = self, tkey = key; - if (!Get(tself, tkey, tmp, false, selfidx)) { return false; } - _RET_ON_FAIL(ARITH_OP( op , target, tmp, incr)) - if (!Set(tself, tkey, target,selfidx)) { return false; } - if (postfix) target = tmp; - return true; -} - -#define arg0 (_i_._arg0) -#define sarg0 ((SQInteger)*((signed char *)&_i_._arg0)) -#define arg1 (_i_._arg1) -#define sarg1 (*((SQInt32 *)&_i_._arg1)) -#define arg2 (_i_._arg2) -#define arg3 (_i_._arg3) -#define sarg3 ((SQInteger)*((signed char *)&_i_._arg3)) - -SQRESULT SQVM::Suspend() -{ - if (_suspended) - return sq_throwerror(this, _SC("cannot suspend an already suspended vm")); - if (_nnativecalls!=2) - return sq_throwerror(this, _SC("cannot suspend through native calls/metamethods")); - return SQ_SUSPEND_FLAG; -} - - -#define _FINISH(howmuchtojump) {jump = howmuchtojump; return true; } -bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr -&o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump) -{ - SQInteger nrefidx; - switch(type(o1)) { - case OT_TABLE: - if((nrefidx = _table(o1)->Next(false,o4, o2, o3)) == -1) _FINISH(exitpos); - o4 = (SQInteger)nrefidx; _FINISH(1); - case OT_ARRAY: - if((nrefidx = _array(o1)->Next(o4, o2, o3)) == -1) _FINISH(exitpos); - o4 = (SQInteger) nrefidx; _FINISH(1); - case OT_STRING: - if((nrefidx = _string(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos); - o4 = (SQInteger)nrefidx; _FINISH(1); - case OT_CLASS: - if((nrefidx = _class(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos); - o4 = (SQInteger)nrefidx; _FINISH(1); - case OT_USERDATA: - case OT_INSTANCE: - if(_delegable(o1)->_delegate) { - SQObjectPtr itr; - SQObjectPtr closure; - if(_delegable(o1)->GetMetaMethod(this, MT_NEXTI, closure)) { - Push(o1); - Push(o4); - if(CallMetaMethod(closure, MT_NEXTI, 2, itr)) { - o4 = o2 = itr; - if(type(itr) == OT_NULL) _FINISH(exitpos); - if(!Get(o1, itr, o3, false, DONT_FALL_BACK)) { - Raise_Error(_SC("_nexti returned an invalid idx")); // cloud be changed - return false; - } - _FINISH(1); - } - else { - return false; - } - } - Raise_Error(_SC("_nexti failed")); - return false; - } - break; - case OT_GENERATOR: - if(_generator(o1)->_state == SQGenerator::eDead) _FINISH(exitpos); - if(_generator(o1)->_state == SQGenerator::eSuspended) { - SQInteger idx = 0; - if(type(o4) == OT_INTEGER) { - idx = _integer(o4) + 1; - } - o2 = idx; - o4 = idx; - _generator(o1)->Resume(this, o3); - _FINISH(0); - } - default: - Raise_Error(_SC("cannot iterate %s"), GetTypeName(o1)); - } - return false; //cannot be hit(just to avoid warnings) -} - -#define COND_LITERAL (arg3!=0?ci->_literals[arg1]:STK(arg1)) - -#define SQ_THROW() { goto exception_trap; } - -#define _GUARD(exp) { if(!exp) { SQ_THROW();} } - -bool SQVM::CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func) -{ - SQInteger nouters; - SQClosure *closure = SQClosure::Create(_ss(this), func); - if((nouters = func->_noutervalues)) { - for(SQInteger i = 0; i_outervalues[i]; - switch(v._type){ - case otLOCAL: - FindOuter(closure->_outervalues[i], &STK(_integer(v._src))); - break; - case otOUTER: - closure->_outervalues[i] = _closure(ci->_closure)->_outervalues[_integer(v._src)]; - break; - } - } - } - SQInteger ndefparams; - if((ndefparams = func->_ndefaultparams)) { - for(SQInteger i = 0; i < ndefparams; i++) { - SQInteger spos = func->_defaultparams[i]; - closure->_defaultparams[i] = _stack._vals[_stackbase + spos]; - } - } - target = closure; - return true; - -} - - -bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes) -{ - SQClass *base = NULL; - SQObjectPtr attrs; - if(baseclass != -1) { - if(type(_stack._vals[_stackbase+baseclass]) != OT_CLASS) { Raise_Error(_SC("trying to inherit from a %s"),GetTypeName(_stack._vals[_stackbase+baseclass])); return false; } - base = _class(_stack._vals[_stackbase + baseclass]); - } - if(attributes != MAX_FUNC_STACKSIZE) { - attrs = _stack._vals[_stackbase+attributes]; - } - target = SQClass::Create(_ss(this),base); - if(type(_class(target)->_metamethods[MT_INHERITED]) != OT_NULL) { - int nparams = 2; - SQObjectPtr ret; - Push(target); Push(attrs); - Call(_class(target)->_metamethods[MT_INHERITED],nparams,_top - nparams, ret, false); - Pop(nparams); - } - _class(target)->_attributes = attrs; - return true; -} - -bool SQVM::IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res) -{ - if(type(o1) == type(o2)) { - res = (_rawval(o1) == _rawval(o2)); - } - else { - if(sq_isnumeric(o1) && sq_isnumeric(o2)) { - res = (tofloat(o1) == tofloat(o2)); - } - else { - res = false; - } - } - return true; -} - -bool SQVM::IsFalse(SQObjectPtr &o) -{ - if(((type(o) & SQOBJECT_CANBEFALSE) - && ( ((type(o) == OT_FLOAT) && (_float(o) == SQFloat(0.0))) )) -#if !defined(SQUSEDOUBLE) || (defined(SQUSEDOUBLE) && defined(_SQ64)) - || (_integer(o) == 0) ) //OT_NULL|OT_INTEGER|OT_BOOL -#else - || (((type(o) != OT_FLOAT) && (_integer(o) == 0))) ) //OT_NULL|OT_INTEGER|OT_BOOL -#endif - { - return true; - } - return false; -} - -bool SQVM::Execute(SQObjectPtr &closure, SQInteger nargs, SQInteger stackbase,SQObjectPtr &outres, SQBool raiseerror,ExecutionType et) -{ - if ((_nnativecalls + 1) > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; } - _nnativecalls++; - AutoDec ad(&_nnativecalls); - SQInteger traps = 0; - CallInfo *prevci = ci; - - switch(et) { - case ET_CALL: { - temp_reg = closure; - if(!StartCall(_closure(temp_reg), _top - nargs, nargs, stackbase, false)) { - //call the handler if there are no calls in the stack, if not relies on the previous node - if(ci == NULL) CallErrorHandler(_lasterror); - return false; - } - if(ci == prevci) { - outres = STK(_top-nargs); - return true; - } - ci->_root = SQTrue; - } - break; - case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, outres); ci->_root = SQTrue; traps += ci->_etraps; break; - case ET_RESUME_VM: - case ET_RESUME_THROW_VM: - traps = _suspended_traps; - ci->_root = _suspended_root; - _suspended = SQFalse; - if(et == ET_RESUME_THROW_VM) { SQ_THROW(); } - break; - } - -exception_restore: - // - { - for(;;) - { - const SQInstruction &_i_ = *ci->_ip++; - //dumpstack(_stackbase); - //scprintf("\n[%d] %s %d %d %d %d\n",ci->_ip-ci->_iv->_vals,g_InstrDesc[_i_.op].name,arg0,arg1,arg2,arg3); - switch(_i_.op) - { - case _OP_LINE: if (_debughook) CallDebugHook(_SC('l'),arg1); continue; - case _OP_LOAD: TARGET = ci->_literals[arg1]; continue; - case _OP_LOADINT: -#ifndef _SQ64 - TARGET = (SQInteger)arg1; continue; -#else - TARGET = (SQInteger)((SQUnsignedInteger32)arg1); continue; -#endif - case _OP_LOADFLOAT: TARGET = *((SQFloat *)&arg1); continue; - case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue; - case _OP_TAILCALL:{ - SQObjectPtr &t = STK(arg1); - if (type(t) == OT_CLOSURE - && (!_closure(t)->_function->_bgenerator)){ - SQObjectPtr clo = t; - if(_openouters) CloseOuters(&(_stack._vals[_stackbase])); - for (SQInteger i = 0; i < arg3; i++) STK(i) = STK(arg2 + i); - _GUARD(StartCall(_closure(clo), ci->_target, arg3, _stackbase, true)); - continue; - } - } - case _OP_CALL: { - SQObjectPtr clo = STK(arg1); - switch (type(clo)) { - case OT_CLOSURE: - _GUARD(StartCall(_closure(clo), sarg0, arg3, _stackbase+arg2, false)); - continue; - case OT_NATIVECLOSURE: { - bool suspend; - _GUARD(CallNative(_nativeclosure(clo), arg3, _stackbase+arg2, clo,suspend)); - if(suspend){ - _suspended = SQTrue; - _suspended_target = sarg0; - _suspended_root = ci->_root; - _suspended_traps = traps; - outres = clo; - return true; - } - if(sarg0 != -1) { - STK(arg0) = clo; - } - } - continue; - case OT_CLASS:{ - SQObjectPtr inst; - _GUARD(CreateClassInstance(_class(clo),inst,clo)); - if(sarg0 != -1) { - STK(arg0) = inst; - } - SQInteger stkbase; - switch(type(clo)) { - case OT_CLOSURE: - stkbase = _stackbase+arg2; - _stack._vals[stkbase] = inst; - _GUARD(StartCall(_closure(clo), -1, arg3, stkbase, false)); - break; - case OT_NATIVECLOSURE: - bool suspend; - stkbase = _stackbase+arg2; - _stack._vals[stkbase] = inst; - _GUARD(CallNative(_nativeclosure(clo), arg3, stkbase, clo,suspend)); - break; - default: break; //shutup GCC 4.x - } - } - break; - case OT_TABLE: - case OT_USERDATA: - case OT_INSTANCE:{ - SQObjectPtr closure; - if(_delegable(clo)->_delegate && _delegable(clo)->GetMetaMethod(this,MT_CALL,closure)) { - Push(clo); - for (SQInteger i = 0; i < arg3; i++) Push(STK(arg2 + i)); - if(!CallMetaMethod(closure, MT_CALL, arg3+1, clo)) SQ_THROW(); - if(sarg0 != -1) { - STK(arg0) = clo; - } - break; - } - - //Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo)); - //SQ_THROW(); - } - default: - Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo)); - SQ_THROW(); - } - } - continue; - case _OP_PREPCALL: - case _OP_PREPCALLK: { - SQObjectPtr &key = _i_.op == _OP_PREPCALLK?(ci->_literals)[arg1]:STK(arg1); - SQObjectPtr &o = STK(arg2); - if (!Get(o, key, temp_reg,false,arg2)) { - SQ_THROW(); - } - STK(arg3) = o; - _Swap(TARGET,temp_reg);//TARGET = temp_reg; - } - continue; - case _OP_GETK: - if (!Get(STK(arg2), ci->_literals[arg1], temp_reg, false,arg2)) { SQ_THROW();} - _Swap(TARGET,temp_reg);//TARGET = temp_reg; - continue; - case _OP_MOVE: TARGET = STK(arg1); continue; - case _OP_NEWSLOT: - _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),false)); - if(arg0 != 0xFF) TARGET = STK(arg3); - continue; - case _OP_DELETE: _GUARD(DeleteSlot(STK(arg1), STK(arg2), TARGET)); continue; - case _OP_SET: - if (!Set(STK(arg1), STK(arg2), STK(arg3),arg1)) { SQ_THROW(); } - if (arg0 != 0xFF) TARGET = STK(arg3); - continue; - case _OP_GET: - if (!Get(STK(arg1), STK(arg2), temp_reg, false,arg1)) { SQ_THROW(); } - _Swap(TARGET,temp_reg);//TARGET = temp_reg; - continue; - case _OP_EQ:{ - bool res; - if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); } - TARGET = res?true:false; - }continue; - case _OP_NE:{ - bool res; - if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); } - TARGET = (!res)?true:false; - } continue; - case _OP_ADD: _ARITH_(+,TARGET,STK(arg2),STK(arg1)); continue; - case _OP_SUB: _ARITH_(-,TARGET,STK(arg2),STK(arg1)); continue; - case _OP_MUL: _ARITH_(*,TARGET,STK(arg2),STK(arg1)); continue; - case _OP_DIV: _ARITH_NOZERO(/,TARGET,STK(arg2),STK(arg1),_SC("division by zero")); continue; - case _OP_MOD: ARITH_OP('%',TARGET,STK(arg2),STK(arg1)); continue; - case _OP_BITW: _GUARD(BW_OP( arg3,TARGET,STK(arg2),STK(arg1))); continue; - case _OP_RETURN: - if((ci)->_generator) { - (ci)->_generator->Kill(); - } - if(Return(arg0, arg1, temp_reg)){ - assert(traps==0); - //outres = temp_reg; - _Swap(outres,temp_reg); - return true; - } - continue; - case _OP_LOADNULLS:{ for(SQInt32 n=0; n < arg1; n++) STK(arg0+n).Null(); }continue; - case _OP_LOADROOT: TARGET = _roottable; continue; - case _OP_LOADBOOL: TARGET = arg1?true:false; continue; - case _OP_DMOVE: STK(arg0) = STK(arg1); STK(arg2) = STK(arg3); continue; - case _OP_JMP: ci->_ip += (sarg1); continue; - //case _OP_JNZ: if(!IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue; - case _OP_JCMP: - _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg0),temp_reg)); - if(IsFalse(temp_reg)) ci->_ip+=(sarg1); - continue; - case _OP_JZ: if(IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue; - case _OP_GETOUTER: { - SQClosure *cur_cls = _closure(ci->_closure); - SQOuter *otr = _outer(cur_cls->_outervalues[arg1]); - TARGET = *(otr->_valptr); - } - continue; - case _OP_SETOUTER: { - SQClosure *cur_cls = _closure(ci->_closure); - SQOuter *otr = _outer(cur_cls->_outervalues[arg1]); - *(otr->_valptr) = STK(arg2); - if(arg0 != 0xFF) { - TARGET = STK(arg2); - } - } - continue; - case _OP_NEWOBJ: - switch(arg3) { - case NOT_TABLE: TARGET = SQTable::Create(_ss(this), arg1); continue; - case NOT_ARRAY: TARGET = SQArray::Create(_ss(this), 0); _array(TARGET)->Reserve(arg1); continue; - case NOT_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue; - default: assert(0); continue; - } - case _OP_APPENDARRAY: - { - SQObject val; - val._unVal.raw = 0; - switch(arg2) { - case AAT_STACK: - val = STK(arg1); break; - case AAT_LITERAL: - val = ci->_literals[arg1]; break; - case AAT_INT: - val._type = OT_INTEGER; -#ifndef _SQ64 - val._unVal.nInteger = (SQInteger)arg1; -#else - val._unVal.nInteger = (SQInteger)((SQUnsignedInteger32)arg1); -#endif - break; - case AAT_FLOAT: - val._type = OT_FLOAT; - val._unVal.fFloat = *((SQFloat *)&arg1); - break; - case AAT_BOOL: - val._type = OT_BOOL; - val._unVal.nInteger = arg1; - break; - default: assert(0); break; - - } - _array(STK(arg0))->Append(val); continue; - } - case _OP_COMPARITH: { - SQInteger selfidx = (((SQUnsignedInteger)arg1&0xFFFF0000)>>16); - _GUARD(DerefInc(arg3, TARGET, STK(selfidx), STK(arg2), STK(arg1&0x0000FFFF), false, selfidx)); - } - continue; - case _OP_INC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, false, arg1));} continue; - case _OP_INCL: { - SQObjectPtr &a = STK(arg1); - if(type(a) == OT_INTEGER) { - a._unVal.nInteger = _integer(a) + sarg3; - } - else { - SQObjectPtr o(sarg3); //_GUARD(LOCAL_INC('+',TARGET, STK(arg1), o)); - _ARITH_(+,a,a,o); - } - } continue; - case _OP_PINC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, true, arg1));} continue; - case _OP_PINCL: { - SQObjectPtr &a = STK(arg1); - if(type(a) == OT_INTEGER) { - TARGET = a; - a._unVal.nInteger = _integer(a) + sarg3; - } - else { - SQObjectPtr o(sarg3); _GUARD(PLOCAL_INC('+',TARGET, STK(arg1), o)); - } - - } continue; - case _OP_CMP: _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg1),TARGET)) continue; - case _OP_EXISTS: TARGET = Get(STK(arg1), STK(arg2), temp_reg, true,DONT_FALL_BACK)?true:false;continue; - case _OP_INSTANCEOF: - if(type(STK(arg1)) != OT_CLASS) - {Raise_Error(_SC("cannot apply instanceof between a %s and a %s"),GetTypeName(STK(arg1)),GetTypeName(STK(arg2))); SQ_THROW();} - TARGET = (type(STK(arg2)) == OT_INSTANCE) ? (_instance(STK(arg2))->InstanceOf(_class(STK(arg1)))?true:false) : false; - continue; - case _OP_AND: - if(IsFalse(STK(arg2))) { - TARGET = STK(arg2); - ci->_ip += (sarg1); - } - continue; - case _OP_OR: - if(!IsFalse(STK(arg2))) { - TARGET = STK(arg2); - ci->_ip += (sarg1); - } - continue; - case _OP_NEG: _GUARD(NEG_OP(TARGET,STK(arg1))); continue; - case _OP_NOT: TARGET = IsFalse(STK(arg1)); continue; - case _OP_BWNOT: - if(type(STK(arg1)) == OT_INTEGER) { - SQInteger t = _integer(STK(arg1)); - TARGET = SQInteger(~t); - continue; - } - Raise_Error(_SC("attempt to perform a bitwise op on a %s"), GetTypeName(STK(arg1))); - SQ_THROW(); - case _OP_CLOSURE: { - SQClosure *c = ci->_closure._unVal.pClosure; - SQFunctionProto *fp = c->_function; - if(!CLOSURE_OP(TARGET,fp->_functions[arg1]._unVal.pFunctionProto)) { SQ_THROW(); } - continue; - } - case _OP_YIELD:{ - if(ci->_generator) { - if(sarg1 != MAX_FUNC_STACKSIZE) temp_reg = STK(arg1); - _GUARD(ci->_generator->Yield(this,arg2)); - traps -= ci->_etraps; - if(sarg1 != MAX_FUNC_STACKSIZE) _Swap(STK(arg1),temp_reg);//STK(arg1) = temp_reg; - } - else { Raise_Error(_SC("trying to yield a '%s',only genenerator can be yielded"), GetTypeName(ci->_generator)); SQ_THROW();} - if(Return(arg0, arg1, temp_reg)){ - assert(traps == 0); - outres = temp_reg; - return true; - } - - } - continue; - case _OP_RESUME: - if(type(STK(arg1)) != OT_GENERATOR){ Raise_Error(_SC("trying to resume a '%s',only genenerator can be resumed"), GetTypeName(STK(arg1))); SQ_THROW();} - _GUARD(_generator(STK(arg1))->Resume(this, TARGET)); - traps += ci->_etraps; - continue; - case _OP_FOREACH:{ int tojump; - _GUARD(FOREACH_OP(STK(arg0),STK(arg2),STK(arg2+1),STK(arg2+2),arg2,sarg1,tojump)); - ci->_ip += tojump; } - continue; - case _OP_POSTFOREACH: - assert(type(STK(arg0)) == OT_GENERATOR); - if(_generator(STK(arg0))->_state == SQGenerator::eDead) - ci->_ip += (sarg1 - 1); - continue; - case _OP_CLONE: _GUARD(Clone(STK(arg1), TARGET)); continue; - case _OP_TYPEOF: _GUARD(TypeOf(STK(arg1), TARGET)) continue; - case _OP_PUSHTRAP:{ - SQInstruction *_iv = _closure(ci->_closure)->_function->_instructions; - _etraps.push_back(SQExceptionTrap(_top,_stackbase, &_iv[(ci->_ip-_iv)+arg1], arg0)); traps++; - ci->_etraps++; - } - continue; - case _OP_POPTRAP: { - for(SQInteger i = 0; i < arg0; i++) { - _etraps.pop_back(); traps--; - ci->_etraps--; - } - } - continue; - case _OP_THROW: Raise_Error(TARGET); SQ_THROW(); continue; - case _OP_NEWSLOTA: { - bool bstatic = (arg0&NEW_SLOT_STATIC_FLAG)?true:false; - if(type(STK(arg1)) == OT_CLASS) { - if(type(_class(STK(arg1))->_metamethods[MT_NEWMEMBER]) != OT_NULL ) { - Push(STK(arg1)); Push(STK(arg2)); Push(STK(arg3)); - Push((arg0&NEW_SLOT_ATTRIBUTES_FLAG) ? STK(arg2-1) : SQObjectPtr()); - Push(bstatic); - int nparams = 5; - if(Call(_class(STK(arg1))->_metamethods[MT_NEWMEMBER], nparams, _top - nparams, temp_reg,SQFalse)) { - Pop(nparams); - continue; - } - else { - SQ_THROW(); - } - } - } - _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),bstatic)); - if((arg0&NEW_SLOT_ATTRIBUTES_FLAG)) { - _class(STK(arg1))->SetAttributes(STK(arg2),STK(arg2-1)); - } - } - continue; - case _OP_GETBASE:{ - SQClosure *clo = _closure(ci->_closure); - if(clo->_base) { - TARGET = clo->_base; - } - else { - TARGET.Null(); - } - continue; - } - case _OP_CLOSE: - if(_openouters) CloseOuters(&(STK(arg1))); - continue; - } - - } - } -exception_trap: - { - SQObjectPtr currerror = _lasterror; -// dumpstack(_stackbase); -// SQInteger n = 0; - SQInteger last_top = _top; - - if(_ss(this)->_notifyallexceptions || (!traps && raiseerror)) CallErrorHandler(currerror); - - while( ci ) { - if(ci->_etraps > 0) { - SQExceptionTrap &et = _etraps.top(); - ci->_ip = et._ip; - _top = et._stacksize; - _stackbase = et._stackbase; - _stack._vals[_stackbase + et._extarget] = currerror; - _etraps.pop_back(); traps--; ci->_etraps--; - while(last_top >= _top) _stack._vals[last_top--].Null(); - goto exception_restore; - } - else if (_debughook) { - //notify debugger of a "return" - //even if it really an exception unwinding the stack - for(SQInteger i = 0; i < ci->_ncalls; i++) { - CallDebugHook(_SC('r')); - } - } - if(ci->_generator) ci->_generator->Kill(); - bool mustbreak = ci && ci->_root; - LeaveFrame(); - if(mustbreak) break; - } - - _lasterror = currerror; - return false; - } - assert(0); -} - -bool SQVM::CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor) -{ - inst = theclass->CreateInstance(); - if(!theclass->GetConstructor(constructor)) { - constructor.Null(); - } - return true; -} - -void SQVM::CallErrorHandler(SQObjectPtr &error) -{ - if(type(_errorhandler) != OT_NULL) { - SQObjectPtr out; - Push(_roottable); Push(error); - Call(_errorhandler, 2, _top-2, out,SQFalse); - Pop(2); - } -} - - -void SQVM::CallDebugHook(SQInteger type,SQInteger forcedline) -{ - _debughook = false; - SQFunctionProto *func=_closure(ci->_closure)->_function; - if(_debughook_native) { - const SQChar *src = type(func->_sourcename) == OT_STRING?_stringval(func->_sourcename):NULL; - const SQChar *fname = type(func->_name) == OT_STRING?_stringval(func->_name):NULL; - SQInteger line = forcedline?forcedline:func->GetLine(ci->_ip); - _debughook_native(this,type,src,line,fname); - } - else { - SQObjectPtr temp_reg; - SQInteger nparams=5; - Push(_roottable); Push(type); Push(func->_sourcename); Push(forcedline?forcedline:func->GetLine(ci->_ip)); Push(func->_name); - Call(_debughook_closure,nparams,_top-nparams,temp_reg,SQFalse); - Pop(nparams); - } - _debughook = true; -} - -bool SQVM::CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newbase, SQObjectPtr &retval, bool &suspend) -{ - SQInteger nparamscheck = nclosure->_nparamscheck; - SQInteger newtop = newbase + nargs + nclosure->_noutervalues; - - if (_nnativecalls + 1 > MAX_NATIVE_CALLS) { - Raise_Error(_SC("Native stack overflow")); - return false; - } - - if(nparamscheck && (((nparamscheck > 0) && (nparamscheck != nargs)) || - ((nparamscheck < 0) && (nargs < (-nparamscheck))))) - { - Raise_Error(_SC("wrong number of parameters")); - return false; - } - - SQInteger tcs; - SQIntVec &tc = nclosure->_typecheck; - if((tcs = tc.size())) { - for(SQInteger i = 0; i < nargs && i < tcs; i++) { - if((tc._vals[i] != -1) && !(type(_stack._vals[newbase+i]) & tc._vals[i])) { - Raise_ParamTypeError(i,tc._vals[i],type(_stack._vals[newbase+i])); - return false; - } - } - } - - if(!EnterFrame(newbase, newtop, false)) return false; - ci->_closure = nclosure; - - SQInteger outers = nclosure->_noutervalues; - for (SQInteger i = 0; i < outers; i++) { - _stack._vals[newbase+nargs+i] = nclosure->_outervalues[i]; - } - if(nclosure->_env) { - _stack._vals[newbase] = nclosure->_env->_obj; - } - - _nnativecalls++; - SQInteger ret = (nclosure->_function)(this); - _nnativecalls--; - - suspend = false; - if (ret == SQ_SUSPEND_FLAG) { - suspend = true; - } - else if (ret < 0) { - LeaveFrame(); - Raise_Error(_lasterror); - return false; - } - if(ret) { - retval = _stack._vals[_top-1]; - } - else { - retval.Null(); - } - //retval = ret ? _stack._vals[_top-1] : _null_; - LeaveFrame(); - return true; -} - -#define FALLBACK_OK 0 -#define FALLBACK_NO_MATCH 1 -#define FALLBACK_ERROR 2 - -bool SQVM::Get(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw, SQInteger selfidx) -{ - switch(type(self)){ - case OT_TABLE: - if(_table(self)->Get(key,dest))return true; - break; - case OT_ARRAY: - if(sq_isnumeric(key)) { if(_array(self)->Get(tointeger(key),dest)) { return true; } Raise_IdxError(key); return false; } - break; - case OT_INSTANCE: - if(_instance(self)->Get(key,dest)) return true; - break; - case OT_CLASS: - if(_class(self)->Get(key,dest)) return true; - break; - case OT_STRING: - if(sq_isnumeric(key)){ - SQInteger n = tointeger(key); - if(abs((int)n) < _string(self)->_len) { - if(n < 0) n = _string(self)->_len - n; - dest = SQInteger(_stringval(self)[n]); - return true; - } - Raise_IdxError(key); - return false; - } - break; - default:break; //shut up compiler - } - if(!raw) { - switch(FallBackGet(self,key,dest)) { - case FALLBACK_OK: return true; //okie - case FALLBACK_NO_MATCH: break; //keep falling back - case FALLBACK_ERROR: return false; // the metamethod failed - } - if(InvokeDefaultDelegate(self,key,dest)) { - return true; - } - } -//#ifdef ROOT_FALLBACK - if(selfidx == 0) { - if(_table(_roottable)->Get(key,dest)) return true; - } -//#endif - Raise_IdxError(key); - return false; -} - -bool SQVM::InvokeDefaultDelegate(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest) -{ - SQTable *ddel = NULL; - switch(type(self)) { - case OT_CLASS: ddel = _class_ddel; break; - case OT_TABLE: ddel = _table_ddel; break; - case OT_ARRAY: ddel = _array_ddel; break; - case OT_STRING: ddel = _string_ddel; break; - case OT_INSTANCE: ddel = _instance_ddel; break; - case OT_INTEGER:case OT_FLOAT:case OT_BOOL: ddel = _number_ddel; break; - case OT_GENERATOR: ddel = _generator_ddel; break; - case OT_CLOSURE: case OT_NATIVECLOSURE: ddel = _closure_ddel; break; - case OT_THREAD: ddel = _thread_ddel; break; - case OT_WEAKREF: ddel = _weakref_ddel; break; - default: return false; - } - return ddel->Get(key,dest); -} - - -SQInteger SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest) -{ - switch(type(self)){ - case OT_TABLE: - case OT_USERDATA: - //delegation - if(_delegable(self)->_delegate) { - if(Get(SQObjectPtr(_delegable(self)->_delegate),key,dest,false,DONT_FALL_BACK)) return FALLBACK_OK; - } - else { - return FALLBACK_NO_MATCH; - } - //go through - case OT_INSTANCE: { - SQObjectPtr closure; - if(_delegable(self)->GetMetaMethod(this, MT_GET, closure)) { - Push(self);Push(key); - _nmetamethodscall++; - AutoDec ad(&_nmetamethodscall); - if(Call(closure, 2, _top - 2, dest, SQFalse)) { - Pop(2); - return FALLBACK_OK; - } - else { - if(type(_lasterror) != OT_NULL) { //NULL means "clean failure" (not found) - //error - Pop(2); - return FALLBACK_ERROR; - } - } - } - } - break; - default: break;//shutup GCC 4.x - } - // no metamethod or no fallback type - return FALLBACK_NO_MATCH; -} - -bool SQVM::Set(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,SQInteger selfidx) -{ - switch(type(self)){ - case OT_TABLE: - if(_table(self)->Set(key,val)) return true; - break; - case OT_INSTANCE: - if(_instance(self)->Set(key,val)) return true; - break; - case OT_ARRAY: - if(!sq_isnumeric(key)) { Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); return false; } - if(!_array(self)->Set(tointeger(key),val)) { - Raise_IdxError(key); - return false; - } - return true; - default: - Raise_Error(_SC("trying to set '%s'"),GetTypeName(self)); - return false; - } - - switch(FallBackSet(self,key,val)) { - case FALLBACK_OK: return true; //okie - case FALLBACK_NO_MATCH: break; //keep falling back - case FALLBACK_ERROR: return false; // the metamethod failed - } - if(selfidx == 0) { - if(_table(_roottable)->Set(key,val)) - return true; - } - Raise_IdxError(key); - return false; -} - -SQInteger SQVM::FallBackSet(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val) -{ - switch(type(self)) { - case OT_TABLE: - if(_table(self)->_delegate) { - if(Set(_table(self)->_delegate,key,val,DONT_FALL_BACK)) return FALLBACK_OK; - } - //keps on going - case OT_INSTANCE: - case OT_USERDATA:{ - SQObjectPtr closure; - SQObjectPtr t; - if(_delegable(self)->GetMetaMethod(this, MT_SET, closure)) { - Push(self);Push(key);Push(val); - _nmetamethodscall++; - AutoDec ad(&_nmetamethodscall); - if(Call(closure, 3, _top - 3, t, SQFalse)) { - Pop(3); - return FALLBACK_OK; - } - else { - if(type(_lasterror) != OT_NULL) { //NULL means "clean failure" (not found) - //error - Pop(3); - return FALLBACK_ERROR; - } - } - } - } - break; - default: break;//shutup GCC 4.x - } - // no metamethod or no fallback type - return FALLBACK_NO_MATCH; -} - -bool SQVM::Clone(const SQObjectPtr &self,SQObjectPtr &target) -{ - SQObjectPtr temp_reg; - SQObjectPtr newobj; - switch(type(self)){ - case OT_TABLE: - newobj = _table(self)->Clone(); - goto cloned_mt; - case OT_INSTANCE: { - newobj = _instance(self)->Clone(_ss(this)); -cloned_mt: - SQObjectPtr closure; - if(_delegable(newobj)->_delegate && _delegable(newobj)->GetMetaMethod(this,MT_CLONED,closure)) { - Push(newobj); - Push(self); - if(!CallMetaMethod(closure,MT_CLONED,2,temp_reg)) - return false; - } - } - target = newobj; - return true; - case OT_ARRAY: - target = _array(self)->Clone(); - return true; - default: - Raise_Error(_SC("cloning a %s"), GetTypeName(self)); - return false; - } -} - -bool SQVM::NewSlot(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic) -{ - if(type(key) == OT_NULL) { Raise_Error(_SC("null cannot be used as index")); return false; } - switch(type(self)) { - case OT_TABLE: { - bool rawcall = true; - if(_table(self)->_delegate) { - SQObjectPtr res; - if(!_table(self)->Get(key,res)) { - SQObjectPtr closure; - if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_NEWSLOT,closure)) { - Push(self);Push(key);Push(val); - if(!CallMetaMethod(closure,MT_NEWSLOT,3,res)) { - return false; - } - rawcall = false; - } - else { - rawcall = true; - } - } - } - if(rawcall) _table(self)->NewSlot(key,val); //cannot fail - - break;} - case OT_INSTANCE: { - SQObjectPtr res; - SQObjectPtr closure; - if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_NEWSLOT,closure)) { - Push(self);Push(key);Push(val); - if(!CallMetaMethod(closure,MT_NEWSLOT,3,res)) { - return false; - } - break; - } - Raise_Error(_SC("class instances do not support the new slot operator")); - return false; - break;} - case OT_CLASS: - if(!_class(self)->NewSlot(_ss(this),key,val,bstatic)) { - if(_class(self)->_locked) { - Raise_Error(_SC("trying to modify a class that has already been instantiated")); - return false; - } - else { - SQObjectPtr oval = PrintObjVal(key); - Raise_Error(_SC("the property '%s' already exists"),_stringval(oval)); - return false; - } - } - break; - default: - Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); - return false; - break; - } - return true; -} - - - -bool SQVM::DeleteSlot(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &res) -{ - switch(type(self)) { - case OT_TABLE: - case OT_INSTANCE: - case OT_USERDATA: { - SQObjectPtr t; - //bool handled = false; - SQObjectPtr closure; - if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_DELSLOT,closure)) { - Push(self);Push(key); - return CallMetaMethod(closure,MT_DELSLOT,2,res); - } - else { - if(type(self) == OT_TABLE) { - if(_table(self)->Get(key,t)) { - _table(self)->Remove(key); - } - else { - Raise_IdxError((SQObject &)key); - return false; - } - } - else { - Raise_Error(_SC("cannot delete a slot from %s"),GetTypeName(self)); - return false; - } - } - res = t; - } - break; - default: - Raise_Error(_SC("attempt to delete a slot from a %s"),GetTypeName(self)); - return false; - } - return true; -} - -bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObjectPtr &outres,SQBool raiseerror) -{ -#ifdef _DEBUG -SQInteger prevstackbase = _stackbase; -#endif - switch(type(closure)) { - case OT_CLOSURE: - return Execute(closure, nparams, stackbase, outres, raiseerror); - break; - case OT_NATIVECLOSURE:{ - bool suspend; - return CallNative(_nativeclosure(closure), nparams, stackbase, outres,suspend); - - } - break; - case OT_CLASS: { - SQObjectPtr constr; - SQObjectPtr temp; - CreateClassInstance(_class(closure),outres,constr); - if(type(constr) != OT_NULL) { - _stack[stackbase] = outres; - return Call(constr,nparams,stackbase,temp,raiseerror); - } - return true; - } - break; - default: - return false; - } -#ifdef _DEBUG - if(!_suspended) { - assert(_stackbase == prevstackbase); - } -#endif - return true; -} - -bool SQVM::CallMetaMethod(SQObjectPtr &closure,SQMetaMethod mm,SQInteger nparams,SQObjectPtr &outres) -{ - //SQObjectPtr closure; - - _nmetamethodscall++; - if(Call(closure, nparams, _top - nparams, outres, SQFalse)) { - _nmetamethodscall--; - Pop(nparams); - return true; - } - _nmetamethodscall--; - //} - Pop(nparams); - return false; -} - -void SQVM::FindOuter(SQObjectPtr &target, SQObjectPtr *stackindex) -{ - SQOuter **pp = &_openouters; - SQOuter *p; - SQOuter *otr; - - while ((p = *pp) != NULL && p->_valptr >= stackindex) { - if (p->_valptr == stackindex) { - target = SQObjectPtr(p); - return; - } - pp = &p->_next; - } - otr = SQOuter::Create(_ss(this), stackindex); - otr->_next = *pp; - otr->_idx = (stackindex - _stack._vals); - __ObjAddRef(otr); - *pp = otr; - target = SQObjectPtr(otr); -} - -bool SQVM::EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall) -{ - if( !tailcall ) { - if( _callsstacksize == _alloccallsstacksize ) { - GrowCallStack(); - } - ci = &_callsstack[_callsstacksize++]; - ci->_prevstkbase = (SQInt32)(newbase - _stackbase); - ci->_prevtop = (SQInt32)(_top - _stackbase); - ci->_etraps = 0; - ci->_ncalls = 1; - ci->_generator = NULL; - ci->_root = SQFalse; - } - else { - ci->_ncalls++; - } - - _stackbase = newbase; - _top = newtop; - if(newtop + MIN_STACK_OVERHEAD > (SQInteger)_stack.size()) { - if(_nmetamethodscall) { - Raise_Error(_SC("stack overflow, cannot resize stack while in a metamethod")); - return false; - } - _stack.resize(_stack.size() + (MIN_STACK_OVERHEAD << 2)); - RelocateOuters(); - } - return true; -} - -void SQVM::LeaveFrame() { - SQInteger last_top = _top; - SQInteger last_stackbase = _stackbase; - SQInteger css = --_callsstacksize; - - /* First clean out the call stack frame */ - ci->_closure.Null(); - _stackbase -= ci->_prevstkbase; - _top = _stackbase + ci->_prevtop; - ci = (css) ? &_callsstack[css-1] : NULL; - - if(_openouters) CloseOuters(&(_stack._vals[last_stackbase])); - while (last_top >= _top) { - _stack._vals[last_top--].Null(); - } -} - -void SQVM::RelocateOuters() -{ - SQOuter *p = _openouters; - while (p) { - p->_valptr = _stack._vals + p->_idx; - p = p->_next; - } -} - -void SQVM::CloseOuters(SQObjectPtr *stackindex) { - SQOuter *p; - while ((p = _openouters) != NULL && p->_valptr >= stackindex) { - p->_value = *(p->_valptr); - p->_valptr = &p->_value; - _openouters = p->_next; - __ObjRelease(p); - } -} - -void SQVM::Remove(SQInteger n) { - n = (n >= 0)?n + _stackbase - 1:_top + n; - for(SQInteger i = n; i < _top; i++){ - _stack[i] = _stack[i+1]; - } - _stack[_top].Null(); - _top--; -} - -void SQVM::Pop() { - _stack[--_top].Null(); -} - -void SQVM::Pop(SQInteger n) { - for(SQInteger i = 0; i < n; i++){ - _stack[--_top].Null(); - } -} - -void SQVM::PushNull() { _stack[_top++].Null(); } -void SQVM::Push(const SQObjectPtr &o) { _stack[_top++] = o; } -SQObjectPtr &SQVM::Top() { return _stack[_top-1]; } -SQObjectPtr &SQVM::PopGet() { return _stack[--_top]; } -SQObjectPtr &SQVM::GetUp(SQInteger n) { return _stack[_top+n]; } -SQObjectPtr &SQVM::GetAt(SQInteger n) { return _stack[n]; } - -#ifdef _DEBUG_DUMP -void SQVM::dumpstack(SQInteger stackbase,bool dumpall) -{ - SQInteger size=dumpall?_stack.size():_top; - SQInteger n=0; - scprintf(_SC("\n>>>>stack dump<<<<\n")); - CallInfo &ci=_callsstack[_callsstacksize-1]; - scprintf(_SC("IP: %p\n"),ci._ip); - scprintf(_SC("prev stack base: %d\n"),ci._prevstkbase); - scprintf(_SC("prev top: %d\n"),ci._prevtop); - for(SQInteger i=0;i"));else scprintf(_SC(" ")); - scprintf(_SC("[%d]:"),n); - switch(type(obj)){ - case OT_FLOAT: scprintf(_SC("FLOAT %.3f"),_float(obj));break; - case OT_INTEGER: scprintf(_SC("INTEGER %d"),_integer(obj));break; - case OT_BOOL: scprintf(_SC("BOOL %s"),_integer(obj)?"true":"false");break; - case OT_STRING: scprintf(_SC("STRING %s"),_stringval(obj));break; - case OT_NULL: scprintf(_SC("NULL")); break; - case OT_TABLE: scprintf(_SC("TABLE %p[%p]"),_table(obj),_table(obj)->_delegate);break; - case OT_ARRAY: scprintf(_SC("ARRAY %p"),_array(obj));break; - case OT_CLOSURE: scprintf(_SC("CLOSURE [%p]"),_closure(obj));break; - case OT_NATIVECLOSURE: scprintf(_SC("NATIVECLOSURE"));break; - case OT_USERDATA: scprintf(_SC("USERDATA %p[%p]"),_userdataval(obj),_userdata(obj)->_delegate);break; - case OT_GENERATOR: scprintf(_SC("GENERATOR %p"),_generator(obj));break; - case OT_THREAD: scprintf(_SC("THREAD [%p]"),_thread(obj));break; - case OT_USERPOINTER: scprintf(_SC("USERPOINTER %p"),_userpointer(obj));break; - case OT_CLASS: scprintf(_SC("CLASS %p"),_class(obj));break; - case OT_INSTANCE: scprintf(_SC("INSTANCE %p"),_instance(obj));break; - case OT_WEAKREF: scprintf(_SC("WEAKERF %p"),_weakref(obj));break; - default: - assert(0); - break; - }; - scprintf(_SC("\n")); - ++n; - } -} - - - -#endif +/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include +#include +#include "sqopcodes.h" +#include "sqvm.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "sqstring.h" +#include "sqtable.h" +#include "squserdata.h" +#include "sqarray.h" +#include "sqclass.h" + +#define TOP() (_stack._vals[_top-1]) + +bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2) +{ + SQInteger res; + if((type(o1)|type(o2)) == OT_INTEGER) + { + SQInteger i1 = _integer(o1), i2 = _integer(o2); + switch(op) { + case BW_AND: res = i1 & i2; break; + case BW_OR: res = i1 | i2; break; + case BW_XOR: res = i1 ^ i2; break; + case BW_SHIFTL: res = i1 << i2; break; + case BW_SHIFTR: res = i1 >> i2; break; + case BW_USHIFTR:res = (SQInteger)(*((SQUnsignedInteger*)&i1) >> i2); break; + default: { Raise_Error(_SC("internal vm error bitwise op failed")); return false; } + } + } + else { Raise_Error(_SC("bitwise op between '%s' and '%s'"),GetTypeName(o1),GetTypeName(o2)); return false;} + trg = res; + return true; +} + +#define _ARITH_(op,trg,o1,o2) \ +{ \ + SQInteger tmask = type(o1)|type(o2); \ + switch(tmask) { \ + case OT_INTEGER: trg = _integer(o1) op _integer(o2);break; \ + case (OT_FLOAT|OT_INTEGER): \ + case (OT_FLOAT): trg = tofloat(o1) op tofloat(o2); break;\ + default: _GUARD(ARITH_OP((#op)[0],trg,o1,o2)); break;\ + } \ +} + +#define _ARITH_NOZERO(op,trg,o1,o2,err) \ +{ \ + SQInteger tmask = type(o1)|type(o2); \ + switch(tmask) { \ + case OT_INTEGER: { SQInteger i2 = _integer(o2); if(i2 == 0) { Raise_Error(err); SQ_THROW(); } trg = _integer(o1) op i2; } break;\ + case (OT_FLOAT|OT_INTEGER): \ + case (OT_FLOAT): trg = tofloat(o1) op tofloat(o2); break;\ + default: _GUARD(ARITH_OP((#op)[0],trg,o1,o2)); break;\ + } \ +} + +bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2) +{ + SQInteger tmask = type(o1)|type(o2); + switch(tmask) { + case OT_INTEGER:{ + SQInteger res, i1 = _integer(o1), i2 = _integer(o2); + switch(op) { + case '+': res = i1 + i2; break; + case '-': res = i1 - i2; break; + case '/': if(i2 == 0) { Raise_Error(_SC("division by zero")); return false; } + res = i1 / i2; + break; + case '*': res = i1 * i2; break; + case '%': if(i2 == 0) { Raise_Error(_SC("modulo by zero")); return false; } + res = i1 % i2; + break; + default: res = 0xDEADBEEF; + } + trg = res; } + break; + case (OT_FLOAT|OT_INTEGER): + case (OT_FLOAT):{ + SQFloat res, f1 = tofloat(o1), f2 = tofloat(o2); + switch(op) { + case '+': res = f1 + f2; break; + case '-': res = f1 - f2; break; + case '/': res = f1 / f2; break; + case '*': res = f1 * f2; break; + case '%': res = SQFloat(fmod((double)f1,(double)f2)); break; + default: res = 0x0f; + } + trg = res; } + break; + default: + if(op == '+' && (tmask & _RT_STRING)){ + if(!StringCat(o1, o2, trg)) return false; + } + else if(!ArithMetaMethod(op,o1,o2,trg)) { + return false; + } + } + return true; +} + +SQVM::SQVM(SQSharedState *ss) +{ + _sharedstate=ss; + _suspended = SQFalse; + _suspended_target = -1; + _suspended_root = SQFalse; + _suspended_traps = -1; + _foreignptr = NULL; + _nnativecalls = 0; + _nmetamethodscall = 0; + _lasterror.Null(); + _errorhandler.Null(); + _debughook = false; + _debughook_native = NULL; + _debughook_closure.Null(); + _openouters = NULL; + ci = NULL; + INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); +} + +void SQVM::Finalize() +{ + if(_openouters) CloseOuters(&_stack._vals[0]); + _roottable.Null(); + _lasterror.Null(); + _errorhandler.Null(); + _debughook = false; + _debughook_native = NULL; + _debughook_closure.Null(); + temp_reg.Null(); + _callstackdata.resize(0); + SQInteger size=_stack.size(); + for(SQInteger i=0;i_gc_chain,this); +} + +bool SQVM::ArithMetaMethod(SQInteger op,const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &dest) +{ + SQMetaMethod mm; + switch(op){ + case _SC('+'): mm=MT_ADD; break; + case _SC('-'): mm=MT_SUB; break; + case _SC('/'): mm=MT_DIV; break; + case _SC('*'): mm=MT_MUL; break; + case _SC('%'): mm=MT_MODULO; break; + default: mm = MT_ADD; assert(0); break; //shutup compiler + } + if(is_delegable(o1) && _delegable(o1)->_delegate) { + + SQObjectPtr closure; + if(_delegable(o1)->GetMetaMethod(this, mm, closure)) { + Push(o1);Push(o2); + return CallMetaMethod(closure,mm,2,dest); + } + } + Raise_Error(_SC("arith op %c on between '%s' and '%s'"),op,GetTypeName(o1),GetTypeName(o2)); + return false; +} + +bool SQVM::NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o) +{ + + switch(type(o)) { + case OT_INTEGER: + trg = -_integer(o); + return true; + case OT_FLOAT: + trg = -_float(o); + return true; + case OT_TABLE: + case OT_USERDATA: + case OT_INSTANCE: + if(_delegable(o)->_delegate) { + SQObjectPtr closure; + if(_delegable(o)->GetMetaMethod(this, MT_UNM, closure)) { + Push(o); + if(!CallMetaMethod(closure, MT_UNM, 1, temp_reg)) return false; + _Swap(trg,temp_reg); + return true; + + } + } + default:break; //shutup compiler + } + Raise_Error(_SC("attempt to negate a %s"), GetTypeName(o)); + return false; +} + +#define _RET_SUCCEED(exp) { result = (exp); return true; } +bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result) +{ + SQObjectType t1 = type(o1), t2 = type(o2); + if(t1 == t2){ + if(_rawval(o1)==_rawval(o2))_RET_SUCCEED(0); + SQObjectPtr res; + switch(t1){ + case OT_STRING: + _RET_SUCCEED(scstrcmp(_stringval(o1),_stringval(o2))); + case OT_INTEGER: + _RET_SUCCEED(_integer(o1)-_integer(o2)); + case OT_FLOAT: + _RET_SUCCEED((_float(o1)<_float(o2))?-1:1); + case OT_TABLE: + case OT_USERDATA: + case OT_INSTANCE: + if(_delegable(o1)->_delegate) { + SQObjectPtr closure; + if(_delegable(o1)->GetMetaMethod(this, MT_CMP, closure)) { + Push(o1);Push(o2); + if(!CallMetaMethod(closure,MT_CMP,2,res)) return false; + } + break; + } + //continues through (no break needed) + default: + _RET_SUCCEED( _userpointer(o1) < _userpointer(o2)?-1:1 ); + } + if(type(res)!=OT_INTEGER) { Raise_CompareError(o1,o2); return false; } + _RET_SUCCEED(_integer(res)); + + } + else{ + if(sq_isnumeric(o1) && sq_isnumeric(o2)){ + if((t1==OT_INTEGER) && (t2==OT_FLOAT)) { + if( _integer(o1)==_float(o2) ) { _RET_SUCCEED(0); } + else if( _integer(o1)<_float(o2) ) { _RET_SUCCEED(-1); } + _RET_SUCCEED(1); + } + else{ + if( _float(o1)==_integer(o2) ) { _RET_SUCCEED(0); } + else if( _float(o1)<_integer(o2) ) { _RET_SUCCEED(-1); } + _RET_SUCCEED(1); + } + } + else if(t1==OT_NULL) {_RET_SUCCEED(-1);} + else if(t2==OT_NULL) {_RET_SUCCEED(1);} + else { Raise_CompareError(o1,o2); return false; } + + } + assert(0); + _RET_SUCCEED(0); //cannot happen +} + +bool SQVM::CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res) +{ + SQInteger r; + if(ObjCmp(o1,o2,r)) { + switch(op) { + case CMP_G: res = (r > 0); return true; + case CMP_GE: res = (r >= 0); return true; + case CMP_L: res = (r < 0); return true; + case CMP_LE: res = (r <= 0); return true; + case CMP_3W: res = r; return true; + } + assert(0); + } + return false; +} + +bool SQVM::ToString(const SQObjectPtr &o,SQObjectPtr &res) +{ + switch(type(o)) { + case OT_STRING: + res = o; + return true; + case OT_FLOAT: + scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_SC("%g"),_float(o)); + break; + case OT_INTEGER: + scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_PRINT_INT_FMT,_integer(o)); + break; + case OT_BOOL: + scsprintf(_sp(rsl(6)),_integer(o)?_SC("true"):_SC("false")); + break; + case OT_TABLE: + case OT_USERDATA: + case OT_INSTANCE: + if(_delegable(o)->_delegate) { + SQObjectPtr closure; + if(_delegable(o)->GetMetaMethod(this, MT_TOSTRING, closure)) { + Push(o); + if(CallMetaMethod(closure,MT_TOSTRING,1,res)) {; + if(type(res) == OT_STRING) + return true; + } + else { + return false; + } + } + } + default: + scsprintf(_sp(rsl(sizeof(void*)+20)),_SC("(%s : 0x%p)"),GetTypeName(o),(void*)_rawval(o)); + } + res = SQString::Create(_ss(this),_spval); + return true; +} + + +bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr &dest) +{ + SQObjectPtr a, b; + if(!ToString(str, a)) return false; + if(!ToString(obj, b)) return false; + SQInteger l = _string(a)->_len , ol = _string(b)->_len; + SQChar *s = _sp(rsl(l + ol + 1)); + memcpy(s, _stringval(a), rsl(l)); + memcpy(s + l, _stringval(b), rsl(ol)); + dest = SQString::Create(_ss(this), _spval, l + ol); + return true; +} + +bool SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest) +{ + if(is_delegable(obj1) && _delegable(obj1)->_delegate) { + SQObjectPtr closure; + if(_delegable(obj1)->GetMetaMethod(this, MT_TYPEOF, closure)) { + Push(obj1); + return CallMetaMethod(closure,MT_TYPEOF,1,dest); + } + } + dest = SQString::Create(_ss(this),GetTypeName(obj1)); + return true; +} + +bool SQVM::Init(SQVM *friendvm, SQInteger stacksize) +{ + _stack.resize(stacksize); + _alloccallsstacksize = 4; + _callstackdata.resize(_alloccallsstacksize); + _callsstacksize = 0; + _callsstack = &_callstackdata[0]; + _stackbase = 0; + _top = 0; + if(!friendvm) + _roottable = SQTable::Create(_ss(this), 0); + else { + _roottable = friendvm->_roottable; + _errorhandler = friendvm->_errorhandler; + _debughook = friendvm->_debughook; + _debughook_native = friendvm->_debughook_native; + _debughook_closure = friendvm->_debughook_closure; + } + + sq_base_register(this); + return true; +} + + +bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQInteger stackbase,bool tailcall) +{ + SQFunctionProto *func = closure->_function; + + SQInteger paramssize = func->_nparameters; + const SQInteger newtop = stackbase + func->_stacksize; + SQInteger nargs = args; + if(func->_varparams) + { + paramssize--; + if (nargs < paramssize) { + Raise_Error(_SC("wrong number of parameters")); + return false; + } + + //dumpstack(stackbase); + SQInteger nvargs = nargs - paramssize; + SQArray *arr = SQArray::Create(_ss(this),nvargs); + SQInteger pbase = stackbase+paramssize; + for(SQInteger n = 0; n < nvargs; n++) { + arr->_values[n] = _stack._vals[pbase]; + _stack._vals[pbase].Null(); + pbase++; + + } + _stack._vals[stackbase+paramssize] = arr; + //dumpstack(stackbase); + } + else if (paramssize != nargs) { + SQInteger ndef = func->_ndefaultparams; + SQInteger diff; + if(ndef && nargs < paramssize && (diff = paramssize - nargs) <= ndef) { + for(SQInteger n = ndef - diff; n < ndef; n++) { + _stack._vals[stackbase + (nargs++)] = closure->_defaultparams[n]; + } + } + else { + Raise_Error(_SC("wrong number of parameters")); + return false; + } + } + + if(closure->_env) { + _stack._vals[stackbase] = closure->_env->_obj; + } + + if(!EnterFrame(stackbase, newtop, tailcall)) return false; + + ci->_closure = closure; + ci->_literals = func->_literals; + ci->_ip = func->_instructions; + ci->_target = (SQInt32)target; + + if (_debughook) { + CallDebugHook(_SC('c')); + } + + if (closure->_function->_bgenerator) { + SQFunctionProto *f = closure->_function; + SQGenerator *gen = SQGenerator::Create(_ss(this), closure); + if(!gen->Yield(this,f->_stacksize)) + return false; + SQObjectPtr temp; + Return(1, target, temp); + STK(target) = gen; + } + + + return true; +} + +bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval) +{ + SQBool _isroot = ci->_root; + SQInteger callerbase = _stackbase - ci->_prevstkbase; + + if (_debughook) { + for(SQInteger i=0; i_ncalls; i++) { + CallDebugHook(_SC('r')); + } + } + + SQObjectPtr *dest; + if (_isroot) { + dest = &(retval); + } else if (ci->_target == -1) { + dest = NULL; + } else { + dest = &_stack._vals[callerbase + ci->_target]; + } + if (dest) { + if(_arg0 != 0xFF) { + *dest = _stack._vals[_stackbase+_arg1]; + } + else { + dest->Null(); + } + //*dest = (_arg0 != 0xFF) ? _stack._vals[_stackbase+_arg1] : _null_; + } + LeaveFrame(); + return _isroot ? true : false; +} + +#define _RET_ON_FAIL(exp) { if(!exp) return false; } + +bool SQVM::PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr) +{ + SQObjectPtr trg; + _RET_ON_FAIL(ARITH_OP( op , trg, a, incr)); + target = a; + a = trg; + return true; +} + +bool SQVM::DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix,SQInteger selfidx) +{ + SQObjectPtr tmp, tself = self, tkey = key; + if (!Get(tself, tkey, tmp, false, selfidx)) { return false; } + _RET_ON_FAIL(ARITH_OP( op , target, tmp, incr)) + if (!Set(tself, tkey, target,selfidx)) { return false; } + if (postfix) target = tmp; + return true; +} + +#define arg0 (_i_._arg0) +#define sarg0 ((SQInteger)*((signed char *)&_i_._arg0)) +#define arg1 (_i_._arg1) +#define sarg1 (*((SQInt32 *)&_i_._arg1)) +#define arg2 (_i_._arg2) +#define arg3 (_i_._arg3) +#define sarg3 ((SQInteger)*((signed char *)&_i_._arg3)) + +SQRESULT SQVM::Suspend() +{ + if (_suspended) + return sq_throwerror(this, _SC("cannot suspend an already suspended vm")); + if (_nnativecalls!=2) + return sq_throwerror(this, _SC("cannot suspend through native calls/metamethods")); + return SQ_SUSPEND_FLAG; +} + + +#define _FINISH(howmuchtojump) {jump = howmuchtojump; return true; } +bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr +&o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump) +{ + SQInteger nrefidx; + switch(type(o1)) { + case OT_TABLE: + if((nrefidx = _table(o1)->Next(false,o4, o2, o3)) == -1) _FINISH(exitpos); + o4 = (SQInteger)nrefidx; _FINISH(1); + case OT_ARRAY: + if((nrefidx = _array(o1)->Next(o4, o2, o3)) == -1) _FINISH(exitpos); + o4 = (SQInteger) nrefidx; _FINISH(1); + case OT_STRING: + if((nrefidx = _string(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos); + o4 = (SQInteger)nrefidx; _FINISH(1); + case OT_CLASS: + if((nrefidx = _class(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos); + o4 = (SQInteger)nrefidx; _FINISH(1); + case OT_USERDATA: + case OT_INSTANCE: + if(_delegable(o1)->_delegate) { + SQObjectPtr itr; + SQObjectPtr closure; + if(_delegable(o1)->GetMetaMethod(this, MT_NEXTI, closure)) { + Push(o1); + Push(o4); + if(CallMetaMethod(closure, MT_NEXTI, 2, itr)) { + o4 = o2 = itr; + if(type(itr) == OT_NULL) _FINISH(exitpos); + if(!Get(o1, itr, o3, false, DONT_FALL_BACK)) { + Raise_Error(_SC("_nexti returned an invalid idx")); // cloud be changed + return false; + } + _FINISH(1); + } + else { + return false; + } + } + Raise_Error(_SC("_nexti failed")); + return false; + } + break; + case OT_GENERATOR: + if(_generator(o1)->_state == SQGenerator::eDead) _FINISH(exitpos); + if(_generator(o1)->_state == SQGenerator::eSuspended) { + SQInteger idx = 0; + if(type(o4) == OT_INTEGER) { + idx = _integer(o4) + 1; + } + o2 = idx; + o4 = idx; + _generator(o1)->Resume(this, o3); + _FINISH(0); + } + default: + Raise_Error(_SC("cannot iterate %s"), GetTypeName(o1)); + } + return false; //cannot be hit(just to avoid warnings) +} + +#define COND_LITERAL (arg3!=0?ci->_literals[arg1]:STK(arg1)) + +#define SQ_THROW() { goto exception_trap; } + +#define _GUARD(exp) { if(!exp) { SQ_THROW();} } + +bool SQVM::CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func) +{ + SQInteger nouters; + SQClosure *closure = SQClosure::Create(_ss(this), func); + if((nouters = func->_noutervalues)) { + for(SQInteger i = 0; i_outervalues[i]; + switch(v._type){ + case otLOCAL: + FindOuter(closure->_outervalues[i], &STK(_integer(v._src))); + break; + case otOUTER: + closure->_outervalues[i] = _closure(ci->_closure)->_outervalues[_integer(v._src)]; + break; + } + } + } + SQInteger ndefparams; + if((ndefparams = func->_ndefaultparams)) { + for(SQInteger i = 0; i < ndefparams; i++) { + SQInteger spos = func->_defaultparams[i]; + closure->_defaultparams[i] = _stack._vals[_stackbase + spos]; + } + } + target = closure; + return true; + +} + + +bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes) +{ + SQClass *base = NULL; + SQObjectPtr attrs; + if(baseclass != -1) { + if(type(_stack._vals[_stackbase+baseclass]) != OT_CLASS) { Raise_Error(_SC("trying to inherit from a %s"),GetTypeName(_stack._vals[_stackbase+baseclass])); return false; } + base = _class(_stack._vals[_stackbase + baseclass]); + } + if(attributes != MAX_FUNC_STACKSIZE) { + attrs = _stack._vals[_stackbase+attributes]; + } + target = SQClass::Create(_ss(this),base); + if(type(_class(target)->_metamethods[MT_INHERITED]) != OT_NULL) { + int nparams = 2; + SQObjectPtr ret; + Push(target); Push(attrs); + Call(_class(target)->_metamethods[MT_INHERITED],nparams,_top - nparams, ret, false); + Pop(nparams); + } + _class(target)->_attributes = attrs; + return true; +} + +bool SQVM::IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res) +{ + if(type(o1) == type(o2)) { + res = (_rawval(o1) == _rawval(o2)); + } + else { + if(sq_isnumeric(o1) && sq_isnumeric(o2)) { + res = (tofloat(o1) == tofloat(o2)); + } + else { + res = false; + } + } + return true; +} + +bool SQVM::IsFalse(SQObjectPtr &o) +{ + if(((type(o) & SQOBJECT_CANBEFALSE) + && ( ((type(o) == OT_FLOAT) && (_float(o) == SQFloat(0.0))) )) +#if !defined(SQUSEDOUBLE) || (defined(SQUSEDOUBLE) && defined(_SQ64)) + || (_integer(o) == 0) ) //OT_NULL|OT_INTEGER|OT_BOOL +#else + || (((type(o) != OT_FLOAT) && (_integer(o) == 0))) ) //OT_NULL|OT_INTEGER|OT_BOOL +#endif + { + return true; + } + return false; +} + +bool SQVM::Execute(SQObjectPtr &closure, SQInteger nargs, SQInteger stackbase,SQObjectPtr &outres, SQBool raiseerror,ExecutionType et) +{ + if ((_nnativecalls + 1) > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; } + _nnativecalls++; + AutoDec ad(&_nnativecalls); + SQInteger traps = 0; + CallInfo *prevci = ci; + + switch(et) { + case ET_CALL: { + temp_reg = closure; + if(!StartCall(_closure(temp_reg), _top - nargs, nargs, stackbase, false)) { + //call the handler if there are no calls in the stack, if not relies on the previous node + if(ci == NULL) CallErrorHandler(_lasterror); + return false; + } + if(ci == prevci) { + outres = STK(_top-nargs); + return true; + } + ci->_root = SQTrue; + } + break; + case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, outres); ci->_root = SQTrue; traps += ci->_etraps; break; + case ET_RESUME_VM: + case ET_RESUME_THROW_VM: + traps = _suspended_traps; + ci->_root = _suspended_root; + _suspended = SQFalse; + if(et == ET_RESUME_THROW_VM) { SQ_THROW(); } + break; + } + +exception_restore: + // + { + for(;;) + { + const SQInstruction &_i_ = *ci->_ip++; + //dumpstack(_stackbase); + //scprintf("\n[%d] %s %d %d %d %d\n",ci->_ip-ci->_iv->_vals,g_InstrDesc[_i_.op].name,arg0,arg1,arg2,arg3); + switch(_i_.op) + { + case _OP_LINE: if (_debughook) CallDebugHook(_SC('l'),arg1); continue; + case _OP_LOAD: TARGET = ci->_literals[arg1]; continue; + case _OP_LOADINT: +#ifndef _SQ64 + TARGET = (SQInteger)arg1; continue; +#else + TARGET = (SQInteger)((SQUnsignedInteger32)arg1); continue; +#endif + case _OP_LOADFLOAT: TARGET = *((SQFloat *)&arg1); continue; + case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue; + case _OP_TAILCALL:{ + SQObjectPtr &t = STK(arg1); + if (type(t) == OT_CLOSURE + && (!_closure(t)->_function->_bgenerator)){ + SQObjectPtr clo = t; + if(_openouters) CloseOuters(&(_stack._vals[_stackbase])); + for (SQInteger i = 0; i < arg3; i++) STK(i) = STK(arg2 + i); + _GUARD(StartCall(_closure(clo), ci->_target, arg3, _stackbase, true)); + continue; + } + } + case _OP_CALL: { + SQObjectPtr clo = STK(arg1); + switch (type(clo)) { + case OT_CLOSURE: + _GUARD(StartCall(_closure(clo), sarg0, arg3, _stackbase+arg2, false)); + continue; + case OT_NATIVECLOSURE: { + bool suspend; + _GUARD(CallNative(_nativeclosure(clo), arg3, _stackbase+arg2, clo,suspend)); + if(suspend){ + _suspended = SQTrue; + _suspended_target = sarg0; + _suspended_root = ci->_root; + _suspended_traps = traps; + outres = clo; + return true; + } + if(sarg0 != -1) { + STK(arg0) = clo; + } + } + continue; + case OT_CLASS:{ + SQObjectPtr inst; + _GUARD(CreateClassInstance(_class(clo),inst,clo)); + if(sarg0 != -1) { + STK(arg0) = inst; + } + SQInteger stkbase; + switch(type(clo)) { + case OT_CLOSURE: + stkbase = _stackbase+arg2; + _stack._vals[stkbase] = inst; + _GUARD(StartCall(_closure(clo), -1, arg3, stkbase, false)); + break; + case OT_NATIVECLOSURE: + bool suspend; + stkbase = _stackbase+arg2; + _stack._vals[stkbase] = inst; + _GUARD(CallNative(_nativeclosure(clo), arg3, stkbase, clo,suspend)); + break; + default: break; //shutup GCC 4.x + } + } + break; + case OT_TABLE: + case OT_USERDATA: + case OT_INSTANCE:{ + SQObjectPtr closure; + if(_delegable(clo)->_delegate && _delegable(clo)->GetMetaMethod(this,MT_CALL,closure)) { + Push(clo); + for (SQInteger i = 0; i < arg3; i++) Push(STK(arg2 + i)); + if(!CallMetaMethod(closure, MT_CALL, arg3+1, clo)) SQ_THROW(); + if(sarg0 != -1) { + STK(arg0) = clo; + } + break; + } + + //Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo)); + //SQ_THROW(); + } + default: + Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo)); + SQ_THROW(); + } + } + continue; + case _OP_PREPCALL: + case _OP_PREPCALLK: { + SQObjectPtr &key = _i_.op == _OP_PREPCALLK?(ci->_literals)[arg1]:STK(arg1); + SQObjectPtr &o = STK(arg2); + if (!Get(o, key, temp_reg,false,arg2)) { + SQ_THROW(); + } + STK(arg3) = o; + _Swap(TARGET,temp_reg);//TARGET = temp_reg; + } + continue; + case _OP_GETK: + if (!Get(STK(arg2), ci->_literals[arg1], temp_reg, false,arg2)) { SQ_THROW();} + _Swap(TARGET,temp_reg);//TARGET = temp_reg; + continue; + case _OP_MOVE: TARGET = STK(arg1); continue; + case _OP_NEWSLOT: + _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),false)); + if(arg0 != 0xFF) TARGET = STK(arg3); + continue; + case _OP_DELETE: _GUARD(DeleteSlot(STK(arg1), STK(arg2), TARGET)); continue; + case _OP_SET: + if (!Set(STK(arg1), STK(arg2), STK(arg3),arg1)) { SQ_THROW(); } + if (arg0 != 0xFF) TARGET = STK(arg3); + continue; + case _OP_GET: + if (!Get(STK(arg1), STK(arg2), temp_reg, false,arg1)) { SQ_THROW(); } + _Swap(TARGET,temp_reg);//TARGET = temp_reg; + continue; + case _OP_EQ:{ + bool res; + if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); } + TARGET = res?true:false; + }continue; + case _OP_NE:{ + bool res; + if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); } + TARGET = (!res)?true:false; + } continue; + case _OP_ADD: _ARITH_(+,TARGET,STK(arg2),STK(arg1)); continue; + case _OP_SUB: _ARITH_(-,TARGET,STK(arg2),STK(arg1)); continue; + case _OP_MUL: _ARITH_(*,TARGET,STK(arg2),STK(arg1)); continue; + case _OP_DIV: _ARITH_NOZERO(/,TARGET,STK(arg2),STK(arg1),_SC("division by zero")); continue; + case _OP_MOD: ARITH_OP('%',TARGET,STK(arg2),STK(arg1)); continue; + case _OP_BITW: _GUARD(BW_OP( arg3,TARGET,STK(arg2),STK(arg1))); continue; + case _OP_RETURN: + if((ci)->_generator) { + (ci)->_generator->Kill(); + } + if(Return(arg0, arg1, temp_reg)){ + assert(traps==0); + //outres = temp_reg; + _Swap(outres,temp_reg); + return true; + } + continue; + case _OP_LOADNULLS:{ for(SQInt32 n=0; n < arg1; n++) STK(arg0+n).Null(); }continue; + case _OP_LOADROOT: TARGET = _roottable; continue; + case _OP_LOADBOOL: TARGET = arg1?true:false; continue; + case _OP_DMOVE: STK(arg0) = STK(arg1); STK(arg2) = STK(arg3); continue; + case _OP_JMP: ci->_ip += (sarg1); continue; + //case _OP_JNZ: if(!IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue; + case _OP_JCMP: + _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg0),temp_reg)); + if(IsFalse(temp_reg)) ci->_ip+=(sarg1); + continue; + case _OP_JZ: if(IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue; + case _OP_GETOUTER: { + SQClosure *cur_cls = _closure(ci->_closure); + SQOuter *otr = _outer(cur_cls->_outervalues[arg1]); + TARGET = *(otr->_valptr); + } + continue; + case _OP_SETOUTER: { + SQClosure *cur_cls = _closure(ci->_closure); + SQOuter *otr = _outer(cur_cls->_outervalues[arg1]); + *(otr->_valptr) = STK(arg2); + if(arg0 != 0xFF) { + TARGET = STK(arg2); + } + } + continue; + case _OP_NEWOBJ: + switch(arg3) { + case NOT_TABLE: TARGET = SQTable::Create(_ss(this), arg1); continue; + case NOT_ARRAY: TARGET = SQArray::Create(_ss(this), 0); _array(TARGET)->Reserve(arg1); continue; + case NOT_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue; + default: assert(0); continue; + } + case _OP_APPENDARRAY: + { + SQObject val; + val._unVal.raw = 0; + switch(arg2) { + case AAT_STACK: + val = STK(arg1); break; + case AAT_LITERAL: + val = ci->_literals[arg1]; break; + case AAT_INT: + val._type = OT_INTEGER; +#ifndef _SQ64 + val._unVal.nInteger = (SQInteger)arg1; +#else + val._unVal.nInteger = (SQInteger)((SQUnsignedInteger32)arg1); +#endif + break; + case AAT_FLOAT: + val._type = OT_FLOAT; + val._unVal.fFloat = *((SQFloat *)&arg1); + break; + case AAT_BOOL: + val._type = OT_BOOL; + val._unVal.nInteger = arg1; + break; + default: assert(0); break; + + } + _array(STK(arg0))->Append(val); continue; + } + case _OP_COMPARITH: { + SQInteger selfidx = (((SQUnsignedInteger)arg1&0xFFFF0000)>>16); + _GUARD(DerefInc(arg3, TARGET, STK(selfidx), STK(arg2), STK(arg1&0x0000FFFF), false, selfidx)); + } + continue; + case _OP_INC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, false, arg1));} continue; + case _OP_INCL: { + SQObjectPtr &a = STK(arg1); + if(type(a) == OT_INTEGER) { + a._unVal.nInteger = _integer(a) + sarg3; + } + else { + SQObjectPtr o(sarg3); //_GUARD(LOCAL_INC('+',TARGET, STK(arg1), o)); + _ARITH_(+,a,a,o); + } + } continue; + case _OP_PINC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, true, arg1));} continue; + case _OP_PINCL: { + SQObjectPtr &a = STK(arg1); + if(type(a) == OT_INTEGER) { + TARGET = a; + a._unVal.nInteger = _integer(a) + sarg3; + } + else { + SQObjectPtr o(sarg3); _GUARD(PLOCAL_INC('+',TARGET, STK(arg1), o)); + } + + } continue; + case _OP_CMP: _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg1),TARGET)) continue; + case _OP_EXISTS: TARGET = Get(STK(arg1), STK(arg2), temp_reg, true,DONT_FALL_BACK)?true:false;continue; + case _OP_INSTANCEOF: + if(type(STK(arg1)) != OT_CLASS) + {Raise_Error(_SC("cannot apply instanceof between a %s and a %s"),GetTypeName(STK(arg1)),GetTypeName(STK(arg2))); SQ_THROW();} + TARGET = (type(STK(arg2)) == OT_INSTANCE) ? (_instance(STK(arg2))->InstanceOf(_class(STK(arg1)))?true:false) : false; + continue; + case _OP_AND: + if(IsFalse(STK(arg2))) { + TARGET = STK(arg2); + ci->_ip += (sarg1); + } + continue; + case _OP_OR: + if(!IsFalse(STK(arg2))) { + TARGET = STK(arg2); + ci->_ip += (sarg1); + } + continue; + case _OP_NEG: _GUARD(NEG_OP(TARGET,STK(arg1))); continue; + case _OP_NOT: TARGET = IsFalse(STK(arg1)); continue; + case _OP_BWNOT: + if(type(STK(arg1)) == OT_INTEGER) { + SQInteger t = _integer(STK(arg1)); + TARGET = SQInteger(~t); + continue; + } + Raise_Error(_SC("attempt to perform a bitwise op on a %s"), GetTypeName(STK(arg1))); + SQ_THROW(); + case _OP_CLOSURE: { + SQClosure *c = ci->_closure._unVal.pClosure; + SQFunctionProto *fp = c->_function; + if(!CLOSURE_OP(TARGET,fp->_functions[arg1]._unVal.pFunctionProto)) { SQ_THROW(); } + continue; + } + case _OP_YIELD:{ + if(ci->_generator) { + if(sarg1 != MAX_FUNC_STACKSIZE) temp_reg = STK(arg1); + _GUARD(ci->_generator->Yield(this,arg2)); + traps -= ci->_etraps; + if(sarg1 != MAX_FUNC_STACKSIZE) _Swap(STK(arg1),temp_reg);//STK(arg1) = temp_reg; + } + else { Raise_Error(_SC("trying to yield a '%s',only genenerator can be yielded"), GetTypeName(ci->_generator)); SQ_THROW();} + if(Return(arg0, arg1, temp_reg)){ + assert(traps == 0); + outres = temp_reg; + return true; + } + + } + continue; + case _OP_RESUME: + if(type(STK(arg1)) != OT_GENERATOR){ Raise_Error(_SC("trying to resume a '%s',only genenerator can be resumed"), GetTypeName(STK(arg1))); SQ_THROW();} + _GUARD(_generator(STK(arg1))->Resume(this, TARGET)); + traps += ci->_etraps; + continue; + case _OP_FOREACH:{ int tojump; + _GUARD(FOREACH_OP(STK(arg0),STK(arg2),STK(arg2+1),STK(arg2+2),arg2,sarg1,tojump)); + ci->_ip += tojump; } + continue; + case _OP_POSTFOREACH: + assert(type(STK(arg0)) == OT_GENERATOR); + if(_generator(STK(arg0))->_state == SQGenerator::eDead) + ci->_ip += (sarg1 - 1); + continue; + case _OP_CLONE: _GUARD(Clone(STK(arg1), TARGET)); continue; + case _OP_TYPEOF: _GUARD(TypeOf(STK(arg1), TARGET)) continue; + case _OP_PUSHTRAP:{ + SQInstruction *_iv = _closure(ci->_closure)->_function->_instructions; + _etraps.push_back(SQExceptionTrap(_top,_stackbase, &_iv[(ci->_ip-_iv)+arg1], arg0)); traps++; + ci->_etraps++; + } + continue; + case _OP_POPTRAP: { + for(SQInteger i = 0; i < arg0; i++) { + _etraps.pop_back(); traps--; + ci->_etraps--; + } + } + continue; + case _OP_THROW: Raise_Error(TARGET); SQ_THROW(); continue; + case _OP_NEWSLOTA: { + bool bstatic = (arg0&NEW_SLOT_STATIC_FLAG)?true:false; + if(type(STK(arg1)) == OT_CLASS) { + if(type(_class(STK(arg1))->_metamethods[MT_NEWMEMBER]) != OT_NULL ) { + Push(STK(arg1)); Push(STK(arg2)); Push(STK(arg3)); + Push((arg0&NEW_SLOT_ATTRIBUTES_FLAG) ? STK(arg2-1) : SQObjectPtr()); + Push(bstatic); + int nparams = 5; + if(Call(_class(STK(arg1))->_metamethods[MT_NEWMEMBER], nparams, _top - nparams, temp_reg,SQFalse)) { + Pop(nparams); + continue; + } + else { + SQ_THROW(); + } + } + } + _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),bstatic)); + if((arg0&NEW_SLOT_ATTRIBUTES_FLAG)) { + _class(STK(arg1))->SetAttributes(STK(arg2),STK(arg2-1)); + } + } + continue; + case _OP_GETBASE:{ + SQClosure *clo = _closure(ci->_closure); + if(clo->_base) { + TARGET = clo->_base; + } + else { + TARGET.Null(); + } + continue; + } + case _OP_CLOSE: + if(_openouters) CloseOuters(&(STK(arg1))); + continue; + } + + } + } +exception_trap: + { + SQObjectPtr currerror = _lasterror; +// dumpstack(_stackbase); +// SQInteger n = 0; + SQInteger last_top = _top; + + if(_ss(this)->_notifyallexceptions || (!traps && raiseerror)) CallErrorHandler(currerror); + + while( ci ) { + if(ci->_etraps > 0) { + SQExceptionTrap &et = _etraps.top(); + ci->_ip = et._ip; + _top = et._stacksize; + _stackbase = et._stackbase; + _stack._vals[_stackbase + et._extarget] = currerror; + _etraps.pop_back(); traps--; ci->_etraps--; + while(last_top >= _top) _stack._vals[last_top--].Null(); + goto exception_restore; + } + else if (_debughook) { + //notify debugger of a "return" + //even if it really an exception unwinding the stack + for(SQInteger i = 0; i < ci->_ncalls; i++) { + CallDebugHook(_SC('r')); + } + } + if(ci->_generator) ci->_generator->Kill(); + bool mustbreak = ci && ci->_root; + LeaveFrame(); + if(mustbreak) break; + } + + _lasterror = currerror; + return false; + } + assert(0); +} + +bool SQVM::CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor) +{ + inst = theclass->CreateInstance(); + if(!theclass->GetConstructor(constructor)) { + constructor.Null(); + } + return true; +} + +void SQVM::CallErrorHandler(SQObjectPtr &error) +{ + if(type(_errorhandler) != OT_NULL) { + SQObjectPtr out; + Push(_roottable); Push(error); + Call(_errorhandler, 2, _top-2, out,SQFalse); + Pop(2); + } +} + + +void SQVM::CallDebugHook(SQInteger type,SQInteger forcedline) +{ + _debughook = false; + SQFunctionProto *func=_closure(ci->_closure)->_function; + if(_debughook_native) { + const SQChar *src = type(func->_sourcename) == OT_STRING?_stringval(func->_sourcename):NULL; + const SQChar *fname = type(func->_name) == OT_STRING?_stringval(func->_name):NULL; + SQInteger line = forcedline?forcedline:func->GetLine(ci->_ip); + _debughook_native(this,type,src,line,fname); + } + else { + SQObjectPtr temp_reg; + SQInteger nparams=5; + Push(_roottable); Push(type); Push(func->_sourcename); Push(forcedline?forcedline:func->GetLine(ci->_ip)); Push(func->_name); + Call(_debughook_closure,nparams,_top-nparams,temp_reg,SQFalse); + Pop(nparams); + } + _debughook = true; +} + +bool SQVM::CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newbase, SQObjectPtr &retval, bool &suspend) +{ + SQInteger nparamscheck = nclosure->_nparamscheck; + SQInteger newtop = newbase + nargs + nclosure->_noutervalues; + + if (_nnativecalls + 1 > MAX_NATIVE_CALLS) { + Raise_Error(_SC("Native stack overflow")); + return false; + } + + if(nparamscheck && (((nparamscheck > 0) && (nparamscheck != nargs)) || + ((nparamscheck < 0) && (nargs < (-nparamscheck))))) + { + Raise_Error(_SC("wrong number of parameters")); + return false; + } + + SQInteger tcs; + SQIntVec &tc = nclosure->_typecheck; + if((tcs = tc.size())) { + for(SQInteger i = 0; i < nargs && i < tcs; i++) { + if((tc._vals[i] != -1) && !(type(_stack._vals[newbase+i]) & tc._vals[i])) { + Raise_ParamTypeError(i,tc._vals[i],type(_stack._vals[newbase+i])); + return false; + } + } + } + + if(!EnterFrame(newbase, newtop, false)) return false; + ci->_closure = nclosure; + + SQInteger outers = nclosure->_noutervalues; + for (SQInteger i = 0; i < outers; i++) { + _stack._vals[newbase+nargs+i] = nclosure->_outervalues[i]; + } + if(nclosure->_env) { + _stack._vals[newbase] = nclosure->_env->_obj; + } + + _nnativecalls++; + SQInteger ret = (nclosure->_function)(this); + _nnativecalls--; + + suspend = false; + if (ret == SQ_SUSPEND_FLAG) { + suspend = true; + } + else if (ret < 0) { + LeaveFrame(); + Raise_Error(_lasterror); + return false; + } + if(ret) { + retval = _stack._vals[_top-1]; + } + else { + retval.Null(); + } + //retval = ret ? _stack._vals[_top-1] : _null_; + LeaveFrame(); + return true; +} + +#define FALLBACK_OK 0 +#define FALLBACK_NO_MATCH 1 +#define FALLBACK_ERROR 2 + +bool SQVM::Get(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw, SQInteger selfidx) +{ + switch(type(self)){ + case OT_TABLE: + if(_table(self)->Get(key,dest))return true; + break; + case OT_ARRAY: + if(sq_isnumeric(key)) { if(_array(self)->Get(tointeger(key),dest)) { return true; } Raise_IdxError(key); return false; } + break; + case OT_INSTANCE: + if(_instance(self)->Get(key,dest)) return true; + break; + case OT_CLASS: + if(_class(self)->Get(key,dest)) return true; + break; + case OT_STRING: + if(sq_isnumeric(key)){ + SQInteger n = tointeger(key); + if(abs((int)n) < _string(self)->_len) { + if(n < 0) n = _string(self)->_len - n; + dest = SQInteger(_stringval(self)[n]); + return true; + } + Raise_IdxError(key); + return false; + } + break; + default:break; //shut up compiler + } + if(!raw) { + switch(FallBackGet(self,key,dest)) { + case FALLBACK_OK: return true; //okie + case FALLBACK_NO_MATCH: break; //keep falling back + case FALLBACK_ERROR: return false; // the metamethod failed + } + if(InvokeDefaultDelegate(self,key,dest)) { + return true; + } + } +//#ifdef ROOT_FALLBACK + if(selfidx == 0) { + if(_table(_roottable)->Get(key,dest)) return true; + } +//#endif + Raise_IdxError(key); + return false; +} + +bool SQVM::InvokeDefaultDelegate(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest) +{ + SQTable *ddel = NULL; + switch(type(self)) { + case OT_CLASS: ddel = _class_ddel; break; + case OT_TABLE: ddel = _table_ddel; break; + case OT_ARRAY: ddel = _array_ddel; break; + case OT_STRING: ddel = _string_ddel; break; + case OT_INSTANCE: ddel = _instance_ddel; break; + case OT_INTEGER:case OT_FLOAT:case OT_BOOL: ddel = _number_ddel; break; + case OT_GENERATOR: ddel = _generator_ddel; break; + case OT_CLOSURE: case OT_NATIVECLOSURE: ddel = _closure_ddel; break; + case OT_THREAD: ddel = _thread_ddel; break; + case OT_WEAKREF: ddel = _weakref_ddel; break; + default: return false; + } + return ddel->Get(key,dest); +} + + +SQInteger SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest) +{ + switch(type(self)){ + case OT_TABLE: + case OT_USERDATA: + //delegation + if(_delegable(self)->_delegate) { + if(Get(SQObjectPtr(_delegable(self)->_delegate),key,dest,false,DONT_FALL_BACK)) return FALLBACK_OK; + } + else { + return FALLBACK_NO_MATCH; + } + //go through + case OT_INSTANCE: { + SQObjectPtr closure; + if(_delegable(self)->GetMetaMethod(this, MT_GET, closure)) { + Push(self);Push(key); + _nmetamethodscall++; + AutoDec ad(&_nmetamethodscall); + if(Call(closure, 2, _top - 2, dest, SQFalse)) { + Pop(2); + return FALLBACK_OK; + } + else { + if(type(_lasterror) != OT_NULL) { //NULL means "clean failure" (not found) + //error + Pop(2); + return FALLBACK_ERROR; + } + } + } + } + break; + default: break;//shutup GCC 4.x + } + // no metamethod or no fallback type + return FALLBACK_NO_MATCH; +} + +bool SQVM::Set(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,SQInteger selfidx) +{ + switch(type(self)){ + case OT_TABLE: + if(_table(self)->Set(key,val)) return true; + break; + case OT_INSTANCE: + if(_instance(self)->Set(key,val)) return true; + break; + case OT_ARRAY: + if(!sq_isnumeric(key)) { Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); return false; } + if(!_array(self)->Set(tointeger(key),val)) { + Raise_IdxError(key); + return false; + } + return true; + default: + Raise_Error(_SC("trying to set '%s'"),GetTypeName(self)); + return false; + } + + switch(FallBackSet(self,key,val)) { + case FALLBACK_OK: return true; //okie + case FALLBACK_NO_MATCH: break; //keep falling back + case FALLBACK_ERROR: return false; // the metamethod failed + } + if(selfidx == 0) { + if(_table(_roottable)->Set(key,val)) + return true; + } + Raise_IdxError(key); + return false; +} + +SQInteger SQVM::FallBackSet(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val) +{ + switch(type(self)) { + case OT_TABLE: + if(_table(self)->_delegate) { + if(Set(_table(self)->_delegate,key,val,DONT_FALL_BACK)) return FALLBACK_OK; + } + //keps on going + case OT_INSTANCE: + case OT_USERDATA:{ + SQObjectPtr closure; + SQObjectPtr t; + if(_delegable(self)->GetMetaMethod(this, MT_SET, closure)) { + Push(self);Push(key);Push(val); + _nmetamethodscall++; + AutoDec ad(&_nmetamethodscall); + if(Call(closure, 3, _top - 3, t, SQFalse)) { + Pop(3); + return FALLBACK_OK; + } + else { + if(type(_lasterror) != OT_NULL) { //NULL means "clean failure" (not found) + //error + Pop(3); + return FALLBACK_ERROR; + } + } + } + } + break; + default: break;//shutup GCC 4.x + } + // no metamethod or no fallback type + return FALLBACK_NO_MATCH; +} + +bool SQVM::Clone(const SQObjectPtr &self,SQObjectPtr &target) +{ + SQObjectPtr temp_reg; + SQObjectPtr newobj; + switch(type(self)){ + case OT_TABLE: + newobj = _table(self)->Clone(); + goto cloned_mt; + case OT_INSTANCE: { + newobj = _instance(self)->Clone(_ss(this)); +cloned_mt: + SQObjectPtr closure; + if(_delegable(newobj)->_delegate && _delegable(newobj)->GetMetaMethod(this,MT_CLONED,closure)) { + Push(newobj); + Push(self); + if(!CallMetaMethod(closure,MT_CLONED,2,temp_reg)) + return false; + } + } + target = newobj; + return true; + case OT_ARRAY: + target = _array(self)->Clone(); + return true; + default: + Raise_Error(_SC("cloning a %s"), GetTypeName(self)); + return false; + } +} + +bool SQVM::NewSlot(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic) +{ + if(type(key) == OT_NULL) { Raise_Error(_SC("null cannot be used as index")); return false; } + switch(type(self)) { + case OT_TABLE: { + bool rawcall = true; + if(_table(self)->_delegate) { + SQObjectPtr res; + if(!_table(self)->Get(key,res)) { + SQObjectPtr closure; + if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_NEWSLOT,closure)) { + Push(self);Push(key);Push(val); + if(!CallMetaMethod(closure,MT_NEWSLOT,3,res)) { + return false; + } + rawcall = false; + } + else { + rawcall = true; + } + } + } + if(rawcall) _table(self)->NewSlot(key,val); //cannot fail + + break;} + case OT_INSTANCE: { + SQObjectPtr res; + SQObjectPtr closure; + if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_NEWSLOT,closure)) { + Push(self);Push(key);Push(val); + if(!CallMetaMethod(closure,MT_NEWSLOT,3,res)) { + return false; + } + break; + } + Raise_Error(_SC("class instances do not support the new slot operator")); + return false; + break;} + case OT_CLASS: + if(!_class(self)->NewSlot(_ss(this),key,val,bstatic)) { + if(_class(self)->_locked) { + Raise_Error(_SC("trying to modify a class that has already been instantiated")); + return false; + } + else { + SQObjectPtr oval = PrintObjVal(key); + Raise_Error(_SC("the property '%s' already exists"),_stringval(oval)); + return false; + } + } + break; + default: + Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); + return false; + break; + } + return true; +} + + + +bool SQVM::DeleteSlot(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &res) +{ + switch(type(self)) { + case OT_TABLE: + case OT_INSTANCE: + case OT_USERDATA: { + SQObjectPtr t; + //bool handled = false; + SQObjectPtr closure; + if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_DELSLOT,closure)) { + Push(self);Push(key); + return CallMetaMethod(closure,MT_DELSLOT,2,res); + } + else { + if(type(self) == OT_TABLE) { + if(_table(self)->Get(key,t)) { + _table(self)->Remove(key); + } + else { + Raise_IdxError((SQObject &)key); + return false; + } + } + else { + Raise_Error(_SC("cannot delete a slot from %s"),GetTypeName(self)); + return false; + } + } + res = t; + } + break; + default: + Raise_Error(_SC("attempt to delete a slot from a %s"),GetTypeName(self)); + return false; + } + return true; +} + +bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObjectPtr &outres,SQBool raiseerror) +{ +#ifdef _DEBUG +SQInteger prevstackbase = _stackbase; +#endif + switch(type(closure)) { + case OT_CLOSURE: + return Execute(closure, nparams, stackbase, outres, raiseerror); + break; + case OT_NATIVECLOSURE:{ + bool suspend; + return CallNative(_nativeclosure(closure), nparams, stackbase, outres,suspend); + + } + break; + case OT_CLASS: { + SQObjectPtr constr; + SQObjectPtr temp; + CreateClassInstance(_class(closure),outres,constr); + if(type(constr) != OT_NULL) { + _stack[stackbase] = outres; + return Call(constr,nparams,stackbase,temp,raiseerror); + } + return true; + } + break; + default: + return false; + } +#ifdef _DEBUG + if(!_suspended) { + assert(_stackbase == prevstackbase); + } +#endif + return true; +} + +bool SQVM::CallMetaMethod(SQObjectPtr &closure,SQMetaMethod mm,SQInteger nparams,SQObjectPtr &outres) +{ + //SQObjectPtr closure; + + _nmetamethodscall++; + if(Call(closure, nparams, _top - nparams, outres, SQFalse)) { + _nmetamethodscall--; + Pop(nparams); + return true; + } + _nmetamethodscall--; + //} + Pop(nparams); + return false; +} + +void SQVM::FindOuter(SQObjectPtr &target, SQObjectPtr *stackindex) +{ + SQOuter **pp = &_openouters; + SQOuter *p; + SQOuter *otr; + + while ((p = *pp) != NULL && p->_valptr >= stackindex) { + if (p->_valptr == stackindex) { + target = SQObjectPtr(p); + return; + } + pp = &p->_next; + } + otr = SQOuter::Create(_ss(this), stackindex); + otr->_next = *pp; + otr->_idx = (stackindex - _stack._vals); + __ObjAddRef(otr); + *pp = otr; + target = SQObjectPtr(otr); +} + +bool SQVM::EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall) +{ + if( !tailcall ) { + if( _callsstacksize == _alloccallsstacksize ) { + GrowCallStack(); + } + ci = &_callsstack[_callsstacksize++]; + ci->_prevstkbase = (SQInt32)(newbase - _stackbase); + ci->_prevtop = (SQInt32)(_top - _stackbase); + ci->_etraps = 0; + ci->_ncalls = 1; + ci->_generator = NULL; + ci->_root = SQFalse; + } + else { + ci->_ncalls++; + } + + _stackbase = newbase; + _top = newtop; + if(newtop + MIN_STACK_OVERHEAD > (SQInteger)_stack.size()) { + if(_nmetamethodscall) { + Raise_Error(_SC("stack overflow, cannot resize stack while in a metamethod")); + return false; + } + _stack.resize(_stack.size() + (MIN_STACK_OVERHEAD << 2)); + RelocateOuters(); + } + return true; +} + +void SQVM::LeaveFrame() { + SQInteger last_top = _top; + SQInteger last_stackbase = _stackbase; + SQInteger css = --_callsstacksize; + + /* First clean out the call stack frame */ + ci->_closure.Null(); + _stackbase -= ci->_prevstkbase; + _top = _stackbase + ci->_prevtop; + ci = (css) ? &_callsstack[css-1] : NULL; + + if(_openouters) CloseOuters(&(_stack._vals[last_stackbase])); + while (last_top >= _top) { + _stack._vals[last_top--].Null(); + } +} + +void SQVM::RelocateOuters() +{ + SQOuter *p = _openouters; + while (p) { + p->_valptr = _stack._vals + p->_idx; + p = p->_next; + } +} + +void SQVM::CloseOuters(SQObjectPtr *stackindex) { + SQOuter *p; + while ((p = _openouters) != NULL && p->_valptr >= stackindex) { + p->_value = *(p->_valptr); + p->_valptr = &p->_value; + _openouters = p->_next; + __ObjRelease(p); + } +} + +void SQVM::Remove(SQInteger n) { + n = (n >= 0)?n + _stackbase - 1:_top + n; + for(SQInteger i = n; i < _top; i++){ + _stack[i] = _stack[i+1]; + } + _stack[_top].Null(); + _top--; +} + +void SQVM::Pop() { + _stack[--_top].Null(); +} + +void SQVM::Pop(SQInteger n) { + for(SQInteger i = 0; i < n; i++){ + _stack[--_top].Null(); + } +} + +void SQVM::PushNull() { _stack[_top++].Null(); } +void SQVM::Push(const SQObjectPtr &o) { _stack[_top++] = o; } +SQObjectPtr &SQVM::Top() { return _stack[_top-1]; } +SQObjectPtr &SQVM::PopGet() { return _stack[--_top]; } +SQObjectPtr &SQVM::GetUp(SQInteger n) { return _stack[_top+n]; } +SQObjectPtr &SQVM::GetAt(SQInteger n) { return _stack[n]; } + +#ifdef _DEBUG_DUMP +void SQVM::dumpstack(SQInteger stackbase,bool dumpall) +{ + SQInteger size=dumpall?_stack.size():_top; + SQInteger n=0; + scprintf(_SC("\n>>>>stack dump<<<<\n")); + CallInfo &ci=_callsstack[_callsstacksize-1]; + scprintf(_SC("IP: %p\n"),ci._ip); + scprintf(_SC("prev stack base: %d\n"),ci._prevstkbase); + scprintf(_SC("prev top: %d\n"),ci._prevtop); + for(SQInteger i=0;i"));else scprintf(_SC(" ")); + scprintf(_SC("[%d]:"),n); + switch(type(obj)){ + case OT_FLOAT: scprintf(_SC("FLOAT %.3f"),_float(obj));break; + case OT_INTEGER: scprintf(_SC("INTEGER %d"),_integer(obj));break; + case OT_BOOL: scprintf(_SC("BOOL %s"),_integer(obj)?"true":"false");break; + case OT_STRING: scprintf(_SC("STRING %s"),_stringval(obj));break; + case OT_NULL: scprintf(_SC("NULL")); break; + case OT_TABLE: scprintf(_SC("TABLE %p[%p]"),_table(obj),_table(obj)->_delegate);break; + case OT_ARRAY: scprintf(_SC("ARRAY %p"),_array(obj));break; + case OT_CLOSURE: scprintf(_SC("CLOSURE [%p]"),_closure(obj));break; + case OT_NATIVECLOSURE: scprintf(_SC("NATIVECLOSURE"));break; + case OT_USERDATA: scprintf(_SC("USERDATA %p[%p]"),_userdataval(obj),_userdata(obj)->_delegate);break; + case OT_GENERATOR: scprintf(_SC("GENERATOR %p"),_generator(obj));break; + case OT_THREAD: scprintf(_SC("THREAD [%p]"),_thread(obj));break; + case OT_USERPOINTER: scprintf(_SC("USERPOINTER %p"),_userpointer(obj));break; + case OT_CLASS: scprintf(_SC("CLASS %p"),_class(obj));break; + case OT_INSTANCE: scprintf(_SC("INSTANCE %p"),_instance(obj));break; + case OT_WEAKREF: scprintf(_SC("WEAKERF %p"),_weakref(obj));break; + default: + assert(0); + break; + }; + scprintf(_SC("\n")); + ++n; + } +} + + + +#endif diff --git a/squirrel_3_0_1_stable/squirrel/sqvm.h b/squirrel_3_0_1_stable/squirrel/sqvm.h index 397dcd9c1..a21be543d 100644 --- a/squirrel_3_0_1_stable/squirrel/sqvm.h +++ b/squirrel_3_0_1_stable/squirrel/sqvm.h @@ -1,208 +1,208 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQVM_H_ -#define _SQVM_H_ - -#include "sqopcodes.h" -#include "sqobject.h" -#define MAX_NATIVE_CALLS 100 -#define MIN_STACK_OVERHEAD 15 - -#define SQ_SUSPEND_FLAG -666 -#define DONT_FALL_BACK 666 -//base lib -void sq_base_register(HSQUIRRELVM v); - -struct SQExceptionTrap{ - SQExceptionTrap() {} - SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;} - SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et; } - SQInteger _stackbase; - SQInteger _stacksize; - SQInstruction *_ip; - SQInteger _extarget; -}; - -#define _INLINE - -#define STK(a) _stack._vals[_stackbase+(a)] -#define TARGET _stack._vals[_stackbase+arg0] - -typedef sqvector ExceptionsTraps; - -struct SQVM : public CHAINABLE_OBJ -{ - struct CallInfo{ - //CallInfo() { _generator = NULL;} - SQInstruction *_ip; - SQObjectPtr *_literals; - SQObjectPtr _closure; - SQGenerator *_generator; - SQInt32 _etraps; - SQInt32 _prevstkbase; - SQInt32 _prevtop; - SQInt32 _target; - SQInt32 _ncalls; - SQBool _root; - }; - -typedef sqvector CallInfoVec; -public: - void DebugHookProxy(SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname); - static void _DebugHookProxy(HSQUIRRELVM v, SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname); - enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM,ET_RESUME_THROW_VM }; - SQVM(SQSharedState *ss); - ~SQVM(); - bool Init(SQVM *friendvm, SQInteger stacksize); - bool Execute(SQObjectPtr &func, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL); - //starts a native call return when the NATIVE closure returns - bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newbase, SQObjectPtr &retval,bool &suspend); - //starts a SQUIRREL call in the same "Execution loop" - bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall); - bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor); - //call a generic closure pure SQUIRREL or NATIVE - bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror); - SQRESULT Suspend(); - - void CallDebugHook(SQInteger type,SQInteger forcedline=0); - void CallErrorHandler(SQObjectPtr &e); - bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, bool raw, SQInteger selfidx); - SQInteger FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest); - bool InvokeDefaultDelegate(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest); - bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, SQInteger selfidx); - SQInteger FallBackSet(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val); - bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic); - bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res); - bool Clone(const SQObjectPtr &self, SQObjectPtr &target); - bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res); - bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest); - static bool IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res); - bool ToString(const SQObjectPtr &o,SQObjectPtr &res); - SQString *PrintObjVal(const SQObjectPtr &o); - - - void Raise_Error(const SQChar *s, ...); - void Raise_Error(const SQObjectPtr &desc); - void Raise_IdxError(const SQObjectPtr &o); - void Raise_CompareError(const SQObject &o1, const SQObject &o2); - void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type); - - void FindOuter(SQObjectPtr &target, SQObjectPtr *stackindex); - void RelocateOuters(); - void CloseOuters(SQObjectPtr *stackindex); - - bool TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest); - bool CallMetaMethod(SQObjectPtr &closure, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres); - bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest); - bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval); - //new stuff - _INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2); - _INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2); - _INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1); - _INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res); - bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func); - bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs); - //return true if the loop is finished - bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump); - //_INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr); - _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr); - _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix,SQInteger arg0); -#ifdef _DEBUG_DUMP - void dumpstack(SQInteger stackbase=-1, bool dumpall = false); -#endif - -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **chain); - SQObjectType GetType() {return OT_THREAD;} -#endif - void Finalize(); - void GrowCallStack() { - SQInteger newsize = _alloccallsstacksize*2; - _callstackdata.resize(newsize); - _callsstack = &_callstackdata[0]; - _alloccallsstacksize = newsize; - } - bool EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall); - void LeaveFrame(); - void Release(){ sq_delete(this,SQVM); } -//////////////////////////////////////////////////////////////////////////// - //stack functions for the api - void Remove(SQInteger n); - - static bool IsFalse(SQObjectPtr &o); - - void Pop(); - void Pop(SQInteger n); - void Push(const SQObjectPtr &o); - void PushNull(); - SQObjectPtr &Top(); - SQObjectPtr &PopGet(); - SQObjectPtr &GetUp(SQInteger n); - SQObjectPtr &GetAt(SQInteger n); - - SQObjectPtrVec _stack; - - SQInteger _top; - SQInteger _stackbase; - SQOuter *_openouters; - SQObjectPtr _roottable; - SQObjectPtr _lasterror; - SQObjectPtr _errorhandler; - - bool _debughook; - SQDEBUGHOOK _debughook_native; - SQObjectPtr _debughook_closure; - - SQObjectPtr temp_reg; - - - CallInfo* _callsstack; - SQInteger _callsstacksize; - SQInteger _alloccallsstacksize; - sqvector _callstackdata; - - ExceptionsTraps _etraps; - CallInfo *ci; - void *_foreignptr; - //VMs sharing the same state - SQSharedState *_sharedstate; - SQInteger _nnativecalls; - SQInteger _nmetamethodscall; - //suspend infos - SQBool _suspended; - SQBool _suspended_root; - SQInteger _suspended_target; - SQInteger _suspended_traps; -}; - -struct AutoDec{ - AutoDec(SQInteger *n) { _n = n; } - ~AutoDec() { (*_n)--; } - SQInteger *_n; -}; - -inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));} - -#define _ss(_vm_) (_vm_)->_sharedstate - -#ifndef NO_GARBAGE_COLLECTOR -#define _opt_ss(_vm_) (_vm_)->_sharedstate -#else -#define _opt_ss(_vm_) NULL -#endif - -#define PUSH_CALLINFO(v,nci){ \ - SQInteger css = v->_callsstacksize; \ - if(css == v->_alloccallsstacksize) { \ - v->GrowCallStack(); \ - } \ - v->ci = &v->_callsstack[css]; \ - *(v->ci) = nci; \ - v->_callsstacksize++; \ -} - -#define POP_CALLINFO(v){ \ - SQInteger css = --v->_callsstacksize; \ - v->ci->_closure.Null(); \ - v->ci = css?&v->_callsstack[css-1]:NULL; \ -} -#endif //_SQVM_H_ +/* see copyright notice in squirrel.h */ +#ifndef _SQVM_H_ +#define _SQVM_H_ + +#include "sqopcodes.h" +#include "sqobject.h" +#define MAX_NATIVE_CALLS 100 +#define MIN_STACK_OVERHEAD 15 + +#define SQ_SUSPEND_FLAG -666 +#define DONT_FALL_BACK 666 +//base lib +void sq_base_register(HSQUIRRELVM v); + +struct SQExceptionTrap{ + SQExceptionTrap() {} + SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;} + SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et; } + SQInteger _stackbase; + SQInteger _stacksize; + SQInstruction *_ip; + SQInteger _extarget; +}; + +#define _INLINE + +#define STK(a) _stack._vals[_stackbase+(a)] +#define TARGET _stack._vals[_stackbase+arg0] + +typedef sqvector ExceptionsTraps; + +struct SQVM : public CHAINABLE_OBJ +{ + struct CallInfo{ + //CallInfo() { _generator = NULL;} + SQInstruction *_ip; + SQObjectPtr *_literals; + SQObjectPtr _closure; + SQGenerator *_generator; + SQInt32 _etraps; + SQInt32 _prevstkbase; + SQInt32 _prevtop; + SQInt32 _target; + SQInt32 _ncalls; + SQBool _root; + }; + +typedef sqvector CallInfoVec; +public: + void DebugHookProxy(SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname); + static void _DebugHookProxy(HSQUIRRELVM v, SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname); + enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM,ET_RESUME_THROW_VM }; + SQVM(SQSharedState *ss); + ~SQVM(); + bool Init(SQVM *friendvm, SQInteger stacksize); + bool Execute(SQObjectPtr &func, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL); + //starts a native call return when the NATIVE closure returns + bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newbase, SQObjectPtr &retval,bool &suspend); + //starts a SQUIRREL call in the same "Execution loop" + bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall); + bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor); + //call a generic closure pure SQUIRREL or NATIVE + bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror); + SQRESULT Suspend(); + + void CallDebugHook(SQInteger type,SQInteger forcedline=0); + void CallErrorHandler(SQObjectPtr &e); + bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, bool raw, SQInteger selfidx); + SQInteger FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest); + bool InvokeDefaultDelegate(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest); + bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, SQInteger selfidx); + SQInteger FallBackSet(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val); + bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic); + bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res); + bool Clone(const SQObjectPtr &self, SQObjectPtr &target); + bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res); + bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest); + static bool IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res); + bool ToString(const SQObjectPtr &o,SQObjectPtr &res); + SQString *PrintObjVal(const SQObjectPtr &o); + + + void Raise_Error(const SQChar *s, ...); + void Raise_Error(const SQObjectPtr &desc); + void Raise_IdxError(const SQObjectPtr &o); + void Raise_CompareError(const SQObject &o1, const SQObject &o2); + void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type); + + void FindOuter(SQObjectPtr &target, SQObjectPtr *stackindex); + void RelocateOuters(); + void CloseOuters(SQObjectPtr *stackindex); + + bool TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest); + bool CallMetaMethod(SQObjectPtr &closure, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres); + bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest); + bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval); + //new stuff + _INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2); + _INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2); + _INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1); + _INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res); + bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func); + bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs); + //return true if the loop is finished + bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump); + //_INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr); + _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr); + _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix,SQInteger arg0); +#ifdef _DEBUG_DUMP + void dumpstack(SQInteger stackbase=-1, bool dumpall = false); +#endif + +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + SQObjectType GetType() {return OT_THREAD;} +#endif + void Finalize(); + void GrowCallStack() { + SQInteger newsize = _alloccallsstacksize*2; + _callstackdata.resize(newsize); + _callsstack = &_callstackdata[0]; + _alloccallsstacksize = newsize; + } + bool EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall); + void LeaveFrame(); + void Release(){ sq_delete(this,SQVM); } +//////////////////////////////////////////////////////////////////////////// + //stack functions for the api + void Remove(SQInteger n); + + static bool IsFalse(SQObjectPtr &o); + + void Pop(); + void Pop(SQInteger n); + void Push(const SQObjectPtr &o); + void PushNull(); + SQObjectPtr &Top(); + SQObjectPtr &PopGet(); + SQObjectPtr &GetUp(SQInteger n); + SQObjectPtr &GetAt(SQInteger n); + + SQObjectPtrVec _stack; + + SQInteger _top; + SQInteger _stackbase; + SQOuter *_openouters; + SQObjectPtr _roottable; + SQObjectPtr _lasterror; + SQObjectPtr _errorhandler; + + bool _debughook; + SQDEBUGHOOK _debughook_native; + SQObjectPtr _debughook_closure; + + SQObjectPtr temp_reg; + + + CallInfo* _callsstack; + SQInteger _callsstacksize; + SQInteger _alloccallsstacksize; + sqvector _callstackdata; + + ExceptionsTraps _etraps; + CallInfo *ci; + void *_foreignptr; + //VMs sharing the same state + SQSharedState *_sharedstate; + SQInteger _nnativecalls; + SQInteger _nmetamethodscall; + //suspend infos + SQBool _suspended; + SQBool _suspended_root; + SQInteger _suspended_target; + SQInteger _suspended_traps; +}; + +struct AutoDec{ + AutoDec(SQInteger *n) { _n = n; } + ~AutoDec() { (*_n)--; } + SQInteger *_n; +}; + +inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));} + +#define _ss(_vm_) (_vm_)->_sharedstate + +#ifndef NO_GARBAGE_COLLECTOR +#define _opt_ss(_vm_) (_vm_)->_sharedstate +#else +#define _opt_ss(_vm_) NULL +#endif + +#define PUSH_CALLINFO(v,nci){ \ + SQInteger css = v->_callsstacksize; \ + if(css == v->_alloccallsstacksize) { \ + v->GrowCallStack(); \ + } \ + v->ci = &v->_callsstack[css]; \ + *(v->ci) = nci; \ + v->_callsstacksize++; \ +} + +#define POP_CALLINFO(v){ \ + SQInteger css = --v->_callsstacksize; \ + v->ci->_closure.Null(); \ + v->ci = css?&v->_callsstack[css-1]:NULL; \ +} +#endif //_SQVM_H_ diff --git a/tolua++-1.0.93/src/bin/toluabind.c b/tolua++-1.0.93/src/bin/toluabind.c index 70271fb3f..bf71cf158 100644 --- a/tolua++-1.0.93/src/bin/toluabind.c +++ b/tolua++-1.0.93/src/bin/toluabind.c @@ -7915,160 +7915,160 @@ TOLUA_API int tolua_tolua_open (lua_State* tolua_S) int top = lua_gettop(tolua_S); // _Xoft(o): hex dump of the lua/doit.lua file, generated by HxD static unsigned char B[] = { - 0x2D, 0x2D, 0x20, 0x47, 0x65, 0x6E, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, - 0x62, 0x69, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x63, 0x6F, 0x64, 0x65, - 0x0A, 0x2D, 0x2D, 0x20, 0x57, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6E, 0x20, - 0x62, 0x79, 0x20, 0x57, 0x61, 0x6C, 0x64, 0x65, 0x6D, 0x61, 0x72, 0x20, - 0x43, 0x65, 0x6C, 0x65, 0x73, 0x0A, 0x2D, 0x2D, 0x20, 0x54, 0x65, 0x43, - 0x47, 0x72, 0x61, 0x66, 0x2F, 0x50, 0x55, 0x43, 0x2D, 0x52, 0x69, 0x6F, - 0x0A, 0x2D, 0x2D, 0x20, 0x4A, 0x75, 0x6C, 0x20, 0x31, 0x39, 0x39, 0x38, - 0x0A, 0x2D, 0x2D, 0x20, 0x4C, 0x61, 0x73, 0x74, 0x20, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x3A, 0x20, 0x41, 0x70, 0x72, 0x20, 0x32, 0x30, 0x30, - 0x33, 0x0A, 0x2D, 0x2D, 0x20, 0x24, 0x49, 0x64, 0x3A, 0x20, 0x24, 0x0A, - 0x0A, 0x0A, 0x2D, 0x2D, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, 0x6F, - 0x64, 0x65, 0x20, 0x69, 0x73, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, 0x73, - 0x6F, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x3B, 0x20, 0x79, 0x6F, 0x75, - 0x20, 0x63, 0x61, 0x6E, 0x20, 0x72, 0x65, 0x64, 0x69, 0x73, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x69, 0x74, 0x20, 0x61, 0x6E, 0x64, - 0x2F, 0x6F, 0x72, 0x20, 0x6D, 0x6F, 0x64, 0x69, 0x66, 0x79, 0x20, 0x69, - 0x74, 0x2E, 0x0A, 0x2D, 0x2D, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6F, - 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x6F, 0x76, 0x69, - 0x64, 0x65, 0x64, 0x20, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6E, 0x64, 0x65, - 0x72, 0x20, 0x69, 0x73, 0x20, 0x6F, 0x6E, 0x20, 0x61, 0x6E, 0x20, 0x22, - 0x61, 0x73, 0x20, 0x69, 0x73, 0x22, 0x20, 0x62, 0x61, 0x73, 0x69, 0x73, - 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x0A, 0x2D, 0x2D, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x20, 0x68, 0x61, 0x73, 0x20, - 0x6E, 0x6F, 0x20, 0x6F, 0x62, 0x6C, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, - 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x70, 0x72, 0x6F, 0x76, 0x69, 0x64, 0x65, - 0x20, 0x6D, 0x61, 0x69, 0x6E, 0x74, 0x65, 0x6E, 0x61, 0x6E, 0x63, 0x65, - 0x2C, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6F, 0x72, 0x74, 0x2C, 0x20, 0x75, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x2C, 0x0A, 0x2D, 0x2D, 0x20, 0x65, - 0x6E, 0x68, 0x61, 0x6E, 0x63, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x2C, - 0x20, 0x6F, 0x72, 0x20, 0x6D, 0x6F, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x2E, 0x0A, 0x0A, 0x66, 0x75, 0x6E, 0x63, - 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5F, 0x65, - 0x78, 0x74, 0x72, 0x61, 0x28, 0x29, 0x0A, 0x0A, 0x09, 0x66, 0x6F, 0x72, - 0x20, 0x6B, 0x2C, 0x76, 0x20, 0x69, 0x6E, 0x20, 0x69, 0x70, 0x61, 0x69, - 0x72, 0x73, 0x28, 0x5F, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5F, 0x70, 0x61, - 0x72, 0x61, 0x6D, 0x65, 0x74, 0x65, 0x72, 0x73, 0x20, 0x6F, 0x72, 0x20, - 0x7B, 0x7D, 0x29, 0x20, 0x64, 0x6F, 0x0A, 0x09, 0x09, 0x0A, 0x09, 0x09, - 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x62, 0x2C, 0x65, 0x2C, 0x6E, 0x61, - 0x6D, 0x65, 0x2C, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x73, - 0x74, 0x72, 0x69, 0x6E, 0x67, 0x2E, 0x66, 0x69, 0x6E, 0x64, 0x28, 0x76, - 0x2C, 0x20, 0x22, 0x5E, 0x28, 0x5B, 0x5E, 0x3D, 0x5D, 0x2A, 0x29, 0x3D, - 0x28, 0x2E, 0x2A, 0x29, 0x24, 0x22, 0x29, 0x0A, 0x09, 0x09, 0x69, 0x66, - 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x09, 0x5F, - 0x65, 0x78, 0x74, 0x72, 0x61, 0x5F, 0x70, 0x61, 0x72, 0x61, 0x6D, 0x65, - 0x74, 0x65, 0x72, 0x73, 0x5B, 0x6E, 0x61, 0x6D, 0x65, 0x5D, 0x20, 0x3D, - 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x0A, 0x09, 0x09, 0x65, 0x6C, 0x73, - 0x65, 0x0A, 0x09, 0x09, 0x09, 0x5F, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5F, - 0x70, 0x61, 0x72, 0x61, 0x6D, 0x65, 0x74, 0x65, 0x72, 0x73, 0x5B, 0x76, - 0x5D, 0x20, 0x3D, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0A, 0x09, 0x09, 0x65, - 0x6E, 0x64, 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x65, 0x6E, 0x64, 0x0A, - 0x0A, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x64, 0x6F, - 0x69, 0x74, 0x20, 0x28, 0x29, 0x0A, 0x09, 0x2D, 0x2D, 0x20, 0x64, 0x65, - 0x66, 0x69, 0x6E, 0x65, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x61, 0x67, 0x65, - 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x2C, 0x20, 0x69, 0x66, 0x20, 0x6E, 0x6F, - 0x74, 0x20, 0x70, 0x72, 0x6F, 0x76, 0x69, 0x64, 0x65, 0x64, 0x0A, 0x09, - 0x69, 0x66, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x66, 0x6C, 0x61, 0x67, 0x73, - 0x2E, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x69, 0x66, - 0x20, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x66, 0x20, 0x74, 0x68, 0x65, - 0x6E, 0x0A, 0x09, 0x09, 0x09, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x6E, - 0x20, 0x3D, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x66, 0x6C, 0x61, 0x67, - 0x73, 0x2E, 0x66, 0x2C, 0x22, 0x25, 0x2E, 0x2E, 0x2A, 0x24, 0x22, 0x2C, - 0x22, 0x22, 0x29, 0x0A, 0x09, 0x09, 0x09, 0x5F, 0x2C, 0x5F, 0x2C, 0x66, - 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x6E, 0x20, 0x3D, 0x20, 0x73, 0x74, 0x72, - 0x69, 0x6E, 0x67, 0x2E, 0x66, 0x69, 0x6E, 0x64, 0x28, 0x66, 0x6C, 0x61, - 0x67, 0x73, 0x2E, 0x6E, 0x2C, 0x20, 0x22, 0x28, 0x5B, 0x5E, 0x2F, 0x5C, - 0x5C, 0x5D, 0x2A, 0x29, 0x24, 0x22, 0x29, 0x0A, 0x09, 0x09, 0x65, 0x6C, - 0x73, 0x65, 0x0A, 0x09, 0x09, 0x09, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28, - 0x22, 0x23, 0x6E, 0x6F, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x61, 0x67, 0x65, - 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x6E, 0x6F, 0x72, 0x20, 0x69, 0x6E, - 0x70, 0x75, 0x74, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x70, 0x72, 0x6F, - 0x76, 0x69, 0x64, 0x65, 0x64, 0x22, 0x29, 0x0A, 0x09, 0x09, 0x65, 0x6E, - 0x64, 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x2D, 0x2D, 0x20, - 0x70, 0x61, 0x72, 0x73, 0x65, 0x20, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x20, - 0x77, 0x69, 0x74, 0x68, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x20, 0x70, - 0x61, 0x72, 0x61, 0x6D, 0x74, 0x65, 0x72, 0x73, 0x0A, 0x09, 0x70, 0x61, - 0x72, 0x73, 0x65, 0x5F, 0x65, 0x78, 0x74, 0x72, 0x61, 0x28, 0x29, 0x0A, - 0x0A, 0x09, 0x2D, 0x2D, 0x20, 0x64, 0x6F, 0x20, 0x74, 0x68, 0x69, 0x73, - 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, - 0x6E, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x61, - 0x67, 0x65, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x0A, 0x09, 0x69, 0x66, 0x20, - 0x66, 0x6C, 0x61, 0x67, 0x73, 0x5B, 0x27, 0x4C, 0x27, 0x5D, 0x20, 0x74, - 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x64, 0x6F, 0x66, 0x69, 0x6C, 0x65, - 0x28, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x5B, 0x27, 0x4C, 0x27, 0x5D, 0x29, - 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x2D, 0x2D, 0x20, 0x61, - 0x64, 0x64, 0x20, 0x63, 0x70, 0x70, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, - 0x0A, 0x09, 0x69, 0x66, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x66, 0x6C, 0x61, - 0x67, 0x73, 0x5B, 0x27, 0x53, 0x27, 0x5D, 0x20, 0x74, 0x68, 0x65, 0x6E, - 0x0A, 0x09, 0x09, 0x5F, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5B, 0x27, 0x73, - 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x5D, 0x20, 0x3D, 0x20, 0x27, 0x63, - 0x70, 0x70, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x0A, 0x09, 0x09, - 0x5F, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5B, 0x27, 0x73, 0x74, 0x64, 0x3A, - 0x3A, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x5D, 0x20, 0x3D, 0x20, - 0x27, 0x63, 0x70, 0x70, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x0A, - 0x09, 0x09, 0x5F, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5B, 0x27, 0x41, 0x53, - 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x5D, 0x20, 0x3D, 0x20, 0x27, 0x63, - 0x70, 0x70, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x0A, 0x09, 0x09, - 0x5F, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5F, 0x63, 0x74, 0x79, 0x70, 0x65, - 0x2E, 0x63, 0x70, 0x70, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x3D, - 0x20, 0x27, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, - 0x2A, 0x27, 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x2D, 0x2D, - 0x20, 0x70, 0x72, 0x6F, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x70, 0x61, - 0x63, 0x6B, 0x61, 0x67, 0x65, 0x0A, 0x09, 0x6C, 0x6F, 0x63, 0x61, 0x6C, - 0x20, 0x70, 0x20, 0x20, 0x3D, 0x20, 0x50, 0x61, 0x63, 0x6B, 0x61, 0x67, - 0x65, 0x28, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x6E, 0x2C, 0x66, 0x6C, - 0x61, 0x67, 0x73, 0x2E, 0x66, 0x29, 0x0A, 0x0A, 0x09, 0x69, 0x66, 0x20, - 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x70, 0x20, 0x74, 0x68, 0x65, 0x6E, - 0x0A, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x20, 0x6F, 0x6E, 0x6C, 0x79, - 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, - 0x0A, 0x09, 0x69, 0x66, 0x20, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x6F, - 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x6C, 0x6F, 0x63, 0x61, - 0x6C, 0x20, 0x73, 0x74, 0x2C, 0x6D, 0x73, 0x67, 0x20, 0x3D, 0x20, 0x77, - 0x72, 0x69, 0x74, 0x65, 0x74, 0x6F, 0x28, 0x66, 0x6C, 0x61, 0x67, 0x73, - 0x2E, 0x6F, 0x29, 0x0A, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6E, 0x6F, 0x74, - 0x20, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x09, - 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28, 0x27, 0x23, 0x27, 0x2E, 0x2E, 0x6D, - 0x73, 0x67, 0x29, 0x0A, 0x09, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x09, 0x65, - 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x70, 0x3A, 0x64, 0x65, 0x63, 0x6C, 0x74, - 0x79, 0x70, 0x65, 0x28, 0x29, 0x0A, 0x09, 0x69, 0x66, 0x20, 0x66, 0x6C, - 0x61, 0x67, 0x73, 0x2E, 0x50, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, - 0x09, 0x70, 0x3A, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x28, 0x29, 0x0A, 0x09, - 0x65, 0x6C, 0x73, 0x65, 0x0A, 0x09, 0x09, 0x70, 0x75, 0x73, 0x68, 0x28, - 0x70, 0x29, 0x0A, 0x09, 0x09, 0x70, 0x72, 0x65, 0x5F, 0x6F, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x5F, 0x68, 0x6F, 0x6F, 0x6B, 0x28, 0x70, 0x29, 0x0A, - 0x09, 0x09, 0x70, 0x6F, 0x70, 0x28, 0x29, 0x0A, 0x09, 0x09, 0x70, 0x3A, - 0x70, 0x72, 0x65, 0x61, 0x6D, 0x62, 0x6C, 0x65, 0x28, 0x29, 0x0A, 0x09, - 0x09, 0x70, 0x3A, 0x73, 0x75, 0x70, 0x63, 0x6F, 0x64, 0x65, 0x28, 0x29, - 0x0A, 0x09, 0x09, 0x70, 0x75, 0x73, 0x68, 0x28, 0x70, 0x29, 0x0A, 0x09, - 0x09, 0x70, 0x72, 0x65, 0x5F, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, - 0x72, 0x5F, 0x68, 0x6F, 0x6F, 0x6B, 0x28, 0x70, 0x29, 0x0A, 0x09, 0x09, - 0x70, 0x6F, 0x70, 0x28, 0x29, 0x0A, 0x09, 0x09, 0x70, 0x3A, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x28, 0x29, 0x0A, 0x09, 0x09, 0x70, - 0x75, 0x73, 0x68, 0x28, 0x70, 0x29, 0x0A, 0x09, 0x09, 0x70, 0x6F, 0x73, - 0x74, 0x5F, 0x6F, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5F, 0x68, 0x6F, 0x6F, - 0x6B, 0x28, 0x70, 0x29, 0x0A, 0x09, 0x09, 0x70, 0x6F, 0x70, 0x28, 0x29, - 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x69, 0x66, 0x20, 0x66, - 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, - 0x09, 0x09, 0x77, 0x72, 0x69, 0x74, 0x65, 0x74, 0x6F, 0x28, 0x29, 0x0A, - 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x2D, 0x2D, 0x20, 0x77, 0x72, - 0x69, 0x74, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x66, - 0x69, 0x6C, 0x65, 0x0A, 0x09, 0x69, 0x66, 0x20, 0x6E, 0x6F, 0x74, 0x20, - 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x50, 0x20, 0x74, 0x68, 0x65, 0x6E, - 0x0A, 0x09, 0x09, 0x69, 0x66, 0x20, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, - 0x48, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x09, 0x6C, 0x6F, - 0x63, 0x61, 0x6C, 0x20, 0x73, 0x74, 0x2C, 0x6D, 0x73, 0x67, 0x20, 0x3D, - 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x74, 0x6F, 0x28, 0x66, 0x6C, 0x61, - 0x67, 0x73, 0x2E, 0x48, 0x29, 0x0A, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, - 0x6E, 0x6F, 0x74, 0x20, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, - 0x09, 0x09, 0x09, 0x09, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28, 0x27, 0x23, - 0x27, 0x2E, 0x2E, 0x6D, 0x73, 0x67, 0x29, 0x0A, 0x09, 0x09, 0x09, 0x65, - 0x6E, 0x64, 0x0A, 0x09, 0x09, 0x09, 0x70, 0x3A, 0x68, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x28, 0x29, 0x0A, 0x09, 0x09, 0x09, 0x77, 0x72, 0x69, 0x74, - 0x65, 0x74, 0x6F, 0x28, 0x29, 0x0A, 0x09, 0x09, 0x65, 0x6E, 0x64, 0x0A, - 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x65, 0x6E, 0x64, 0x0A, 0x0A + 0x2D, 0x2D, 0x20, 0x47, 0x65, 0x6E, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, + 0x62, 0x69, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x63, 0x6F, 0x64, 0x65, + 0x0A, 0x2D, 0x2D, 0x20, 0x57, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6E, 0x20, + 0x62, 0x79, 0x20, 0x57, 0x61, 0x6C, 0x64, 0x65, 0x6D, 0x61, 0x72, 0x20, + 0x43, 0x65, 0x6C, 0x65, 0x73, 0x0A, 0x2D, 0x2D, 0x20, 0x54, 0x65, 0x43, + 0x47, 0x72, 0x61, 0x66, 0x2F, 0x50, 0x55, 0x43, 0x2D, 0x52, 0x69, 0x6F, + 0x0A, 0x2D, 0x2D, 0x20, 0x4A, 0x75, 0x6C, 0x20, 0x31, 0x39, 0x39, 0x38, + 0x0A, 0x2D, 0x2D, 0x20, 0x4C, 0x61, 0x73, 0x74, 0x20, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x3A, 0x20, 0x41, 0x70, 0x72, 0x20, 0x32, 0x30, 0x30, + 0x33, 0x0A, 0x2D, 0x2D, 0x20, 0x24, 0x49, 0x64, 0x3A, 0x20, 0x24, 0x0A, + 0x0A, 0x0A, 0x2D, 0x2D, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, 0x6F, + 0x64, 0x65, 0x20, 0x69, 0x73, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, 0x73, + 0x6F, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x3B, 0x20, 0x79, 0x6F, 0x75, + 0x20, 0x63, 0x61, 0x6E, 0x20, 0x72, 0x65, 0x64, 0x69, 0x73, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x69, 0x74, 0x20, 0x61, 0x6E, 0x64, + 0x2F, 0x6F, 0x72, 0x20, 0x6D, 0x6F, 0x64, 0x69, 0x66, 0x79, 0x20, 0x69, + 0x74, 0x2E, 0x0A, 0x2D, 0x2D, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6F, + 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x6F, 0x76, 0x69, + 0x64, 0x65, 0x64, 0x20, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6E, 0x64, 0x65, + 0x72, 0x20, 0x69, 0x73, 0x20, 0x6F, 0x6E, 0x20, 0x61, 0x6E, 0x20, 0x22, + 0x61, 0x73, 0x20, 0x69, 0x73, 0x22, 0x20, 0x62, 0x61, 0x73, 0x69, 0x73, + 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x0A, 0x2D, 0x2D, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x20, 0x68, 0x61, 0x73, 0x20, + 0x6E, 0x6F, 0x20, 0x6F, 0x62, 0x6C, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x70, 0x72, 0x6F, 0x76, 0x69, 0x64, 0x65, + 0x20, 0x6D, 0x61, 0x69, 0x6E, 0x74, 0x65, 0x6E, 0x61, 0x6E, 0x63, 0x65, + 0x2C, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6F, 0x72, 0x74, 0x2C, 0x20, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x2C, 0x0A, 0x2D, 0x2D, 0x20, 0x65, + 0x6E, 0x68, 0x61, 0x6E, 0x63, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x2C, + 0x20, 0x6F, 0x72, 0x20, 0x6D, 0x6F, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x2E, 0x0A, 0x0A, 0x66, 0x75, 0x6E, 0x63, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5F, 0x65, + 0x78, 0x74, 0x72, 0x61, 0x28, 0x29, 0x0A, 0x0A, 0x09, 0x66, 0x6F, 0x72, + 0x20, 0x6B, 0x2C, 0x76, 0x20, 0x69, 0x6E, 0x20, 0x69, 0x70, 0x61, 0x69, + 0x72, 0x73, 0x28, 0x5F, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5F, 0x70, 0x61, + 0x72, 0x61, 0x6D, 0x65, 0x74, 0x65, 0x72, 0x73, 0x20, 0x6F, 0x72, 0x20, + 0x7B, 0x7D, 0x29, 0x20, 0x64, 0x6F, 0x0A, 0x09, 0x09, 0x0A, 0x09, 0x09, + 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x62, 0x2C, 0x65, 0x2C, 0x6E, 0x61, + 0x6D, 0x65, 0x2C, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6E, 0x67, 0x2E, 0x66, 0x69, 0x6E, 0x64, 0x28, 0x76, + 0x2C, 0x20, 0x22, 0x5E, 0x28, 0x5B, 0x5E, 0x3D, 0x5D, 0x2A, 0x29, 0x3D, + 0x28, 0x2E, 0x2A, 0x29, 0x24, 0x22, 0x29, 0x0A, 0x09, 0x09, 0x69, 0x66, + 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x09, 0x5F, + 0x65, 0x78, 0x74, 0x72, 0x61, 0x5F, 0x70, 0x61, 0x72, 0x61, 0x6D, 0x65, + 0x74, 0x65, 0x72, 0x73, 0x5B, 0x6E, 0x61, 0x6D, 0x65, 0x5D, 0x20, 0x3D, + 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x0A, 0x09, 0x09, 0x65, 0x6C, 0x73, + 0x65, 0x0A, 0x09, 0x09, 0x09, 0x5F, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5F, + 0x70, 0x61, 0x72, 0x61, 0x6D, 0x65, 0x74, 0x65, 0x72, 0x73, 0x5B, 0x76, + 0x5D, 0x20, 0x3D, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0A, 0x09, 0x09, 0x65, + 0x6E, 0x64, 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x65, 0x6E, 0x64, 0x0A, + 0x0A, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x64, 0x6F, + 0x69, 0x74, 0x20, 0x28, 0x29, 0x0A, 0x09, 0x2D, 0x2D, 0x20, 0x64, 0x65, + 0x66, 0x69, 0x6E, 0x65, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x61, 0x67, 0x65, + 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x2C, 0x20, 0x69, 0x66, 0x20, 0x6E, 0x6F, + 0x74, 0x20, 0x70, 0x72, 0x6F, 0x76, 0x69, 0x64, 0x65, 0x64, 0x0A, 0x09, + 0x69, 0x66, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x66, 0x6C, 0x61, 0x67, 0x73, + 0x2E, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x69, 0x66, + 0x20, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x6E, 0x0A, 0x09, 0x09, 0x09, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x6E, + 0x20, 0x3D, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x66, 0x6C, 0x61, 0x67, + 0x73, 0x2E, 0x66, 0x2C, 0x22, 0x25, 0x2E, 0x2E, 0x2A, 0x24, 0x22, 0x2C, + 0x22, 0x22, 0x29, 0x0A, 0x09, 0x09, 0x09, 0x5F, 0x2C, 0x5F, 0x2C, 0x66, + 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x6E, 0x20, 0x3D, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6E, 0x67, 0x2E, 0x66, 0x69, 0x6E, 0x64, 0x28, 0x66, 0x6C, 0x61, + 0x67, 0x73, 0x2E, 0x6E, 0x2C, 0x20, 0x22, 0x28, 0x5B, 0x5E, 0x2F, 0x5C, + 0x5C, 0x5D, 0x2A, 0x29, 0x24, 0x22, 0x29, 0x0A, 0x09, 0x09, 0x65, 0x6C, + 0x73, 0x65, 0x0A, 0x09, 0x09, 0x09, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28, + 0x22, 0x23, 0x6E, 0x6F, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x61, 0x67, 0x65, + 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x6E, 0x6F, 0x72, 0x20, 0x69, 0x6E, + 0x70, 0x75, 0x74, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x70, 0x72, 0x6F, + 0x76, 0x69, 0x64, 0x65, 0x64, 0x22, 0x29, 0x0A, 0x09, 0x09, 0x65, 0x6E, + 0x64, 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x2D, 0x2D, 0x20, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x20, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x20, + 0x77, 0x69, 0x74, 0x68, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x20, 0x70, + 0x61, 0x72, 0x61, 0x6D, 0x74, 0x65, 0x72, 0x73, 0x0A, 0x09, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x5F, 0x65, 0x78, 0x74, 0x72, 0x61, 0x28, 0x29, 0x0A, + 0x0A, 0x09, 0x2D, 0x2D, 0x20, 0x64, 0x6F, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, + 0x6E, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x61, + 0x67, 0x65, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x0A, 0x09, 0x69, 0x66, 0x20, + 0x66, 0x6C, 0x61, 0x67, 0x73, 0x5B, 0x27, 0x4C, 0x27, 0x5D, 0x20, 0x74, + 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x64, 0x6F, 0x66, 0x69, 0x6C, 0x65, + 0x28, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x5B, 0x27, 0x4C, 0x27, 0x5D, 0x29, + 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x2D, 0x2D, 0x20, 0x61, + 0x64, 0x64, 0x20, 0x63, 0x70, 0x70, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, + 0x0A, 0x09, 0x69, 0x66, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x66, 0x6C, 0x61, + 0x67, 0x73, 0x5B, 0x27, 0x53, 0x27, 0x5D, 0x20, 0x74, 0x68, 0x65, 0x6E, + 0x0A, 0x09, 0x09, 0x5F, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5B, 0x27, 0x73, + 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x5D, 0x20, 0x3D, 0x20, 0x27, 0x63, + 0x70, 0x70, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x0A, 0x09, 0x09, + 0x5F, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5B, 0x27, 0x73, 0x74, 0x64, 0x3A, + 0x3A, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x5D, 0x20, 0x3D, 0x20, + 0x27, 0x63, 0x70, 0x70, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x0A, + 0x09, 0x09, 0x5F, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5B, 0x27, 0x41, 0x53, + 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x5D, 0x20, 0x3D, 0x20, 0x27, 0x63, + 0x70, 0x70, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x0A, 0x09, 0x09, + 0x5F, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5F, 0x63, 0x74, 0x79, 0x70, 0x65, + 0x2E, 0x63, 0x70, 0x70, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x3D, + 0x20, 0x27, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, + 0x2A, 0x27, 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x2D, 0x2D, + 0x20, 0x70, 0x72, 0x6F, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x70, 0x61, + 0x63, 0x6B, 0x61, 0x67, 0x65, 0x0A, 0x09, 0x6C, 0x6F, 0x63, 0x61, 0x6C, + 0x20, 0x70, 0x20, 0x20, 0x3D, 0x20, 0x50, 0x61, 0x63, 0x6B, 0x61, 0x67, + 0x65, 0x28, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x6E, 0x2C, 0x66, 0x6C, + 0x61, 0x67, 0x73, 0x2E, 0x66, 0x29, 0x0A, 0x0A, 0x09, 0x69, 0x66, 0x20, + 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x70, 0x20, 0x74, 0x68, 0x65, 0x6E, + 0x0A, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x20, 0x6F, 0x6E, 0x6C, 0x79, + 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, + 0x0A, 0x09, 0x69, 0x66, 0x20, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x6F, + 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x6C, 0x6F, 0x63, 0x61, + 0x6C, 0x20, 0x73, 0x74, 0x2C, 0x6D, 0x73, 0x67, 0x20, 0x3D, 0x20, 0x77, + 0x72, 0x69, 0x74, 0x65, 0x74, 0x6F, 0x28, 0x66, 0x6C, 0x61, 0x67, 0x73, + 0x2E, 0x6F, 0x29, 0x0A, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6E, 0x6F, 0x74, + 0x20, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x09, + 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28, 0x27, 0x23, 0x27, 0x2E, 0x2E, 0x6D, + 0x73, 0x67, 0x29, 0x0A, 0x09, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x09, 0x65, + 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x70, 0x3A, 0x64, 0x65, 0x63, 0x6C, 0x74, + 0x79, 0x70, 0x65, 0x28, 0x29, 0x0A, 0x09, 0x69, 0x66, 0x20, 0x66, 0x6C, + 0x61, 0x67, 0x73, 0x2E, 0x50, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, + 0x09, 0x70, 0x3A, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x28, 0x29, 0x0A, 0x09, + 0x65, 0x6C, 0x73, 0x65, 0x0A, 0x09, 0x09, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x70, 0x29, 0x0A, 0x09, 0x09, 0x70, 0x72, 0x65, 0x5F, 0x6F, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x5F, 0x68, 0x6F, 0x6F, 0x6B, 0x28, 0x70, 0x29, 0x0A, + 0x09, 0x09, 0x70, 0x6F, 0x70, 0x28, 0x29, 0x0A, 0x09, 0x09, 0x70, 0x3A, + 0x70, 0x72, 0x65, 0x61, 0x6D, 0x62, 0x6C, 0x65, 0x28, 0x29, 0x0A, 0x09, + 0x09, 0x70, 0x3A, 0x73, 0x75, 0x70, 0x63, 0x6F, 0x64, 0x65, 0x28, 0x29, + 0x0A, 0x09, 0x09, 0x70, 0x75, 0x73, 0x68, 0x28, 0x70, 0x29, 0x0A, 0x09, + 0x09, 0x70, 0x72, 0x65, 0x5F, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x5F, 0x68, 0x6F, 0x6F, 0x6B, 0x28, 0x70, 0x29, 0x0A, 0x09, 0x09, + 0x70, 0x6F, 0x70, 0x28, 0x29, 0x0A, 0x09, 0x09, 0x70, 0x3A, 0x72, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x28, 0x29, 0x0A, 0x09, 0x09, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x70, 0x29, 0x0A, 0x09, 0x09, 0x70, 0x6F, 0x73, + 0x74, 0x5F, 0x6F, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5F, 0x68, 0x6F, 0x6F, + 0x6B, 0x28, 0x70, 0x29, 0x0A, 0x09, 0x09, 0x70, 0x6F, 0x70, 0x28, 0x29, + 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x69, 0x66, 0x20, 0x66, + 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, + 0x09, 0x09, 0x77, 0x72, 0x69, 0x74, 0x65, 0x74, 0x6F, 0x28, 0x29, 0x0A, + 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x2D, 0x2D, 0x20, 0x77, 0x72, + 0x69, 0x74, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x66, + 0x69, 0x6C, 0x65, 0x0A, 0x09, 0x69, 0x66, 0x20, 0x6E, 0x6F, 0x74, 0x20, + 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x50, 0x20, 0x74, 0x68, 0x65, 0x6E, + 0x0A, 0x09, 0x09, 0x69, 0x66, 0x20, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, + 0x48, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x09, 0x6C, 0x6F, + 0x63, 0x61, 0x6C, 0x20, 0x73, 0x74, 0x2C, 0x6D, 0x73, 0x67, 0x20, 0x3D, + 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x74, 0x6F, 0x28, 0x66, 0x6C, 0x61, + 0x67, 0x73, 0x2E, 0x48, 0x29, 0x0A, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, + 0x6E, 0x6F, 0x74, 0x20, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, + 0x09, 0x09, 0x09, 0x09, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28, 0x27, 0x23, + 0x27, 0x2E, 0x2E, 0x6D, 0x73, 0x67, 0x29, 0x0A, 0x09, 0x09, 0x09, 0x65, + 0x6E, 0x64, 0x0A, 0x09, 0x09, 0x09, 0x70, 0x3A, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x28, 0x29, 0x0A, 0x09, 0x09, 0x09, 0x77, 0x72, 0x69, 0x74, + 0x65, 0x74, 0x6F, 0x28, 0x29, 0x0A, 0x09, 0x09, 0x65, 0x6E, 0x64, 0x0A, + 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x65, 0x6E, 0x64, 0x0A, 0x0A }; tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua embedded: src/bin/lua/doit.lua"); lua_settop(tolua_S, top); -- cgit v1.2.3