summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Install/Zip2008.list2
-rw-r--r--MCServer/Plugins/APIDump/APIDesc.lua38
-rw-r--r--MCServer/monsters.ini11
-rw-r--r--MCServer/settings.example.ini32
-rw-r--r--MCServer/webadmin.example.ini6
-rw-r--r--docs/NBT Examples/single chunk NBT data.txt (renamed from nbt examples/single chunk NBT data.txt)0
-rw-r--r--docs/NBT Examples/tile entities.txt (renamed from nbt examples/tile entities.txt)0
-rw-r--r--source/Authenticator.cpp36
-rw-r--r--source/Blocks/BlockHandler.h2
-rw-r--r--source/Blocks/BlockTorch.h13
-rw-r--r--source/ClientHandle.cpp17
-rw-r--r--source/ClientHandle.h1
-rw-r--r--source/Defines.h5
-rw-r--r--source/Inventory.cpp9
-rw-r--r--source/Inventory.h2
-rw-r--r--source/LeakFinder.cpp4
-rw-r--r--source/MobSpawner.cpp6
-rw-r--r--source/Mobs/AggressiveMonster.cpp2
-rw-r--r--source/Mobs/Blaze.cpp27
-rw-r--r--source/Mobs/Blaze.h1
-rw-r--r--source/Mobs/Ghast.cpp29
-rw-r--r--source/Mobs/Ghast.h1
-rw-r--r--source/Mobs/Monster.cpp12
-rw-r--r--source/Mobs/Skeleton.cpp42
-rw-r--r--source/Mobs/Skeleton.h2
-rw-r--r--source/Mobs/Zombie.cpp15
-rw-r--r--source/Mobs/Zombie.h1
-rw-r--r--source/PluginManager.cpp52
-rw-r--r--source/PluginManager.h9
-rw-r--r--source/Protocol/Protocol.h1
-rw-r--r--source/Protocol/Protocol125.cpp9
-rw-r--r--source/Protocol/Protocol125.h1
-rw-r--r--source/Protocol/Protocol17x.cpp223
-rw-r--r--source/Protocol/Protocol17x.h3
-rw-r--r--source/Protocol/ProtocolRecognizer.cpp10
-rw-r--r--source/Protocol/ProtocolRecognizer.h1
-rw-r--r--source/Root.cpp17
-rw-r--r--source/Server.cpp9
-rw-r--r--source/Server.h4
-rw-r--r--source/WebAdmin.cpp13
-rw-r--r--source/World.cpp6
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)