diff options
41 files changed, 462 insertions, 212 deletions
diff --git a/Install/Zip2008.list b/Install/Zip2008.list index 0b45d81f3..fbfc06e0c 100644 --- a/Install/Zip2008.list +++ b/Install/Zip2008.list @@ -11,5 +11,3 @@ Lua-LICENSE.txt LuaExpat-license.html LuaSQLite3-LICENSE.txt MersenneTwister-LICENSE.txt -settings.example.ini -webadmin.example.ini
\ No newline at end of file diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index f8e201244..ebe284ad6 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2395,6 +2395,44 @@ World:ForEachEntity( }, }, -- HTTPRequest + ItemCategory = + { + Desc = [[ + This class contains static functions for determining item categories. All of the functions are + called directly on the class table, unlike most other object, which require an instance first. + ]], + Functions = + { + IsArmor = { Params = "ItemType", Return = "bool", Notes = "(STATIC) Returns true if the specified item type is any kind of an armor." }, + IsAxe = { Params = "ItemType", Return = "bool", Notes = "(STATIC) Returns true if the specified item type is any kind of an axe." }, + IsBoots = { Params = "ItemType", Return = "bool", Notes = "(STATIC) Returns true if the specified item type is any kind of boots." }, + IsChestPlate = { Params = "ItemType", Return = "bool", Notes = "(STATIC) Returns true if the specified item type is any kind of a chestplate." }, + IsHelmet = { Params = "ItemType", Return = "bool", Notes = "(STATIC) Returns true if the specified item type is any kind of a helmet." }, + IsHoe = { Params = "ItemType", Return = "bool", Notes = "(STATIC) Returns true if the specified item type is any kind of a hoe." }, + IsLeggings = { Params = "ItemType", Return = "bool", Notes = "(STATIC) Returns true if the specified item type is any kind of a leggings." }, + IsPickaxe = { Params = "ItemType", Return = "bool", Notes = "(STATIC) Returns true if the specified item type is any kind of a pickaxe." }, + IsShovel = { Params = "ItemType", Return = "bool", Notes = "(STATIC) Returns true if the specified item type is any kind of a shovel." }, + IsSword = { Params = "ItemType", Return = "bool", Notes = "(STATIC) Returns true if the specified item type is any kind of a sword." }, + IsTool = { Params = "ItemType", Return = "bool", Notes = "(STATIC) Returns true if the specified item type is any kind of a tool (axe, hoe, pickaxe, shovel or FIXME: sword)" }, + }, + AdditionalInfo = + { + { + Header = "Code example", + Contents = [[ + The following code snippet checks if the player holds a shovel. +<pre class="prettyprint lang-lua"> +-- a_Player is a {{cPlayer}} object, possibly received as a hook param +local HeldItem = a_Player:GetEquippedItem(); +if (cItemCategory:IsShovel(HeldItem.m_ItemType)) then + -- It's a shovel +end +</pre> + ]], + } + }, + }, -- ItemCategory + TakeDamageInfo = { Desc = [[The TakeDamageInfo is a struct that contains the amount of damage, and the entity that caused the damage. It is used in the {{OnTakeDamage|OnTakeDamage}}() hook and in the {{cEntity|cEntity}}'s TakeDamage() function. diff --git a/MCServer/monsters.ini b/MCServer/monsters.ini index efd801a62..94454c355 100644 --- a/MCServer/monsters.ini +++ b/MCServer/monsters.ini @@ -69,10 +69,10 @@ SightDistance=25.0 MaxHealth=20 [Ghast] -AttackRange=5.0 +AttackRange=50.0 AttackRate=1 AttackDamage=0.0 -SightDistance=25.0 +SightDistance=50.0 MaxHealth=10 [Silverfish] @@ -83,10 +83,9 @@ SightDistance=25.0 MaxHealth=8 [Skeleton] -AttackRange=5.0 +AttackRange=15.0 AttackRate=1 -AttackDamage=3.0 -SightDistance=25.0 +SightDistance=40.0 MaxHealth=20 [Slime] @@ -111,7 +110,7 @@ SightDistance=25.0 MaxHealth=20 [Blaze] -AttackRange=5.0 +AttackRange=15.0 AttackRate=1 AttackDamage=6.0 SightDistance=25.0 diff --git a/MCServer/settings.example.ini b/MCServer/settings.example.ini deleted file mode 100644 index 3daeb00f1..000000000 --- a/MCServer/settings.example.ini +++ /dev/null @@ -1,32 +0,0 @@ -; This is the main server configuration -; For help, please visit the Wiki page: http://www.mc-server.org/wiki/doku.php?id=configure:settings.ini -; Most of these settings can also be set using the webadmin interface, if it is enabled. - -[Server] -Port=25565 -MaxPlayers=100 -Description=MCServer - in C++ -DefaultViewDistance=9 - -[Worlds] -DefaultWorld=world - -[Plugins] -; Plugin=Debuggers -; Plugin=DiamondMover -; Plugin=HookNotify -Plugin=Core -Plugin=ChunkWorx -Plugin=ChatLog -Plugin=TransAPI - -[Monsters] -AnimalsOn=0 -AnimalSpawnInterval=10 -Types=Spider,Chicken,Cow,Pig,Sheep,Squid,Enderman,Zombiepigman,Cavespider,Creeper,Ghast,Silverfish,Skeleton,Slime,Spider,Zombie - -[Authentication] -Server=session.minecraft.net -Address=/game/checkserver.jsp?user=%USERNAME%&serverId=%SERVERID% -Authenticate=0 - diff --git a/MCServer/webadmin.example.ini b/MCServer/webadmin.example.ini deleted file mode 100644 index 8597225bb..000000000 --- a/MCServer/webadmin.example.ini +++ /dev/null @@ -1,6 +0,0 @@ -[WebAdmin] -Enabled=1 -Port=8081 - -[User:admin] -Password=admin
\ No newline at end of file diff --git a/nbt examples/single chunk NBT data.txt b/docs/NBT Examples/single chunk NBT data.txt index 905d6465c..905d6465c 100644 --- a/nbt examples/single chunk NBT data.txt +++ b/docs/NBT Examples/single chunk NBT data.txt diff --git a/nbt examples/tile entities.txt b/docs/NBT Examples/tile entities.txt index e16ae45a7..e16ae45a7 100644 --- a/nbt examples/tile entities.txt +++ b/docs/NBT Examples/tile entities.txt diff --git a/source/Authenticator.cpp b/source/Authenticator.cpp index e09fd0871..9a6dcf51b 100644 --- a/source/Authenticator.cpp +++ b/source/Authenticator.cpp @@ -46,28 +46,9 @@ cAuthenticator::~cAuthenticator() /// Read custom values from INI void cAuthenticator::ReadINI(cIniFile & IniFile) { - 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); - } + m_Server = IniFile.GetValueSet("Authentication", "Server", DEFAULT_AUTH_SERVER); + m_Address = IniFile.GetValueSet("Authentication", "Address", DEFAULT_AUTH_ADDRESS); + m_ShouldAuthenticate = IniFile.GetValueSetB("Authentication", "Authenticate", true); } @@ -199,7 +180,7 @@ bool cAuthenticator::AuthFromAddress(const AString & a_Server, const AString & a } else if (code == 200) { - LOGINFO("Got 200 OK :D"); + LOGD("cAuthenticator: Received status 200 OK! :D"); bOK = true; } } @@ -268,17 +249,16 @@ bool cAuthenticator::AuthFromAddress(const AString & a_Server, const AString & a std::string Result; ss >> Result; - LOGINFO("Got result: %s", Result.c_str()); - //if (Result.compare("3") == 0) // FIXME: Quick and dirty hack to support auth - //Lapayo: Wtf 3? + LOGD("cAuthenticator: Authentication result was %s", Result.c_str()); + if (Result.compare("YES") == 0) //Works well { - LOGINFO("Result was \"YES\", so player is authenticated!"); + LOGINFO("Authentication result \"YES\", player authentication success!"); return true; } - LOGINFO("Result was \"%s\", so player is NOT authenticated!", Result.c_str()); + LOGINFO("Authentication result was \"%s\", player authentication failure!", Result.c_str()); return false; } diff --git a/source/Blocks/BlockHandler.h b/source/Blocks/BlockHandler.h index 0487505ee..81d9f240c 100644 --- a/source/Blocks/BlockHandler.h +++ b/source/Blocks/BlockHandler.h @@ -66,7 +66,7 @@ public: /// Called if the user right clicks the block and the block is useable virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ); - /// Called when the item is mined to convert it into pickups. Pickups may specify multiple items. + /// Called when the item is mined to convert it into pickups. Pickups may specify multiple items. Appends items to a_Pickups, preserves its original contents virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta); /// Handles the dropping of a block based on what ConvertToDrops() returns. This will not destroy the block. a_Digger is the entity causing the drop; it may be NULL diff --git a/source/Blocks/BlockTorch.h b/source/Blocks/BlockTorch.h index a52b373cb..36383a524 100644 --- a/source/Blocks/BlockTorch.h +++ b/source/Blocks/BlockTorch.h @@ -166,19 +166,6 @@ public: } - /* - virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override - { - if (TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace)) - { - return true; - } - - return (FindSuitableFace(a_World, a_BlockX, a_BlockY, a_BlockZ) != BLOCK_FACE_BOTTOM); - } - */ - - virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { char Face = MetaDataToDirection(a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp index 6860a29ca..86a4aecc8 100644 --- a/source/ClientHandle.cpp +++ b/source/ClientHandle.cpp @@ -205,7 +205,7 @@ 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()); + LOG("Kicking user \"%s\" for \"%s\"", m_Username.c_str(), StripColorCodes(a_Reason).c_str()); } SendDisconnect(a_Reason); } @@ -255,8 +255,8 @@ void cClientHandle::Authenticate(void) // Send time m_Protocol->SendTimeUpdate(World->GetWorldAge(), World->GetTimeOfDay()); - // Send inventory - m_Player->GetInventory().SendWholeInventory(*this); + // Send contents of the inventory window + m_Protocol->SendWholeInventory(*m_Player->GetWindow()); // Send health m_Player->SendHealth(); @@ -2004,15 +2004,6 @@ void cClientHandle::SendWeather(eWeather a_Weather) -void cClientHandle::SendWholeInventory(const cInventory & a_Inventory) -{ - m_Protocol->SendWholeInventory(a_Inventory); -} - - - - - void cClientHandle::SendWholeInventory(const cWindow & a_Window) { m_Protocol->SendWholeInventory(a_Window); @@ -2196,7 +2187,7 @@ void cClientHandle::SocketClosed(void) { // The socket has been closed for any reason - LOG("Client \"%s\" @ %s disconnected", m_Username.c_str(), m_IPString.c_str()); + LOGD("Client \"%s\" @ %s disconnected", m_Username.c_str(), m_IPString.c_str()); Destroy(); } diff --git a/source/ClientHandle.h b/source/ClientHandle.h index ef6dbd124..f7fa2b36f 100644 --- a/source/ClientHandle.h +++ b/source/ClientHandle.h @@ -134,7 +134,6 @@ public: void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ); void SendWeather (eWeather a_Weather); - void SendWholeInventory (const cInventory & a_Inventory); void SendWholeInventory (const cWindow & a_Window); void SendWindowClose (const cWindow & a_Window); void SendWindowOpen (char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots); diff --git a/source/Defines.h b/source/Defines.h index 6dd81137e..60dab12be 100644 --- a/source/Defines.h +++ b/source/Defines.h @@ -35,10 +35,15 @@ extern bool g_BlockPistonBreakable[256]; /// Can this block hold snow atop? extern bool g_BlockIsSnowable[256]; +/// Does this block require a tool to drop? extern bool g_BlockRequiresSpecialTool[256]; +/// Is this block solid (player cannot walk through)? extern bool g_BlockIsSolid[256]; +/// Can torches be placed on this block? +extern bool g_BlockIsTorchPlaceable[256]; + diff --git a/source/Inventory.cpp b/source/Inventory.cpp index d5fc7f0d8..90b998358 100644 --- a/source/Inventory.cpp +++ b/source/Inventory.cpp @@ -393,15 +393,6 @@ void cInventory::CopyToItems(cItems & a_Items) -void cInventory::SendWholeInventory(cClientHandle & a_Client) -{ - a_Client.SendWholeInventory(*this); -} - - - - - void cInventory::SendSlot(int a_SlotNum) { cItem Item(GetSlot(a_SlotNum)); diff --git a/source/Inventory.h b/source/Inventory.h index f8f8042f4..3c6a19de8 100644 --- a/source/Inventory.h +++ b/source/Inventory.h @@ -110,8 +110,6 @@ public: // tolua_end - void SendWholeInventory(cClientHandle & a_Client); - /// Returns the player associated with this inventory (const version) const cPlayer & GetOwner(void) const { return m_Owner; } diff --git a/source/LeakFinder.cpp b/source/LeakFinder.cpp index 272e313a0..0f84adb2b 100644 --- a/source/LeakFinder.cpp +++ b/source/LeakFinder.cpp @@ -108,8 +108,8 @@ #include "LeakFinder.h" // Currently only tested with MS VC++ 5 to 10 -#if (_MSC_VER < 1100) || (_MSC_VER > 1700) -#error Only MS VC++ 5/6/7/7.1/8/9 supported. Check if the '_CrtMemBlockHeader' has not changed with this compiler! +#if (_MSC_VER < 1100) || (_MSC_VER > 1800) +#error Only MS VC++ 5/6/7/7.1/8/9/10/11/12 supported. Check if the '_CrtMemBlockHeader' has not changed with this compiler! #endif diff --git a/source/MobSpawner.cpp b/source/MobSpawner.cpp index d4926bbe5..dd9419ba4 100644 --- a/source/MobSpawner.cpp +++ b/source/MobSpawner.cpp @@ -71,10 +71,10 @@ cMonster::eType cMobSpawner::ChooseMobType(EMCSBiome a_Biome) addIfAllowed(cMonster::mtZombiePigman, allowedMobs); addIfAllowed(cMonster::mtMagmaCube, allowedMobs); } - /*else if (a_Biome == biEnder) MG TODO : figure out what are the biomes of the ender + else if (a_Biome == biEnd) { addIfAllowed(cMonster::mtEnderman, allowedMobs); - }*/ + } else { addIfAllowed(cMonster::mtBat, allowedMobs); @@ -210,7 +210,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R return (TargetBlock == E_BLOCK_AIR) && (BlockAbove == E_BLOCK_AIR) && (!g_BlockTransparent[BlockBelow]) && (m_Random.NextInt(20,a_Biome) == 0); default: - LOGD("MG TODO : check I've got a Rule to write for type %d",a_MobType); + LOGD("MG TODO: Write spawning rule for mob type %d", a_MobType); return false; } } diff --git a/source/Mobs/AggressiveMonster.cpp b/source/Mobs/AggressiveMonster.cpp index 88bd2743a..cc7e7da2b 100644 --- a/source/Mobs/AggressiveMonster.cpp +++ b/source/Mobs/AggressiveMonster.cpp @@ -44,7 +44,7 @@ void cAggressiveMonster::InStateChasing(float a_Dt) Vector3f Their = Vector3f( m_Target->GetPosition() ); if ((Their - Pos).Length() <= m_AttackRange) { - cMonster::Attack(a_Dt); + Attack(a_Dt); } MoveToPosition(Their + Vector3f(0, 0.65f, 0)); } diff --git a/source/Mobs/Blaze.cpp b/source/Mobs/Blaze.cpp index 74c82c081..f9c05b17a 100644 --- a/source/Mobs/Blaze.cpp +++ b/source/Mobs/Blaze.cpp @@ -2,7 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Blaze.h" - +#include "../World.h" @@ -25,3 +25,28 @@ void cBlaze::GetDrops(cItems & a_Drops, cEntity * a_Killer) + +void cBlaze::Attack(float a_Dt) +{ + m_AttackInterval += a_Dt * m_AttackRate; + + if (m_Target != NULL && m_AttackInterval > 3.0) + { + // Setting this higher gives us more wiggle room for attackrate + Vector3d Speed = GetLookVector() * 20; + Speed.y = Speed.y + 1; + cFireChargeEntity * FireCharge = new cFireChargeEntity(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); + if (FireCharge == NULL) + { + return; + } + if (!FireCharge->Initialize(m_World)) + { + delete FireCharge; + return; + } + m_World->BroadcastSpawnEntity(*FireCharge); + m_AttackInterval = 0.0; + // ToDo: Shoot 3 fireballs instead of 1. + } +}
\ No newline at end of file diff --git a/source/Mobs/Blaze.h b/source/Mobs/Blaze.h index 9df57530e..cdb3a1306 100644 --- a/source/Mobs/Blaze.h +++ b/source/Mobs/Blaze.h @@ -18,6 +18,7 @@ public: CLASS_PROTODEF(cBlaze); virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void Attack(float a_Dt) override; } ; diff --git a/source/Mobs/Ghast.cpp b/source/Mobs/Ghast.cpp index 419c8474d..96a29b2d8 100644 --- a/source/Mobs/Ghast.cpp +++ b/source/Mobs/Ghast.cpp @@ -2,7 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Ghast.h" - +#include "../World.h" @@ -25,3 +25,30 @@ void cGhast::GetDrops(cItems & a_Drops, cEntity * a_Killer) + +void cGhast::Attack(float a_Dt) +{ + m_AttackInterval += a_Dt * m_AttackRate; + + if (m_Target != NULL && m_AttackInterval > 3.0) + { + // Setting this higher gives us more wiggle room for attackrate + Vector3d Speed = GetLookVector() * 20; + Speed.y = Speed.y + 1; + cGhastFireballEntity * GhastBall = new cGhastFireballEntity(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); + if (GhastBall == NULL) + { + return; + } + if (!GhastBall->Initialize(m_World)) + { + delete GhastBall; + return; + } + m_World->BroadcastSpawnEntity(*GhastBall); + m_AttackInterval = 0.0; + } +} + + + diff --git a/source/Mobs/Ghast.h b/source/Mobs/Ghast.h index a2adc21b9..43e8bedb6 100644 --- a/source/Mobs/Ghast.h +++ b/source/Mobs/Ghast.h @@ -18,6 +18,7 @@ public: CLASS_PROTODEF(cGhast); virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void Attack(float a_Dt) override; bool IsCharging(void) const {return false; } } ; diff --git a/source/Mobs/Monster.cpp b/source/Mobs/Monster.cpp index 72dfb2583..9d2be1e29 100644 --- a/source/Mobs/Monster.cpp +++ b/source/Mobs/Monster.cpp @@ -440,12 +440,12 @@ void cMonster::InStateEscaping(float a_Dt) void cMonster::Attack(float a_Dt) { m_AttackInterval += a_Dt * m_AttackRate; - if ((m_Target != NULL) && (m_AttackInterval > 3.0)) - { - // Setting this higher gives us more wiggle room for attackrate - m_AttackInterval = 0.0; - ((cPawn *)m_Target)->TakeDamage(*this); - } + if ((m_Target != NULL) && (m_AttackInterval > 3.0)) + { + // Setting this higher gives us more wiggle room for attackrate + m_AttackInterval = 0.0; + ((cPawn *)m_Target)->TakeDamage(*this); + } } diff --git a/source/Mobs/Skeleton.cpp b/source/Mobs/Skeleton.cpp index 37a724848..509c2191e 100644 --- a/source/Mobs/Skeleton.cpp +++ b/source/Mobs/Skeleton.cpp @@ -7,7 +7,6 @@ - cSkeleton::cSkeleton(bool IsWither) : super("Skeleton", mtSkeleton, "mob.skeleton.hurt", "mob.skeleton.death", 0.6, 1.8), m_bIsWither(IsWither) @@ -28,3 +27,44 @@ void cSkeleton::GetDrops(cItems & a_Drops, cEntity * a_Killer) + +void cSkeleton::MoveToPosition(const Vector3f & a_Position) +{ + m_Destination = a_Position; + + // If the destination is in the sun and if it is not night AND the skeleton isn't on fire then block the movement. + if (!IsOnFire() && m_World->GetTimeOfDay() < 13187 && m_World->GetBlockSkyLight((int) a_Position.x, (int) a_Position.y, (int) a_Position.z) == 15) + { + m_bMovingToDestination = false; + return; + } + m_bMovingToDestination = true; +} + + + + + +void cSkeleton::Attack(float a_Dt) +{ + m_AttackInterval += a_Dt * m_AttackRate; + + if (m_Target != NULL && m_AttackInterval > 3.0) + { + // Setting this higher gives us more wiggle room for attackrate + Vector3d Speed = GetLookVector() * 20; + Speed.y = Speed.y + 1; + cArrowEntity * Arrow = new cArrowEntity(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); + if (Arrow == NULL) + { + return; + } + if (!Arrow->Initialize(m_World)) + { + delete Arrow; + return; + } + m_World->BroadcastSpawnEntity(*Arrow); + m_AttackInterval = 0.0; + } +}
\ No newline at end of file diff --git a/source/Mobs/Skeleton.h b/source/Mobs/Skeleton.h index 7a4af7e22..8f31b42e1 100644 --- a/source/Mobs/Skeleton.h +++ b/source/Mobs/Skeleton.h @@ -18,6 +18,8 @@ public: CLASS_PROTODEF(cSkeleton); virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void MoveToPosition(const Vector3f & a_Position) override; + virtual void Attack(float a_Dt) override; bool IsWither(void) const { return m_bIsWither; }; private: diff --git a/source/Mobs/Zombie.cpp b/source/Mobs/Zombie.cpp index 1752ec390..a485d2b55 100644 --- a/source/Mobs/Zombie.cpp +++ b/source/Mobs/Zombie.cpp @@ -30,3 +30,18 @@ void cZombie::GetDrops(cItems & a_Drops, cEntity * a_Killer) + +void cZombie::MoveToPosition(const Vector3f & a_Position) +{ + m_Destination = a_Position; + + // If the destination is in the sun and if it is not night AND the skeleton isn't on fire then block the movement. + if ((m_World->GetBlockSkyLight((int) a_Position.x, (int) a_Position.y, (int) a_Position.z) == 15) && (m_World->GetTimeOfDay() < 13187) && !IsOnFire()) + { + m_bMovingToDestination = false; + return; + } + m_bMovingToDestination = true; +} + + diff --git a/source/Mobs/Zombie.h b/source/Mobs/Zombie.h index 148b1121e..7e14fe42f 100644 --- a/source/Mobs/Zombie.h +++ b/source/Mobs/Zombie.h @@ -17,6 +17,7 @@ public: CLASS_PROTODEF(cZombie); virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void MoveToPosition(const Vector3f & a_Position) override; bool IsVillagerZombie(void) const {return m_bIsVillagerZombie; } bool IsConverting(void) const {return m_bIsConverting; } diff --git a/source/PluginManager.cpp b/source/PluginManager.cpp index 5ae70d48d..3ac2366ca 100644 --- a/source/PluginManager.cpp +++ b/source/PluginManager.cpp @@ -95,6 +95,17 @@ void cPluginManager::FindPlugins(void) void cPluginManager::ReloadPluginsNow(void) { + cIniFile a_SettingsIni; + a_SettingsIni.ReadFile("settings.ini"); + ReloadPluginsNow(a_SettingsIni); +} + + + + + +void cPluginManager::ReloadPluginsNow(cIniFile & a_SettingsIni) +{ LOG("-- Loading Plugins --"); m_bReloadPlugins = false; UnloadPluginsNow(); @@ -102,26 +113,21 @@ void cPluginManager::ReloadPluginsNow(void) FindPlugins(); cServer::BindBuiltInConsoleCommands(); - - cIniFile IniFile; - if (!IniFile.ReadFile("settings.ini")) + + unsigned int KeyNum = a_SettingsIni.FindKey("Plugins"); + unsigned int NumPlugins = ((KeyNum != -1) ? (a_SettingsIni.GetNumValues(KeyNum)) : 0); + if (KeyNum == -1) { - LOGWARNING("cPluginManager: Can't find settings.ini, so can't load any plugins."); + InsertDefaultPlugins(a_SettingsIni); } - - unsigned int KeyNum = IniFile.FindKey("Plugins"); - unsigned int NumPlugins = IniFile.GetNumValues(KeyNum); - if (NumPlugins > 0) + else if (NumPlugins > 0) { for(unsigned int i = 0; i < NumPlugins; i++) { - AString ValueName = IniFile.GetValueName(KeyNum, i ); - if ( - (ValueName.compare("NewPlugin") == 0) || - (ValueName.compare("Plugin") == 0) - ) + AString ValueName = a_SettingsIni.GetValueName(KeyNum, i); + if (ValueName.compare("Plugin") == 0) { - AString PluginFile = IniFile.GetValue(KeyNum, i); + AString PluginFile = a_SettingsIni.GetValue(KeyNum, i); if (!PluginFile.empty()) { if (m_Plugins.find(PluginFile) != m_Plugins.end()) @@ -137,7 +143,7 @@ void cPluginManager::ReloadPluginsNow(void) { LOG("-- No Plugins Loaded --"); } - else if ((GetNumPlugins() > 1) || (GetNumPlugins() == 0)) + else if (GetNumPlugins() > 1) { LOG("-- Loaded %i Plugins --", GetNumPlugins()); } @@ -151,6 +157,22 @@ void cPluginManager::ReloadPluginsNow(void) +void cPluginManager::InsertDefaultPlugins(cIniFile & a_SettingsIni) +{ + a_SettingsIni.AddKeyName("Plugins"); + a_SettingsIni.AddKeyComment("Plugins", " Plugin=Debuggers"); + a_SettingsIni.AddKeyComment("Plugins", " Plugin=HookNotify"); + a_SettingsIni.AddKeyComment("Plugins", " Plugin=ChunkWorx"); + a_SettingsIni.AddKeyComment("Plugins", " Plugin=APIDump"); + a_SettingsIni.SetValue("Plugins", "Plugin", "Core"); + a_SettingsIni.SetValue("Plugins", "Plugin", "TransAPI"); + a_SettingsIni.SetValue("Plugins", "Plugin", "ChatLog"); +} + + + + + void cPluginManager::Tick(float a_Dt) { while (!m_DisablePluginList.empty()) diff --git a/source/PluginManager.h b/source/PluginManager.h index 816e4a40c..4140bffb5 100644 --- a/source/PluginManager.h +++ b/source/PluginManager.h @@ -271,9 +271,18 @@ private: cPluginManager(); ~cPluginManager(); + /// Reloads all plugins, defaulting to settings.ini for settings location void ReloadPluginsNow(void); + + /// Reloads all plugins with a cIniFile object expected to be initialised to settings.ini + void ReloadPluginsNow(cIniFile & a_SettingsIni); + + /// Unloads all plugins void UnloadPluginsNow(void); + /// Handles writing default plugins if 'Plugins' key not found using a cIniFile object expected to be intialised to settings.ini + void InsertDefaultPlugins(cIniFile & a_SettingsIni); + /// Adds the plugin into the internal list of plugins and initializes it. If initialization fails, the plugin is removed again. bool AddPlugin(cPlugin * a_Plugin); diff --git a/source/Protocol/Protocol.h b/source/Protocol/Protocol.h index 6bea4edbb..5d66808cf 100644 --- a/source/Protocol/Protocol.h +++ b/source/Protocol/Protocol.h @@ -99,7 +99,6 @@ public: virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) = 0; virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) = 0; virtual void SendWeather (eWeather a_Weather) = 0; - virtual void SendWholeInventory (const cInventory & a_Inventory) = 0; virtual void SendWholeInventory (const cWindow & a_Window) = 0; virtual void SendWindowClose (const cWindow & a_Window) = 0; virtual void SendWindowOpen (char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots) = 0; diff --git a/source/Protocol/Protocol125.cpp b/source/Protocol/Protocol125.cpp index ef40f265a..4cb1197da 100644 --- a/source/Protocol/Protocol125.cpp +++ b/source/Protocol/Protocol125.cpp @@ -940,15 +940,6 @@ void cProtocol125::SendWeather(eWeather a_Weather) -void cProtocol125::SendWholeInventory(const cInventory & a_Inventory) -{ - SendWholeInventory(*(a_Inventory.GetOwner().GetWindow())); -} - - - - - void cProtocol125::SendWholeInventory(const cWindow & a_Window) { cCSLock Lock(m_CSPacket); diff --git a/source/Protocol/Protocol125.h b/source/Protocol/Protocol125.h index 1da50a1d4..ad61dea74 100644 --- a/source/Protocol/Protocol125.h +++ b/source/Protocol/Protocol125.h @@ -76,7 +76,6 @@ public: virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) override; virtual void SendWeather (eWeather a_Weather) override; - virtual void SendWholeInventory (const cInventory & a_Inventory) override; virtual void SendWholeInventory (const cWindow & a_Window) override; virtual void SendWindowClose (const cWindow & a_Window) override; virtual void SendWindowOpen (char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots) override; diff --git a/source/Protocol/Protocol17x.cpp b/source/Protocol/Protocol17x.cpp index e23ee66a5..d0ecc5583 100644 --- a/source/Protocol/Protocol17x.cpp +++ b/source/Protocol/Protocol17x.cpp @@ -10,15 +10,16 @@ Implements the 1.7.x protocol classes: #include "Globals.h" #include "Protocol17x.h" +#include "ChunkDataSerializer.h" #include "../ClientHandle.h" #include "../Root.h" #include "../Server.h" -#include "../Entities/Player.h" #include "../World.h" -#include "ChunkDataSerializer.h" -#include "../Entities/Pickup.h" #include "../WorldStorage/FastNBT.h" #include "../StringCompression.h" +#include "../Entities/FallingBlock.h" +#include "../Entities/Pickup.h" +#include "../Entities/Player.h" @@ -158,7 +159,10 @@ void cProtocol172::SendChat(const AString & a_Message) void cProtocol172::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) { - const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_3_2); // This contains the flags and bitmasks, too + // Serialize first, before creating the Packetizer (the packetizer locks a CS) + // This contains the flags and bitmasks, too + const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_3_2); + cPacketizer Pkt(*this, 0x21); // Chunk Data packet Pkt.WriteInt(a_ChunkX); Pkt.WriteInt(a_ChunkZ); @@ -250,12 +254,10 @@ void cProtocol172::SendEntityLook(const cEntity & a_Entity) void cProtocol172::SendEntityMetadata(const cEntity & a_Entity) { - /* - // TODO cPacketizer Pkt(*this, 0x1c); // Entity Metadata packet Pkt.WriteInt(a_Entity.GetUniqueID()); - WriteEntityMetadata(Pkt, a_Entity); - */ + Pkt.WriteEntityMetadata(a_Entity); + Pkt.WriteByte(0x7f); // The termination byte } @@ -565,7 +567,13 @@ void cProtocol172::SendRespawn(void) void cProtocol172::SendSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) // a_Src coords are Block * 8 { - // TODO + cPacketizer Pkt(*this, 0x29); // Sound Effect packet + Pkt.WriteString(a_SoundName); + Pkt.WriteInt(a_SrcX); + Pkt.WriteInt(a_SrcY); + Pkt.WriteInt(a_SrcZ); + Pkt.WriteFloat(a_Volume); + Pkt.WriteByte((Byte)(a_Pitch * 63)); } @@ -574,7 +582,15 @@ void cProtocol172::SendSoundEffect(const AString & a_SoundName, int a_SrcX, int void cProtocol172::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) { - // TODO + cPacketizer Pkt(*this, 0x28); // Effect packet + Pkt.WriteInt(a_EffectID); + Pkt.WriteInt(a_SrcX); + // TODO: Check if this is really an int + // wiki.vg says it's a byte, but that wouldn't cover the entire range needed (Y location * 8 = 0..2048) + Pkt.WriteInt(a_SrcY); + Pkt.WriteInt(a_SrcZ); + Pkt.WriteInt(a_Data); + Pkt.WriteBool(false); } @@ -583,7 +599,18 @@ void cProtocol172::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_Src void cProtocol172::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) { - // TODO + cPacketizer Pkt(*this, 0x0e); // Spawn Object packet + Pkt.WriteInt(a_FallingBlock.GetUniqueID()); + Pkt.WriteByte(70); // Falling block + Pkt.WriteFPInt(a_FallingBlock.GetPosX()); + Pkt.WriteFPInt(a_FallingBlock.GetPosY()); + Pkt.WriteFPInt(a_FallingBlock.GetPosZ()); + Pkt.WriteByteAngle(a_FallingBlock.GetYaw()); + Pkt.WriteByteAngle(a_FallingBlock.GetPitch()); + Pkt.WriteInt(((int)a_FallingBlock.GetBlockType()) | (((int)a_FallingBlock.GetBlockMeta()) << 12)); + Pkt.WriteShort((short)(a_FallingBlock.GetSpeedX() * 400)); + Pkt.WriteShort((short)(a_FallingBlock.GetSpeedY() * 400)); + Pkt.WriteShort((short)(a_FallingBlock.GetSpeedZ() * 400)); } @@ -592,7 +619,20 @@ void cProtocol172::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) void cProtocol172::SendSpawnMob(const cMonster & a_Mob) { - // TODO + cPacketizer Pkt(*this, 0x0f); // Spawn Mob packet + Pkt.WriteInt(a_Mob.GetUniqueID()); + Pkt.WriteByte((Byte)a_Mob.GetMobType()); + Pkt.WriteFPInt(a_Mob.GetPosX()); + Pkt.WriteFPInt(a_Mob.GetPosY()); + Pkt.WriteFPInt(a_Mob.GetPosZ()); + Pkt.WriteByteAngle(a_Mob.GetPitch()); + Pkt.WriteByteAngle(a_Mob.GetHeadYaw()); + Pkt.WriteByteAngle(a_Mob.GetYaw()); + Pkt.WriteShort((short)(a_Mob.GetSpeedX() * 400)); + Pkt.WriteShort((short)(a_Mob.GetSpeedY() * 400)); + Pkt.WriteShort((short)(a_Mob.GetSpeedZ() * 400)); + Pkt.WriteEntityMetadata(a_Mob); + Pkt.WriteByte(0x7f); // Metadata terminator } @@ -601,7 +641,21 @@ void cProtocol172::SendSpawnMob(const cMonster & a_Mob) void cProtocol172::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) { - // TODO + cPacketizer Pkt(*this, 0xe); // Spawn Object packet + Pkt.WriteInt(a_Entity.GetUniqueID()); + Pkt.WriteByte(a_ObjectType); + Pkt.WriteFPInt(a_Entity.GetPosX()); + Pkt.WriteFPInt(a_Entity.GetPosY()); + Pkt.WriteFPInt(a_Entity.GetPosZ()); + Pkt.WriteByteAngle(a_Entity.GetYaw()); + Pkt.WriteByteAngle(a_Entity.GetPitch()); + Pkt.WriteInt(a_ObjectData); + if (a_ObjectData != 0) + { + Pkt.WriteShort((short)(a_Entity.GetSpeedX() * 400)); + Pkt.WriteShort((short)(a_Entity.GetSpeedY() * 400)); + Pkt.WriteShort((short)(a_Entity.GetSpeedZ() * 400)); + } } @@ -610,7 +664,21 @@ void cProtocol172::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, void cProtocol172::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) { - // TODO + cPacketizer Pkt(*this, 0xe); // Spawn Object packet + Pkt.WriteInt(a_Vehicle.GetUniqueID()); + Pkt.WriteByte(a_VehicleType); + Pkt.WriteFPInt(a_Vehicle.GetPosX()); + Pkt.WriteFPInt(a_Vehicle.GetPosY()); + Pkt.WriteFPInt(a_Vehicle.GetPosZ()); + Pkt.WriteByteAngle(a_Vehicle.GetYaw()); + Pkt.WriteByteAngle(a_Vehicle.GetPitch()); + Pkt.WriteInt(a_VehicleSubType); + if (a_VehicleSubType != 0) + { + Pkt.WriteShort((short)(a_Vehicle.GetSpeedX() * 400)); + Pkt.WriteShort((short)(a_Vehicle.GetSpeedY() * 400)); + Pkt.WriteShort((short)(a_Vehicle.GetSpeedZ() * 400)); + } } @@ -619,7 +687,17 @@ void cProtocol172::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleTyp void cProtocol172::SendTabCompletionResults(const AStringVector & a_Results) { - // TODO + AString Results; + Results.reserve(500); // Make a moderate reservation to avoid excessive reallocations + for (AStringVector::const_iterator itr = a_Results.begin(), end = a_Results.end(); itr != end; ++itr) + { + Results.append(*itr); + Results.push_back(0); + } + + cPacketizer Pkt(*this, 0x3a); // Tab-Complete packet + Pkt.WriteVarInt(a_Results.size()); + Pkt.WriteString(Results); } @@ -628,7 +706,13 @@ void cProtocol172::SendTabCompletionResults(const AStringVector & a_Results) void cProtocol172::SendTeleportEntity(const cEntity & a_Entity) { - // TODO + cPacketizer Pkt(*this, 0x18); + Pkt.WriteInt(a_Entity.GetUniqueID()); + Pkt.WriteFPInt(a_Entity.GetPosX()); + Pkt.WriteFPInt(a_Entity.GetPosY()); + Pkt.WriteFPInt(a_Entity.GetPosZ()); + Pkt.WriteByteAngle(a_Entity.GetYaw()); + Pkt.WriteByteAngle(a_Entity.GetPitch()); } @@ -637,7 +721,12 @@ void cProtocol172::SendTeleportEntity(const cEntity & a_Entity) void cProtocol172::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ) { - // TODO + cPacketizer Pkt(*this, 0x2c); // Spawn Global Entity packet + Pkt.WriteVarInt(0); // EntityID = 0, always + Pkt.WriteByte(1); // Type = Thunderbolt + Pkt.WriteFPInt(a_BlockX); + Pkt.WriteFPInt(a_BlockY); + Pkt.WriteFPInt(a_BlockZ); } @@ -646,7 +735,9 @@ void cProtocol172::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ) void cProtocol172::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay) { - // TODO + cPacketizer Pkt(*this, 0x03); + Pkt.WriteInt64(a_WorldAge); + Pkt.WriteInt64(a_TimeOfDay); } @@ -655,7 +746,13 @@ void cProtocol172::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay) void cProtocol172::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) { - // TODO + cPacketizer Pkt(*this, 0x21); // Chunk Data packet + Pkt.WriteInt(a_ChunkX); + Pkt.WriteInt(a_ChunkZ); + Pkt.WriteBool(true); + Pkt.WriteShort(0); // Primary bitmap + Pkt.WriteShort(0); // Add bitmap + Pkt.WriteInt(0); // Compressed data size } @@ -664,16 +761,27 @@ void cProtocol172::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) void cProtocol172::SendUpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) { - // TODO + cPacketizer Pkt(*this, 0x33); + Pkt.WriteInt(a_BlockX); + Pkt.WriteShort((short)a_BlockY); + Pkt.WriteInt(a_BlockZ); + Pkt.WriteString(a_Line1); + Pkt.WriteString(a_Line2); + Pkt.WriteString(a_Line3); + Pkt.WriteString(a_Line4); } -void cProtocol172::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) +void cProtocol172::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) { - // TODO + cPacketizer Pkt(*this, 0x0a); + Pkt.WriteInt(a_Entity.GetUniqueID()); + Pkt.WriteInt(a_BlockX); + Pkt.WriteByte((Byte)a_BlockY); + Pkt.WriteInt(a_BlockZ); } @@ -682,16 +790,9 @@ void cProtocol172::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_Bloc void cProtocol172::SendWeather(eWeather a_Weather) { - // TODO -} - - - - - -void cProtocol172::SendWholeInventory(const cInventory & a_Inventory) -{ - // TODO + cPacketizer Pkt(*this, 0x2b); + Pkt.WriteByte((a_Weather == wSunny) ? 2 : 1); // begin rain / end rain + Pkt.WriteFloat(0); // unused } @@ -1294,3 +1395,61 @@ void cProtocol172::cPacketizer::WriteFPInt(double a_Value) + +void cProtocol172::cPacketizer::WriteEntityMetadata(const cEntity & a_Entity) +{ + // Common metadata: + Byte Flags = 0; + if (a_Entity.IsOnFire()) + { + Flags |= 0x01; + } + if (a_Entity.IsCrouched()) + { + Flags |= 0x02; + } + if (a_Entity.IsSprinting()) + { + Flags |= 0x08; + } + if (a_Entity.IsRclking()) + { + Flags |= 0x10; + } + if (a_Entity.IsInvisible()) + { + Flags |= 0x20; + } + WriteByte(0); // Byte(0) + index 0 + WriteByte(Flags); + + switch (a_Entity.GetEntityType()) + { + case cEntity::etPlayer: break; // TODO? + case cEntity::etPickup: + { + WriteByte((5 << 5) | 10); // Slot(5) + index 10 + WriteItem(((const cPickup &)a_Entity).GetItem()); + break; + } + case cEntity::etMonster: + { + WriteMobMetadata((const cMonster &)a_Entity); + break; + } + // TODO: Other types + } +} + + + + + +void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob) +{ + // TODO +} + + + + diff --git a/source/Protocol/Protocol17x.h b/source/Protocol/Protocol17x.h index 4be166814..f63cd8187 100644 --- a/source/Protocol/Protocol17x.h +++ b/source/Protocol/Protocol17x.h @@ -85,7 +85,6 @@ public: virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) override; virtual void SendWeather (eWeather a_Weather) override; - virtual void SendWholeInventory (const cInventory & a_Inventory) override; virtual void SendWholeInventory (const cWindow & a_Window) override; virtual void SendWindowClose (const cWindow & a_Window) override; virtual void SendWindowOpen (char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots) override; @@ -167,6 +166,8 @@ protected: void WriteItem(const cItem & a_Item); void WriteByteAngle(double a_Angle); // Writes the specified angle using a single byte void WriteFPInt(double a_Value); // Writes the double value as a 27:5 fixed-point integer + void WriteEntityMetadata(const cEntity & a_Entity); // Writes the metadata for the specified entity, not including the terminating 0x7f + void WriteMobMetadata(const cMonster & a_Mob); // Writes the mob-specific metadata for the specified mob protected: cProtocol172 & m_Protocol; diff --git a/source/Protocol/ProtocolRecognizer.cpp b/source/Protocol/ProtocolRecognizer.cpp index 67f924d7e..501e8bbe0 100644 --- a/source/Protocol/ProtocolRecognizer.cpp +++ b/source/Protocol/ProtocolRecognizer.cpp @@ -605,16 +605,6 @@ void cProtocolRecognizer::SendWeather(eWeather a_Weather) -void cProtocolRecognizer::SendWholeInventory(const cInventory & a_Inventory) -{ - ASSERT(m_Protocol != NULL); - m_Protocol->SendWholeInventory(a_Inventory); -} - - - - - void cProtocolRecognizer::SendWholeInventory(const cWindow & a_Window) { ASSERT(m_Protocol != NULL); diff --git a/source/Protocol/ProtocolRecognizer.h b/source/Protocol/ProtocolRecognizer.h index 79dc5568f..9bf550309 100644 --- a/source/Protocol/ProtocolRecognizer.h +++ b/source/Protocol/ProtocolRecognizer.h @@ -111,7 +111,6 @@ public: virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) override; virtual void SendWeather (eWeather a_Weather) override; - virtual void SendWholeInventory (const cInventory & a_Inventory) override; virtual void SendWholeInventory (const cWindow & a_Window) override; virtual void SendWindowClose (const cWindow & a_Window) override; virtual void SendWindowOpen (char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots) override; diff --git a/source/Root.cpp b/source/Root.cpp index e992ff614..8ec94629b 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -119,8 +119,12 @@ void cRoot::Start(void) cIniFile IniFile; if (!IniFile.ReadFile("settings.ini")) { - LOGWARNING("settings.ini inaccessible, all settings are reset to default values"); + LOGWARN("Regenerating settings.ini, all settings will be reset"); + IniFile.AddHeaderComment(" This is the main server configuration"); + IniFile.AddHeaderComment(" Most of the settings here can be configured using the webadmin interface, if enabled in webadmin.ini"); + IniFile.AddHeaderComment(" See: http://www.mc-server.org/wiki/doku.php?id=configure:settings.ini for further configuration help"); } + m_PrimaryServerVersion = IniFile.GetValueI("Server", "PrimaryServerVersion", 0); if (m_PrimaryServerVersion == 0) { @@ -129,7 +133,7 @@ void cRoot::Start(void) else { // Make a note in the log that the primary server version is explicitly set in the ini file - LOGINFO("settings.ini: [Server].PrimaryServerVersion set to %d.", m_PrimaryServerVersion); + LOGINFO("Primary server version set explicitly to %d.", m_PrimaryServerVersion); } LOG("Starting server..."); @@ -152,7 +156,7 @@ void cRoot::Start(void) LOGD("Loading plugin manager..."); m_PluginManager = new cPluginManager(); - m_PluginManager->ReloadPluginsNow(); + m_PluginManager->ReloadPluginsNow(IniFile); LOGD("Loading MonsterConfig..."); m_MonsterConfig = new cMonsterConfig; @@ -261,6 +265,7 @@ void cRoot::LoadWorlds(cIniFile & IniFile) return; } + bool FoundAdditionalWorlds = false; for (unsigned int i = 0; i < NumWorlds; i++) { AString ValueName = IniFile.GetValueName(KeyNum, i ); @@ -273,9 +278,15 @@ void cRoot::LoadWorlds(cIniFile & IniFile) { continue; } + FoundAdditionalWorlds = true; cWorld* NewWorld = new cWorld( WorldName.c_str() ); m_WorldsByName[ WorldName ] = NewWorld; } // for i - Worlds + + if (!FoundAdditionalWorlds) + { + IniFile.AddKeyComment("Worlds", " World=secondworld"); + } } diff --git a/source/Server.cpp b/source/Server.cpp index 879bfae5a..75ce35cb7 100644 --- a/source/Server.cpp +++ b/source/Server.cpp @@ -195,8 +195,9 @@ void cServer::PlayerDestroying(const cPlayer * a_Player) bool cServer::InitServer(cIniFile & a_SettingsIni) { - m_Description = a_SettingsIni.GetValue ("Server", "Description", "MCServer! - In C++!").c_str(); - m_MaxPlayers = a_SettingsIni.GetValueI("Server", "MaxPlayers", 100); + m_Description = a_SettingsIni.GetValueSet("Server", "Description", "MCServer - in C++!").c_str(); + m_MaxPlayers = a_SettingsIni.GetValueSetI("Server", "MaxPlayers", 100); + m_bIsHardcore = a_SettingsIni.GetValueSetB("Server", "HardcoreEnabled", false); m_PlayerCount = 0; m_PlayerCountDiff = 0; @@ -320,7 +321,7 @@ void cServer::OnConnectionAccepted(cSocket & a_Socket) return; } - LOG("Client \"%s\" connected!", ClientIP.c_str()); + LOGD("Client \"%s\" connected!", ClientIP.c_str()); cClientHandle * NewHandle = new cClientHandle(&a_Socket, m_ClientViewDistance); if (!m_SocketThreads.AddClient(a_Socket, NewHandle)) @@ -507,7 +508,7 @@ void cServer::BindBuiltInConsoleCommands(void) PlgMgr->BindConsoleCommand("chunkstats", NULL, " - Displays detailed chunk memory statistics"); #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) PlgMgr->BindConsoleCommand("dumpmem", NULL, " - Dumps all used memory blocks together with their callstacks into memdump.xml"); - #endif + #endif } diff --git a/source/Server.h b/source/Server.h index b4fe81d8f..6742153ac 100644 --- a/source/Server.h +++ b/source/Server.h @@ -46,6 +46,9 @@ public: // tolua_export int GetNumPlayers(void); void SetMaxPlayers(int a_MaxPlayers) { m_MaxPlayers = a_MaxPlayers; } + // Hardcore mode or not: + bool IsHardcore(void) const {return m_bIsHardcore; } + // tolua_end bool Start(void); @@ -161,6 +164,7 @@ private: AString m_Description; int m_MaxPlayers; + bool m_bIsHardcore; cTickThread m_TickThread; cEvent m_RestartEvent; diff --git a/source/WebAdmin.cpp b/source/WebAdmin.cpp index 8c95e4e21..7a1d332a5 100644 --- a/source/WebAdmin.cpp +++ b/source/WebAdmin.cpp @@ -56,7 +56,7 @@ cWebAdmin::~cWebAdmin() { if (m_IsInitialized) { - LOG("Stopping WebAdmin..."); + LOGD("Stopping WebAdmin..."); } } @@ -87,7 +87,11 @@ bool cWebAdmin::Init(void) { if (!m_IniFile.ReadFile("webadmin.ini")) { - return false; + LOGWARN("Regenerating webadmin.ini, all settings will be reset"); + m_IniFile.AddHeaderComment(" This file controls the webadmin feature of MCServer"); + m_IniFile.AddHeaderComment(" Username format: [User:*username*] | Password format: Password=*password*; for example:"); + m_IniFile.AddHeaderComment(" [User:admin]"); + m_IniFile.AddHeaderComment(" Password=admin"); } if (!m_IniFile.GetValueSetB("WebAdmin", "Enabled", true)) @@ -96,7 +100,7 @@ bool cWebAdmin::Init(void) return true; } - LOG("Initialising WebAdmin..."); + LOGD("Initialising WebAdmin..."); AString PortsIPv4 = m_IniFile.GetValueSet("WebAdmin", "Port", "8080"); AString PortsIPv6 = m_IniFile.GetValueSet("WebAdmin", "PortsIPv6", ""); @@ -106,6 +110,7 @@ bool cWebAdmin::Init(void) return false; } m_IsInitialized = true; + m_IniFile.WriteFile("webadmin.ini"); return true; } @@ -121,7 +126,7 @@ bool cWebAdmin::Start(void) return false; } - LOG("Starting WebAdmin..."); + LOGD("Starting WebAdmin..."); // Initialize the WebAdmin template script and load the file m_TemplateScript.Create(); diff --git a/source/World.cpp b/source/World.cpp index dd3965e3d..c6bc47be5 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -509,7 +509,7 @@ void cWorld::Start(void) break; } } - m_bAnimals = IniFile.GetValueB("Monsters", "AnimalsOn", true); + m_bAnimals = IniFile.GetValueSetB("Monsters", "AnimalsOn", true); AString AllMonsters = IniFile.GetValueSet("Monsters", "Types", DefaultMonsters); AStringVector SplitList = StringSplitAndTrim(AllMonsters, ","); for (AStringVector::const_iterator itr = SplitList.begin(), end = SplitList.end(); itr != end; ++itr) @@ -784,8 +784,8 @@ void cWorld::TickMobs(float a_Dt) SpawnMobFinalize(*itr2); } } - } // for i - AllFamilies[] - } // if (Spawning enabled) + } // for i - AllFamilies[] + } // if (Spawning enabled) // move close mobs cMobProximityCounter::sIterablePair allCloseEnoughToMoveMobs = MobCensus.GetProximityCounter().getMobWithinThosesDistances(-1, 64 * 16);// MG TODO : deal with this magic number (the 16 is the size of a block) |