From c7fa610be3b6e072d3da4611f6de72390ebbf446 Mon Sep 17 00:00:00 2001 From: "mtilden@gmail.com" Date: Mon, 26 Dec 2011 09:09:47 +0000 Subject: - Linux compatible fixes including updated makefile - Mersenne Twister still says uint32 but it's now signed for compatibility with random uses needing negative values - Server seed is sent to clients, but needs to be able to be signed long long later on for authentic reasons - Protocol Version is required to match to ensure client compatibility, this should probably have a settings.ini check as well as store the value there git-svn-id: http://mc-server.googlecode.com/svn/trunk@121 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/MersenneTwister.h | 2 +- source/cAggressiveMonster.cpp | 4 +++- source/cBlockToPickup.cpp | 13 ++++++++----- source/cChunk.cpp | 9 +++++---- source/cChunk.h | 2 +- source/cClientHandle.cpp | 10 +++++++--- source/cMonster.cpp | 14 +++++++++----- source/cMonster.h | 1 + source/cPassiveMonster.cpp | 4 +++- source/cPlayer.cpp | 8 +++++--- source/cWindow.h | 2 +- source/cWorld.cpp | 32 ++++++++++++++++++-------------- source/cWorld.h | 1 + source/cWorldGenerator.cpp | 17 +++++++++-------- 14 files changed, 72 insertions(+), 47 deletions(-) (limited to 'source') diff --git a/source/MersenneTwister.h b/source/MersenneTwister.h index 18f34edde..e87fe0f9b 100644 --- a/source/MersenneTwister.h +++ b/source/MersenneTwister.h @@ -63,7 +63,7 @@ class MTRand { // Data public: - typedef unsigned long uint32; // unsigned integer type, at least 32 bits + 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() diff --git a/source/cAggressiveMonster.cpp b/source/cAggressiveMonster.cpp index ff8dc72c1..d52c1c19a 100644 --- a/source/cAggressiveMonster.cpp +++ b/source/cAggressiveMonster.cpp @@ -2,6 +2,7 @@ #include "Vector3f.h" #include "cPlayer.h" +#include "MersenneTwister.h" cAggressiveMonster::cAggressiveMonster() @@ -58,7 +59,8 @@ void cAggressiveMonster::Tick(float a_Dt) if(m_SeePlayerInterval > 1) { - int rem = rand() % 3 + 1; //check most of the time but miss occasionally + MTRand r1; + int rem = r1.randInt() % 3 + 1; //check most of the time but miss occasionally m_SeePlayerInterval = 0.0; if(rem >= 2) diff --git a/source/cBlockToPickup.cpp b/source/cBlockToPickup.cpp index fb7a898ae..531c9601e 100644 --- a/source/cBlockToPickup.cpp +++ b/source/cBlockToPickup.cpp @@ -2,9 +2,11 @@ #include "Defines.h" #include "BlockID.h" #include "stdlib.h" +#include "MersenneTwister.h" ENUM_ITEM_ID cBlockToPickup::ToPickup( unsigned char a_BlockID, ENUM_ITEM_ID a_UsedItemID ) { + MTRand r1; (void)a_UsedItemID; switch( a_BlockID ) @@ -28,7 +30,7 @@ ENUM_ITEM_ID cBlockToPickup::ToPickup( unsigned char a_BlockID, ENUM_ITEM_ID a_U if( a_UsedItemID == E_ITEM_SHEARS ) return E_ITEM_LEAVES; else - if(rand() % 5 == 0) return E_ITEM_SAPLING; + if(r1.randInt() % 5 == 0) return E_ITEM_SAPLING; return E_ITEM_EMPTY; case E_BLOCK_COAL_ORE: return E_ITEM_COAL; @@ -67,17 +69,18 @@ ENUM_ITEM_ID cBlockToPickup::ToPickup( unsigned char a_BlockID, ENUM_ITEM_ID a_U char cBlockToPickup::PickupCount(unsigned char a_BlockID) { + MTRand r1; switch(a_BlockID) { case E_BLOCK_REDSTONE_ORE_GLOWING: case E_BLOCK_REDSTONE_ORE: - return rand() % 2 + 4; + return r1.randInt() % 2 + 4; case E_BLOCK_GLOWSTONE: - return rand() % 3 + 2; + return r1.randInt() % 3 + 2; case E_BLOCK_MELON: - return rand() % 8 + 3; + return r1.randInt() % 8 + 3; case E_BLOCK_LAPIS_ORE: - return rand() % 5 + 4; + return r1.randInt() % 5 + 4; default: return 1; } diff --git a/source/cChunk.cpp b/source/cChunk.cpp index 30f6d839f..4eeb5c5b8 100644 --- a/source/cChunk.cpp +++ b/source/cChunk.cpp @@ -30,6 +30,7 @@ #include "cCriticalSection.h" #include "cWorldGenerator.h" #include "cBlockToPickup.h" +#include "MersenneTwister.h" #include "packets/cPacket_DestroyEntity.h" #include "packets/cPacket_PreChunk.h" @@ -333,11 +334,11 @@ void cChunk::Tick(float a_Dt) break; }; } - + MTRand r1; // Tick dem blocks - int RandomX = rand(); - int RandomY = rand(); - int RandomZ = rand(); + int RandomX = r1.randInt(); + int RandomY = r1.randInt(); + int RandomZ = r1.randInt(); for(int i = 0; i < 50; i++) { diff --git a/source/cChunk.h b/source/cChunk.h index b794f4153..5bb64697d 100644 --- a/source/cChunk.h +++ b/source/cChunk.h @@ -82,7 +82,7 @@ public: void AddTickBlockEntity( cFurnaceEntity* a_Entity ); void RemoveTickBlockEntity( cFurnaceEntity* a_Entity ); - inline static unsigned int cChunk::MakeIndex(int x, int y, int z ) + inline static unsigned int MakeIndex(int x, int y, int z ) { if( x < 16 && x > -1 && y < 128 && y > -1 && z < 16 && z > -1 ) return y + (z * 128) + (x * 128 * 16); diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp index 00e81c416..1182e2e58 100644 --- a/source/cClientHandle.cpp +++ b/source/cClientHandle.cpp @@ -70,7 +70,6 @@ #ifndef _WIN32 #define sprintf_s(dst, size, format, ...) sprintf(dst, format, __VA_ARGS__ ) -#include // rand() #endif #define AddPistonDir( x, y, z, dir, amount ) switch(dir) { case 0: (y)-=(amount); break; case 1: (y)+=(amount); break;\ @@ -84,7 +83,7 @@ typedef std::list PacketList; struct cClientHandle::sClientHandleState { sClientHandleState() - : ProtocolVersion( 0 ) + : ProtocolVersion( 22 ) , pReceiveThread( 0 ) , pSendThread( 0 ) , pAuthenticateThread( 0 ) @@ -458,6 +457,10 @@ void cClientHandle::HandlePacket( cPacket* a_Packet ) { LOG("LOGIN %s", GetUsername() ); cPacket_Login* PacketData = reinterpret_cast(a_Packet); + if (PacketData->m_ProtocolVersion != m_pState->ProtocolVersion) { + Kick("Your client is outdated!"); + return; + } if( m_pState->Username.compare( PacketData->m_Username ) != 0 ) { Kick("Login Username does not match Handshake username!"); @@ -1243,9 +1246,10 @@ void cClientHandle::Tick(float a_Dt) LoginResponse.m_ProtocolVersion = m_Player->GetUniqueID(); //LoginResponse.m_Username = ""; LoginResponse.m_ServerMode = m_Player->GetGameMode(); //set gamemode from player. - LoginResponse.m_MapSeed = 0; + LoginResponse.m_MapSeed = cRoot::Get()->GetWorld()->GetWorldSeed(); LoginResponse.m_Dimension = 0; LoginResponse.m_MaxPlayers = (unsigned char)cRoot::Get()->GetWorld()->GetMaxPlayers(); + LoginResponse.m_Difficulty = 2; Send( LoginResponse ); // Send Weather if raining: diff --git a/source/cMonster.cpp b/source/cMonster.cpp index 18afcf8b0..217cd5367 100644 --- a/source/cMonster.cpp +++ b/source/cMonster.cpp @@ -11,6 +11,7 @@ #include "cPickup.h" #include "cItem.h" #include "cMonsterConfig.h" +#include "MersenneTwister.h" #include "packets/cPacket_SpawnMob.h" #include "packets/cPacket_EntityLook.h" @@ -64,7 +65,8 @@ cMonster::cMonster() LOG("In state: %s",GetState()); m_Health = 10; - int RandVal = rand() % 4; + MTRand r1; + int RandVal = r1.randInt() % 4; if( RandVal == 0 ) m_MobType = 90; // Pig else if( RandVal == 1 ) @@ -418,12 +420,13 @@ void cMonster::EventLosePlayer(){ void cMonster::InStateIdle(float a_Dt) { idle_interval += a_Dt; if(idle_interval > 1) { //at this interval the results are predictable - int rem = rand()%6 + 1; + MTRand r1; + int rem = r1.randInt()%6 + 1; //LOG("Moving: int: %3.3f rem: %i",idle_interval,rem); idle_interval = 0; Vector3f Dist; - Dist.x = (float)((rand()%11)-5); - Dist.z = (float)((rand()%11)-5); + 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); @@ -581,5 +584,6 @@ void cMonster::DropItem(ENUM_ITEM_ID a_Item, unsigned int a_Count) void cMonster::RandomDropItem(ENUM_ITEM_ID a_Item, unsigned int a_Min, unsigned int a_Max) { - return cMonster::DropItem(a_Item, rand() % (a_Max + 1) + a_Min); + MTRand r1; + return cMonster::DropItem(a_Item, r1.randInt() % (a_Max + 1) + a_Min); } \ No newline at end of file diff --git a/source/cMonster.h b/source/cMonster.h index 2b05c871d..6523c2e52 100644 --- a/source/cMonster.h +++ b/source/cMonster.h @@ -3,6 +3,7 @@ #include "Defines.h" #include "cWorld.h" #include "BlockID.h" +#include class Vector3f; class cClientHandle; diff --git a/source/cPassiveMonster.cpp b/source/cPassiveMonster.cpp index bbfbc83ed..1f11484ef 100644 --- a/source/cPassiveMonster.cpp +++ b/source/cPassiveMonster.cpp @@ -1,4 +1,5 @@ #include "cPassiveMonster.h" +#include "MersenneTwister.h" cPassiveMonster::cPassiveMonster() @@ -24,7 +25,8 @@ void cPassiveMonster::Tick(float a_Dt) if(m_SeePlayerInterval > 1) { - int rem = rand() % 3 + 1; //check most of the time but miss occasionally + MTRand r1; + int rem = r1.randInt() % 3 + 1; //check most of the time but miss occasionally m_SeePlayerInterval = 0.0; if(rem >= 2) { diff --git a/source/cPlayer.cpp b/source/cPlayer.cpp index 41bb24945..5fe31c8c9 100644 --- a/source/cPlayer.cpp +++ b/source/cPlayer.cpp @@ -17,6 +17,7 @@ #include "cRoot.h" #include "cMakeDir.h" #include "cTimer.h" +#include "MersenneTwister.h" #include "packets/cPacket_NamedEntitySpawn.h" #include "packets/cPacket_EntityLook.h" @@ -375,15 +376,16 @@ void cPlayer::KilledBy( cEntity* a_Killer ) m_bVisible = false; // So new clients don't see the player + MTRand r1; // Puke out all the items cItem* Items = m_Inventory->GetSlots(); for( unsigned int i = 1; i < m_Inventory->c_NumSlots; ++i ) { if( !Items[i].IsEmpty() ) { - float SpeedX = ((rand()%1000)-500) /100.f; - float SpeedY = ((rand()%1000)) /100.f; - float SpeedZ = ((rand()%1000)-500) /100.f; + float SpeedX = ((r1.randInt()%1000)-500) /100.f; + float SpeedY = ((r1.randInt()%1000)) /100.f; + float SpeedZ = ((r1.randInt()%1000)-500) /100.f; cPickup* Pickup = new cPickup( (int)(m_Pos->x*32), (int)(m_Pos->y*32), (int)(m_Pos->z*32), Items[i], SpeedX, SpeedY, SpeedZ ); Pickup->Initialize( GetWorld() ); } diff --git a/source/cWindow.h b/source/cWindow.h index d2726d171..1cc44d138 100644 --- a/source/cWindow.h +++ b/source/cWindow.h @@ -18,7 +18,7 @@ public: int GetWindowID() { return m_WindowID; } void SetWindowID( int a_WindowID ) { m_WindowID = a_WindowID; } - static enum WindowType { + enum WindowType { Chest, Workbench, Furnace, diff --git a/source/cWorld.cpp b/source/cWorld.cpp index 1dc4de6ac..382744e43 100644 --- a/source/cWorld.cpp +++ b/source/cWorld.cpp @@ -34,6 +34,7 @@ #include "cGenSettings.h" #include "cMakeDir.h" #include "cChunkGenerator.h" +#include "MersenneTwister.h" #include "packets/cPacket_TimeUpdate.h" @@ -65,7 +66,8 @@ bool g_BlockPistonBreakable[128]; #define RECI_RAND_MAX (1.f/RAND_MAX) inline float fRadRand( float a_Radius ) { - return ((float)rand() * RECI_RAND_MAX)*a_Radius - a_Radius*0.5f; + MTRand r1; + return ((float)r1.rand() * RECI_RAND_MAX)*a_Radius - a_Radius*0.5f; } struct sSetBlockData @@ -141,11 +143,11 @@ cWorld::cWorld( const char* a_WorldName ) cMakeDir::MakeDir(m_pState->WorldName.c_str()); - srand( (unsigned int) time(0) ); - m_SpawnX = (double)((rand()%1000)-500); + MTRand r1; + m_SpawnX = (double)((r1.randInt()%1000)-500); m_SpawnY = 128; - m_SpawnZ = (double)((rand()%1000)-500); - m_WorldSeed = rand(); + m_SpawnZ = (double)((r1.randInt()%1000)-500); + m_WorldSeed = r1.randInt(); m_GameMode = 0; cIniFile IniFile( m_pState->WorldName + "/world.ini"); @@ -411,11 +413,12 @@ void cWorld::Tick(float a_Dt) m_LavaSimulator->Simulate(a_Dt); UnlockChunks(); + MTRand r1; ////////////////Weather/////////////////////// if ( GetWeather() == 0 ) { //if sunny if( CurrentTick % 19 == 0 ) { //every 20 ticks random weather - randWeather = (rand() %10000); + randWeather = (r1.randInt() %10000); if (randWeather == 0) { LOG("Starting Rainstorm!"); SetWeather ( 1 ); @@ -428,7 +431,7 @@ void cWorld::Tick(float a_Dt) if ( GetWeather() != 0 ) { //if raining or thunderstorm if( CurrentTick % 19 == 0 ) { //every 20 ticks random weather - randWeather = (rand() %4999); + randWeather = (r1.randInt() %4999); if (randWeather == 0) { //2% chance per second LOG("Back to sunny!"); SetWeather ( 0 ); @@ -440,7 +443,7 @@ void cWorld::Tick(float a_Dt) } if ( GetWeather() == 2 ) { //if thunderstorm - if (rand() %199 == 0) { //0.5% chance per tick of thunderbolt + if (r1.randInt() %199 == 0) { //0.5% chance per tick of thunderbolt CastThunderbolt ( 0, 0, 0 ); //todo: find random possitions near players to cast thunderbolts. } } @@ -480,17 +483,17 @@ void cWorld::Tick(float a_Dt) cMonster *Monster = 0; //srand ( time(NULL) ); // Only seed random ONCE! Is already done in the cWorld constructor - int dayRand = rand() % 6; //added mob code - int nightRand = rand() % 10; //added mob code + int dayRand = r1.randInt() % 6; //added mob code + int nightRand = r1.randInt() % 10; //added mob code - int RandomPlayerIdx = rand() & m_pState->Players.size(); + int RandomPlayerIdx = r1.randInt() & m_pState->Players.size(); PlayerList::iterator itr = m_pState->Players.begin(); for( int i = 1; i < RandomPlayerIdx; i++ ) itr++; cPlayer* Player = *itr; Vector3d SpawnPos = Player->GetPosition(); - SpawnPos += Vector3d( (double)(rand()%64)-32, (double)(rand()%64)-32, (double)(rand()%64)-32 ); + SpawnPos += Vector3d( (double)(r1.randInt()%64)-32, (double)(r1.randInt()%64)-32, (double)(r1.randInt()%64)-32 ); char Height = GetHeight( (int)SpawnPos.x, (int)SpawnPos.z ); if(m_WorldTime >= 12000 + 1000) { @@ -581,7 +584,8 @@ void cWorld::GrowTree( int a_X, int a_Y, int a_Z ) // converted from php to lua then lua to c++ // build trunk - int trunk = rand() % (7 - 5 + 1) + 5; + MTRand r1; + int trunk = r1.randInt() % (7 - 5 + 1) + 5; for (int i = 0; i < trunk; i++) { if( GetBlock( a_X, a_Y + i, a_Z ) == E_BLOCK_AIR ) @@ -598,7 +602,7 @@ void cWorld::GrowTree( int a_X, int a_Y, int a_Z ) for (int i = a_X - radius; i <= a_X + radius; i++) { for (int k = a_Z-radius; k <= a_Z + radius; k++) { // small chance to be missing a block to add a little random - if (k != a_Z || i != a_X && (rand() % 100 + 1) > 20) { + if (k != a_Z || i != a_X && (r1.randInt() % 100 + 1) > 20) { if( GetBlock( i, a_Y + j, k ) == E_BLOCK_AIR ) FastSetBlock(i, a_Y+j, k, E_BLOCK_LEAVES, 0 ); } diff --git a/source/cWorld.h b/source/cWorld.h index 1e3e1b5a2..ec30db956 100644 --- a/source/cWorld.h +++ b/source/cWorld.h @@ -10,6 +10,7 @@ enum ENUM_ITEM_ID; #include #include +#include class cPacket; class cRedstone; diff --git a/source/cWorldGenerator.cpp b/source/cWorldGenerator.cpp index f07f5f791..b4291ddb0 100644 --- a/source/cWorldGenerator.cpp +++ b/source/cWorldGenerator.cpp @@ -3,6 +3,7 @@ #include "cWorld.h" #include "cChunk.h" #include "cGenSettings.h" +#include "MersenneTwister.h" #include "BlockID.h" #include "Vector3i.h" @@ -205,7 +206,7 @@ void cWorldGenerator::GenerateFoliage( cChunk* a_Chunk ) BlockType[ index ] = (char)GrassID; } - + MTRand r1; // Plant sum trees { int xx = x + PosX*16; @@ -215,10 +216,10 @@ void cWorldGenerator::GenerateFoliage( cChunk* a_Chunk ) float val2 = m_Noise.CubicNoise2D( xx*0.01f, zz*0.01f ); if( BlockType[index] == SandID ) { - if( (val1 + val2 > 0.f) && (rand()%128) > 124 && BlockType[index] == E_BLOCK_SAND ) + if( (val1 + val2 > 0.f) && (r1.randInt()%128) > 124 && BlockType[index] == E_BLOCK_SAND ) { BlockType[ cChunk::MakeIndex(x, TopY+1, z) ] = E_BLOCK_CACTUS; - if( (rand() & 3) == 3 ) + if( (r1.randInt() & 3) == 3 ) { BlockType[ cChunk::MakeIndex(x, TopY+2, z) ] = E_BLOCK_CACTUS; } @@ -229,15 +230,15 @@ void cWorldGenerator::GenerateFoliage( cChunk* a_Chunk ) { float val3 = m_Noise.CubicNoise2D( xx*0.01f+10, zz*0.01f+10 ); float val4 = m_Noise.CubicNoise2D( xx*0.05f+20, zz*0.05f+20 ); - if( val1 + val2 > 0.2f && (rand()%128) > 124 ) + if( val1 + val2 > 0.2f && (r1.randInt()%128) > 124 ) World->GrowTree( xx, TopY, zz ); - else if( val3 > 0.2f && (rand()%128) > 124 ) + else if( val3 > 0.2f && (r1.randInt()%128) > 124 ) BlockType[ cChunk::MakeIndex(x, TopY+1, z) ] = E_BLOCK_YELLOW_FLOWER; - else if( val4 > 0.2f && (rand()%128) > 124 ) + else if( val4 > 0.2f && (r1.randInt()%128) > 124 ) BlockType[ cChunk::MakeIndex(x, TopY+1, z) ] = E_BLOCK_RED_ROSE; - else if( val1+val2+val3+val4 > 0.2f && (rand()%128) > 124 ) + else if( val1+val2+val3+val4 > 0.2f && (r1.randInt()%128) > 124 ) BlockType[ cChunk::MakeIndex(x, TopY+1, z) ] = E_BLOCK_RED_MUSHROOM; - else if( val1+val2+val3+val4 > 0.2f && (rand()%128) > 124 ) + else if( val1+val2+val3+val4 > 0.2f && (r1.randInt()%128) > 124 ) BlockType[ cChunk::MakeIndex(x, TopY+1, z) ] = E_BLOCK_BROWN_MUSHROOM; } } -- cgit v1.2.3