Merge branch 'master' into VillageGen
This commit is contained in:
commit
dff71823d4
@ -39,7 +39,8 @@ pre
|
|||||||
|
|
||||||
body
|
body
|
||||||
{
|
{
|
||||||
min-width: 800px;
|
min-width: 400px;
|
||||||
|
max-width: 1200px;
|
||||||
width: 95%;
|
width: 95%;
|
||||||
margin: 10px auto;
|
margin: 10px auto;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 5c8557d4fdfa580c100510cde07a1a778ea2e244
|
Subproject commit 3790f78d3f7503ff33a423b8e73e81a275562783
|
29
README.md
29
README.md
@ -1,38 +1,39 @@
|
|||||||
MCServer
|
MCServer [![Build Status](http://img.shields.io/travis/mc-server/MCServer.svg)](https://travis-ci.org/mc-server/MCServer) [![Support via Gittip](http://img.shields.io/gittip/mcs_team.svg)](https://www.gittip.com/mcs_team) [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74)
|
||||||
========
|
========
|
||||||
|
|
||||||
**Current Protocol Supported:** Minecraft v1.2 -> v1.7
|
MCServer is a Minecraft server that is written in C++ and designed to be efficient with memory and CPU, as well as having a flexible Lua Plugin API.
|
||||||
|
|
||||||
MCServer is a performant C++ Minecraft server designed for use in memory and cpu-limited places, or just to make regular server perform better.
|
|
||||||
|
|
||||||
MCServer can run on PCs, Macs, and *nix. This includes android phones and tablets as well as Raspberry Pis.
|
MCServer can run on PCs, Macs, and *nix. This includes android phones and tablets as well as Raspberry Pis.
|
||||||
|
|
||||||
|
We currently support the protocol from Minecraft 1.2 all the way up to Minecraft 1.7.9.
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
|
|
||||||
To install MCServer, you can either download the repository and compile it, or download a pre-compiled version.
|
Normally, you will want to download a pre-compiled version of MCServer from one of the buildservers:
|
||||||
|
|
||||||
If you've cloned the repository using Git, you need to pull down the submodules (core plugins, some dependencies). This can be achieved with `git submodule init` and then on a regular basis (to keep up to date) `git submodule update`.
|
* [Linux and Raspberry Pi](http://ci.bearbin.net) (Bearbin's CI Server)
|
||||||
|
* [Windows](http://mc-server.xoft.cz) (xoft's nightly build service)
|
||||||
|
|
||||||
If you downloaded a ZIP file of the sources instead, you will need to download PolarSSL, too, from https://github.com/polarssl/polarssl , and unpack it into the `lib/polarssl` folder. You will also need to manually download all the plugins that you want included.
|
You simply need to download and extract these files before you can use the server.
|
||||||
|
|
||||||
Compilation instructions are available in the COMPILING file.
|
If you're a more advanced user, you may want to compile the server yourself for more performance. See the [COMPILING.md](https://github.com/mc-server/MCServer/blob/master/COMPILING.md) file for more details.
|
||||||
|
|
||||||
Linux builds can be downloaded from [Bearbin's CI Service](http://ci.bearbin.net) and Windows builds from xoft's [nightly build service](http://mc-server.xoft.cz).
|
|
||||||
|
|
||||||
After you've extracted the files, simply run the MCServer executable.
|
|
||||||
|
|
||||||
Contributing
|
Contributing
|
||||||
------------
|
------------
|
||||||
|
|
||||||
MCServer is licensed under the Apache license V2, and we welcome anybody to fork and submit a Pull Request back with their changes, and if you want to join as a permanent member we can add you to the team.
|
MCServer is licensed under the Apache license V2, and we welcome anybody to fork and submit a Pull Request back with their changes, and if you want to join as a permanent member we can add you to the team.
|
||||||
|
|
||||||
|
Check out the [CONTRIBUTING.md](https://github.com/mc-server/MCServer/blob/master/CONTRIBUTING.md) file for more details.
|
||||||
|
|
||||||
Other Stuff
|
Other Stuff
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
For other stuff, including plugins and discussion, check the [forums](http://forum.mc-server.org) and [wiki](http://wiki.mc-server.org/).
|
For other stuff, including plugins and discussion, check the [forums](http://forum.mc-server.org) and [Plugin API](http://mc-server.xoft.cz/LuaAPI/).
|
||||||
|
|
||||||
Earn bitcoins for commits or donate to reward the MCServer developers: [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74)
|
Earn bitcoins for commits or donate to reward the MCServer developers: [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74)
|
||||||
|
|
||||||
Travis CI: [![Build Status](https://travis-ci.org/mc-server/MCServer.png?branch=master)](https://travis-ci.org/mc-server/MCServer)
|
Support Us on Gittip: [![Support via Gittip](http://img.shields.io/gittip/mcs_team.svg)](https://www.gittip.com/mcs_team)
|
||||||
|
|
||||||
|
Travis CI: [![Build Status](http://img.shields.io/travis/mc-server/MCServer.svg)](https://travis-ci.org/mc-server/MCServer)
|
||||||
|
|
||||||
|
@ -1391,28 +1391,8 @@ void cClientHandle::HandlePlayerLook(float a_Rotation, float a_Pitch, bool a_IsO
|
|||||||
|
|
||||||
void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Rotation, float a_Pitch, bool a_IsOnGround)
|
void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Rotation, float a_Pitch, bool a_IsOnGround)
|
||||||
{
|
{
|
||||||
if ((m_Player == NULL) || (m_State != csPlaying))
|
HandlePlayerLook(a_Rotation, a_Pitch, a_IsOnGround);
|
||||||
{
|
HandlePlayerPos(a_PosX, a_PosY, a_PosZ, a_Stance, a_IsOnGround);
|
||||||
// The client hasn't been spawned yet and sends nonsense, we know better
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
// TODO: Invalid stance check
|
|
||||||
if ((a_PosY >= a_Stance) || (a_Stance > a_PosY + 1.65))
|
|
||||||
{
|
|
||||||
LOGD("Invalid stance");
|
|
||||||
SendPlayerMoveLook();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
m_Player->MoveTo(Vector3d(a_PosX, a_PosY, a_PosZ));
|
|
||||||
m_Player->SetStance (a_Stance);
|
|
||||||
m_Player->SetTouchGround(a_IsOnGround);
|
|
||||||
m_Player->SetHeadYaw (a_Rotation);
|
|
||||||
m_Player->SetYaw (a_Rotation);
|
|
||||||
m_Player->SetPitch (a_Pitch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,9 +80,9 @@ public:
|
|||||||
static AString GenerateOfflineUUID(const AString & a_Username); // tolua_export
|
static AString GenerateOfflineUUID(const AString & a_Username); // tolua_export
|
||||||
|
|
||||||
/** Formats the type of message with the proper color and prefix for sending to the client. **/
|
/** Formats the type of message with the proper color and prefix for sending to the client. **/
|
||||||
AString FormatMessageType(bool ShouldAppendChatPrefixes, eMessageType a_ChatPrefix, const AString & a_AdditionalData);
|
static AString FormatMessageType(bool ShouldAppendChatPrefixes, eMessageType a_ChatPrefix, const AString & a_AdditionalData);
|
||||||
|
|
||||||
AString FormatChatPrefix(bool ShouldAppendChatPrefixes, AString a_ChatPrefixS, AString m_Color1, AString m_Color2);
|
static AString FormatChatPrefix(bool ShouldAppendChatPrefixes, AString a_ChatPrefixS, AString m_Color1, AString m_Color2);
|
||||||
|
|
||||||
void Kick(const AString & a_Reason); // tolua_export
|
void Kick(const AString & a_Reason); // tolua_export
|
||||||
void Authenticate(const AString & a_Name, const AString & a_UUID); // Called by cAuthenticator when the user passes authentication
|
void Authenticate(const AString & a_Name, const AString & a_UUID); // Called by cAuthenticator when the user passes authentication
|
||||||
|
@ -189,6 +189,15 @@ void cCompositeChat::AddSuggestCommandPart(const AString & a_Text, const AString
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cCompositeChat::AddShowAchievementPart(const AString & a_PlayerName, const AString & a_Achievement, const AString & a_Style)
|
||||||
|
{
|
||||||
|
m_Parts.push_back(new cShowAchievementPart(a_PlayerName, a_Achievement, a_Style));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cCompositeChat::ParseText(const AString & a_ParseText)
|
void cCompositeChat::ParseText(const AString & a_ParseText)
|
||||||
{
|
{
|
||||||
size_t len = a_ParseText.length();
|
size_t len = a_ParseText.length();
|
||||||
@ -290,9 +299,10 @@ void cCompositeChat::ParseText(const AString & a_ParseText)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cCompositeChat::SetMessageType(eMessageType a_MessageType)
|
void cCompositeChat::SetMessageType(eMessageType a_MessageType, const AString & a_AdditionalMessageTypeData)
|
||||||
{
|
{
|
||||||
m_MessageType = a_MessageType;
|
m_MessageType = a_MessageType;
|
||||||
|
m_AdditionalMessageTypeData = a_AdditionalMessageTypeData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -476,3 +486,16 @@ cCompositeChat::cSuggestCommandPart::cSuggestCommandPart(const AString & a_Text,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// cCompositeChat::cShowAchievementPart:
|
||||||
|
|
||||||
|
cCompositeChat::cShowAchievementPart::cShowAchievementPart(const AString & a_PlayerName, const AString & a_Achievement, const AString & a_Style) :
|
||||||
|
super(ptShowAchievement, a_Achievement, a_Style),
|
||||||
|
m_PlayerName(a_PlayerName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ public:
|
|||||||
ptUrl,
|
ptUrl,
|
||||||
ptRunCommand,
|
ptRunCommand,
|
||||||
ptSuggestCommand,
|
ptSuggestCommand,
|
||||||
|
ptShowAchievement,
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
class cBasePart
|
class cBasePart
|
||||||
@ -46,6 +47,7 @@ public:
|
|||||||
ePartType m_PartType;
|
ePartType m_PartType;
|
||||||
AString m_Text;
|
AString m_Text;
|
||||||
AString m_Style;
|
AString m_Style;
|
||||||
|
AString m_AdditionalStyleData;
|
||||||
|
|
||||||
cBasePart(ePartType a_PartType, const AString & a_Text, const AString & a_Style = "");
|
cBasePart(ePartType a_PartType, const AString & a_Text, const AString & a_Style = "");
|
||||||
|
|
||||||
@ -106,6 +108,15 @@ public:
|
|||||||
public:
|
public:
|
||||||
cSuggestCommandPart(const AString & a_Text, const AString & a_Command, const AString & a_Style = "");
|
cSuggestCommandPart(const AString & a_Text, const AString & a_Command, const AString & a_Style = "");
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
class cShowAchievementPart :
|
||||||
|
public cBasePart
|
||||||
|
{
|
||||||
|
typedef cBasePart super;
|
||||||
|
public:
|
||||||
|
AString m_PlayerName;
|
||||||
|
cShowAchievementPart(const AString & a_PlayerName, const AString & a_Achievement, const AString & a_Style = "");
|
||||||
|
} ;
|
||||||
|
|
||||||
typedef std::vector<cBasePart *> cParts;
|
typedef std::vector<cBasePart *> cParts;
|
||||||
|
|
||||||
@ -148,13 +159,20 @@ public:
|
|||||||
/** Adds a part that suggests a command (enters it into the chat message area, but doesn't send) when clicked.
|
/** Adds a part that suggests a command (enters it into the chat message area, but doesn't send) when clicked.
|
||||||
The default style is underlined yellow text. */
|
The default style is underlined yellow text. */
|
||||||
void AddSuggestCommandPart(const AString & a_Text, const AString & a_SuggestedCommand, const AString & a_Style = "u@b");
|
void AddSuggestCommandPart(const AString & a_Text, const AString & a_SuggestedCommand, const AString & a_Style = "u@b");
|
||||||
|
|
||||||
|
/** Adds a part that fully formats a specified achievement using client translatable strings
|
||||||
|
Takes achievement name and player awarded to. Displays as {player} has earned the achievement {achievement_name}.
|
||||||
|
*/
|
||||||
|
void AddShowAchievementPart(const AString & a_PlayerName, const AString & a_Achievement, const AString & a_Style = "");
|
||||||
|
|
||||||
/** Parses text into various parts, adds those.
|
/** Parses text into various parts, adds those.
|
||||||
Recognizes "http:" and "https:" URLs and @color-codes. */
|
Recognizes "http:" and "https:" URLs and @color-codes. */
|
||||||
void ParseText(const AString & a_ParseText);
|
void ParseText(const AString & a_ParseText);
|
||||||
|
|
||||||
/** Sets the message type, which is indicated by prefixes added to the message when serializing. */
|
/** Sets the message type, which is indicated by prefixes added to the message when serializing
|
||||||
void SetMessageType(eMessageType a_MessageType);
|
Takes optional AdditionalMessageTypeData to set m_AdditionalMessageTypeData. See said variable for more documentation.
|
||||||
|
*/
|
||||||
|
void SetMessageType(eMessageType a_MessageType, const AString & a_AdditionalMessageTypeData = "");
|
||||||
|
|
||||||
/** Adds the "underline" style to each part that is an URL. */
|
/** Adds the "underline" style to each part that is an URL. */
|
||||||
void UnderlineUrls(void);
|
void UnderlineUrls(void);
|
||||||
@ -163,6 +181,9 @@ public:
|
|||||||
|
|
||||||
/** Returns the message type set previously by SetMessageType(). */
|
/** Returns the message type set previously by SetMessageType(). */
|
||||||
eMessageType GetMessageType(void) const { return m_MessageType; }
|
eMessageType GetMessageType(void) const { return m_MessageType; }
|
||||||
|
|
||||||
|
/** Returns additional data pertaining to message type, for example, the name of a mtPrivateMsg sender */
|
||||||
|
AString GetAdditionalMessageTypeData(void) const { return m_AdditionalMessageTypeData; }
|
||||||
|
|
||||||
/** Returns the text from the parts that comprises the human-readable data.
|
/** Returns the text from the parts that comprises the human-readable data.
|
||||||
Used for older protocols that don't support composite chat
|
Used for older protocols that don't support composite chat
|
||||||
@ -184,6 +205,9 @@ protected:
|
|||||||
/** The message type, as indicated by prefixes. */
|
/** The message type, as indicated by prefixes. */
|
||||||
eMessageType m_MessageType;
|
eMessageType m_MessageType;
|
||||||
|
|
||||||
|
/** Additional data pertaining to message type, for example, the name of a mtPrivateMsg sender */
|
||||||
|
AString m_AdditionalMessageTypeData;
|
||||||
|
|
||||||
|
|
||||||
/** Adds a_AddStyle to a_Style; overwrites the existing style if appropriate.
|
/** Adds a_AddStyle to a_Style; overwrites the existing style if appropriate.
|
||||||
If the style already contains something that a_AddStyle overrides, it is erased first. */
|
If the style already contains something that a_AddStyle overrides, it is erased first. */
|
||||||
|
@ -1018,16 +1018,17 @@ void cEntity::TickInVoid(cChunk & a_Chunk)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cEntity::DetectCacti()
|
void cEntity::DetectCacti(void)
|
||||||
{
|
{
|
||||||
int X = POSX_TOINT, Y = POSY_TOINT, Z = POSZ_TOINT;
|
int X = POSX_TOINT, Y = POSY_TOINT, Z = POSZ_TOINT;
|
||||||
float w = m_Width / 2;
|
double w = m_Width / 2;
|
||||||
if (
|
if (
|
||||||
(((X + 1) - GetPosX() < w) && (GetWorld()->GetBlock(X + 1, Y, Z) == E_BLOCK_CACTUS)) ||
|
((Y > 0) && (Y < cChunkDef::Height)) &&
|
||||||
(((GetPosX() - (X - 1)) - 1 < w) && (GetWorld()->GetBlock(X - 1, Y, Z) == E_BLOCK_CACTUS)) ||
|
((((X + 1) - GetPosX() < w) && (GetWorld()->GetBlock(X + 1, Y, Z) == E_BLOCK_CACTUS)) ||
|
||||||
|
((GetPosX() - X < w) && (GetWorld()->GetBlock(X - 1, Y, Z) == E_BLOCK_CACTUS)) ||
|
||||||
(((Z + 1) - GetPosZ() < w) && (GetWorld()->GetBlock(X, Y, Z + 1) == E_BLOCK_CACTUS)) ||
|
(((Z + 1) - GetPosZ() < w) && (GetWorld()->GetBlock(X, Y, Z + 1) == E_BLOCK_CACTUS)) ||
|
||||||
(((GetPosZ() - (Z - 1)) - 1 < w) && (GetWorld()->GetBlock(X, Y, Z - 1) == E_BLOCK_CACTUS)) ||
|
((GetPosZ() - Z < w) && (GetWorld()->GetBlock(X, Y, Z - 1) == E_BLOCK_CACTUS)) ||
|
||||||
(((Y > 0) && (Y < cChunkDef::Height)) && ((GetPosY() - Y < 1) && (GetWorld()->GetBlock(X, Y, Z) == E_BLOCK_CACTUS)))
|
(((GetPosY() - Y < 1) && (GetWorld()->GetBlock(X, Y, Z) == E_BLOCK_CACTUS))))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
TakeDamage(dtCactusContact, NULL, 1, 0);
|
TakeDamage(dtCactusContact, NULL, 1, 0);
|
||||||
|
@ -377,7 +377,7 @@ short cPlayer::DeltaExperience(short a_Xp_delta)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LOGD("Player \"%s\" gained/lost %d experience, total is now: %d",
|
LOGD("Player \"%s\" gained/lost %d experience, total is now: %d",
|
||||||
m_PlayerName.c_str(), a_Xp_delta, m_CurrentXp);
|
GetName().c_str(), a_Xp_delta, m_CurrentXp);
|
||||||
|
|
||||||
// Set experience to be updated
|
// Set experience to be updated
|
||||||
m_bDirtyExperience = true;
|
m_bDirtyExperience = true;
|
||||||
@ -391,7 +391,7 @@ short cPlayer::DeltaExperience(short a_Xp_delta)
|
|||||||
|
|
||||||
void cPlayer::StartChargingBow(void)
|
void cPlayer::StartChargingBow(void)
|
||||||
{
|
{
|
||||||
LOGD("Player \"%s\" started charging their bow", m_PlayerName.c_str());
|
LOGD("Player \"%s\" started charging their bow", GetName().c_str());
|
||||||
m_IsChargingBow = true;
|
m_IsChargingBow = true;
|
||||||
m_BowCharge = 0;
|
m_BowCharge = 0;
|
||||||
}
|
}
|
||||||
@ -402,7 +402,7 @@ void cPlayer::StartChargingBow(void)
|
|||||||
|
|
||||||
int cPlayer::FinishChargingBow(void)
|
int cPlayer::FinishChargingBow(void)
|
||||||
{
|
{
|
||||||
LOGD("Player \"%s\" finished charging their bow at a charge of %d", m_PlayerName.c_str(), m_BowCharge);
|
LOGD("Player \"%s\" finished charging their bow at a charge of %d", GetName().c_str(), m_BowCharge);
|
||||||
int res = m_BowCharge;
|
int res = m_BowCharge;
|
||||||
m_IsChargingBow = false;
|
m_IsChargingBow = false;
|
||||||
m_BowCharge = 0;
|
m_BowCharge = 0;
|
||||||
@ -415,7 +415,7 @@ int cPlayer::FinishChargingBow(void)
|
|||||||
|
|
||||||
void cPlayer::CancelChargingBow(void)
|
void cPlayer::CancelChargingBow(void)
|
||||||
{
|
{
|
||||||
LOGD("Player \"%s\" cancelled charging their bow at a charge of %d", m_PlayerName.c_str(), m_BowCharge);
|
LOGD("Player \"%s\" cancelled charging their bow at a charge of %d", GetName().c_str(), m_BowCharge);
|
||||||
m_IsChargingBow = false;
|
m_IsChargingBow = false;
|
||||||
m_BowCharge = 0;
|
m_BowCharge = 0;
|
||||||
}
|
}
|
||||||
@ -1179,8 +1179,8 @@ unsigned int cPlayer::AwardAchievement(const eStatistic a_Ach)
|
|||||||
{
|
{
|
||||||
// First time, announce it
|
// First time, announce it
|
||||||
cCompositeChat Msg;
|
cCompositeChat Msg;
|
||||||
Msg.AddTextPart(m_PlayerName + " has just earned the achievement ");
|
Msg.SetMessageType(mtSuccess);
|
||||||
Msg.AddTextPart(cStatInfo::GetName(a_Ach)); // TODO 2014-05-12 xdot: Use the proper cCompositeChat part (cAchievement)
|
Msg.AddShowAchievementPart(GetName(), cStatInfo::GetName(a_Ach));
|
||||||
m_World->BroadcastChat(Msg);
|
m_World->BroadcastChat(Msg);
|
||||||
|
|
||||||
// Increment the statistic
|
// Increment the statistic
|
||||||
@ -1315,7 +1315,7 @@ void cPlayer::AddToGroup( const AString & a_GroupName )
|
|||||||
{
|
{
|
||||||
cGroup* Group = cRoot::Get()->GetGroupManager()->GetGroup( a_GroupName );
|
cGroup* Group = cRoot::Get()->GetGroupManager()->GetGroup( a_GroupName );
|
||||||
m_Groups.push_back( Group );
|
m_Groups.push_back( Group );
|
||||||
LOGD("Added %s to group %s", m_PlayerName.c_str(), a_GroupName.c_str() );
|
LOGD("Added %s to group %s", GetName().c_str(), a_GroupName.c_str() );
|
||||||
ResolveGroups();
|
ResolveGroups();
|
||||||
ResolvePermissions();
|
ResolvePermissions();
|
||||||
}
|
}
|
||||||
@ -1339,13 +1339,13 @@ void cPlayer::RemoveFromGroup( const AString & a_GroupName )
|
|||||||
|
|
||||||
if( bRemoved )
|
if( bRemoved )
|
||||||
{
|
{
|
||||||
LOGD("Removed %s from group %s", m_PlayerName.c_str(), a_GroupName.c_str() );
|
LOGD("Removed %s from group %s", GetName().c_str(), a_GroupName.c_str() );
|
||||||
ResolveGroups();
|
ResolveGroups();
|
||||||
ResolvePermissions();
|
ResolvePermissions();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOGWARN("Tried to remove %s from group %s but was not in that group", m_PlayerName.c_str(), a_GroupName.c_str() );
|
LOGWARN("Tried to remove %s from group %s but was not in that group", GetName().c_str(), a_GroupName.c_str() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1451,7 +1451,7 @@ void cPlayer::ResolveGroups()
|
|||||||
if( AllGroups.find( CurrentGroup ) != AllGroups.end() )
|
if( AllGroups.find( CurrentGroup ) != AllGroups.end() )
|
||||||
{
|
{
|
||||||
LOGWARNING("ERROR: Player \"%s\" is in the group multiple times (\"%s\"). Please fix your settings in users.ini!",
|
LOGWARNING("ERROR: Player \"%s\" is in the group multiple times (\"%s\"). Please fix your settings in users.ini!",
|
||||||
m_PlayerName.c_str(), CurrentGroup->GetName().c_str()
|
GetName().c_str(), CurrentGroup->GetName().c_str()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1463,7 +1463,7 @@ void cPlayer::ResolveGroups()
|
|||||||
{
|
{
|
||||||
if( AllGroups.find( *itr ) != AllGroups.end() )
|
if( AllGroups.find( *itr ) != AllGroups.end() )
|
||||||
{
|
{
|
||||||
LOGERROR("ERROR: Player %s is in the same group multiple times due to inheritance (%s). FIX IT!", m_PlayerName.c_str(), (*itr)->GetName().c_str() );
|
LOGERROR("ERROR: Player %s is in the same group multiple times due to inheritance (%s). FIX IT!", GetName().c_str(), (*itr)->GetName().c_str() );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ToIterate.push_back( *itr );
|
ToIterate.push_back( *itr );
|
||||||
@ -1615,19 +1615,19 @@ void cPlayer::LoadPermissionsFromDisk()
|
|||||||
cIniFile IniFile;
|
cIniFile IniFile;
|
||||||
if (IniFile.ReadFile("users.ini"))
|
if (IniFile.ReadFile("users.ini"))
|
||||||
{
|
{
|
||||||
AString Groups = IniFile.GetValueSet(m_PlayerName, "Groups", "Default");
|
AString Groups = IniFile.GetValueSet(GetName(), "Groups", "Default");
|
||||||
AStringVector Split = StringSplitAndTrim(Groups, ",");
|
AStringVector Split = StringSplitAndTrim(Groups, ",");
|
||||||
|
|
||||||
for (AStringVector::const_iterator itr = Split.begin(), end = Split.end(); itr != end; ++itr)
|
for (AStringVector::const_iterator itr = Split.begin(), end = Split.end(); itr != end; ++itr)
|
||||||
{
|
{
|
||||||
if (!cRoot::Get()->GetGroupManager()->ExistsGroup(*itr))
|
if (!cRoot::Get()->GetGroupManager()->ExistsGroup(*itr))
|
||||||
{
|
{
|
||||||
LOGWARNING("The group %s for player %s was not found!", itr->c_str(), m_PlayerName.c_str());
|
LOGWARNING("The group %s for player %s was not found!", itr->c_str(), GetName().c_str());
|
||||||
}
|
}
|
||||||
AddToGroup(*itr);
|
AddToGroup(*itr);
|
||||||
}
|
}
|
||||||
|
|
||||||
AString Color = IniFile.GetValue(m_PlayerName, "Color", "-");
|
AString Color = IniFile.GetValue(GetName(), "Color", "-");
|
||||||
if (!Color.empty())
|
if (!Color.empty())
|
||||||
{
|
{
|
||||||
m_Color = Color[0];
|
m_Color = Color[0];
|
||||||
@ -1636,7 +1636,7 @@ void cPlayer::LoadPermissionsFromDisk()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
cGroupManager::GenerateDefaultUsersIni(IniFile);
|
cGroupManager::GenerateDefaultUsersIni(IniFile);
|
||||||
IniFile.AddValue("Groups", m_PlayerName, "Default");
|
IniFile.AddValue("Groups", GetName(), "Default");
|
||||||
AddToGroup("Default");
|
AddToGroup("Default");
|
||||||
}
|
}
|
||||||
IniFile.WriteFile("users.ini");
|
IniFile.WriteFile("users.ini");
|
||||||
@ -1651,14 +1651,14 @@ bool cPlayer::LoadFromDisk()
|
|||||||
LoadPermissionsFromDisk();
|
LoadPermissionsFromDisk();
|
||||||
|
|
||||||
// Log player permissions, cause it's what the cool kids do
|
// Log player permissions, cause it's what the cool kids do
|
||||||
LOGINFO("Player %s has permissions:", m_PlayerName.c_str() );
|
LOGINFO("Player %s has permissions:", GetName().c_str() );
|
||||||
for( PermissionMap::iterator itr = m_ResolvedPermissions.begin(); itr != m_ResolvedPermissions.end(); ++itr )
|
for( PermissionMap::iterator itr = m_ResolvedPermissions.begin(); itr != m_ResolvedPermissions.end(); ++itr )
|
||||||
{
|
{
|
||||||
if( itr->second ) LOG(" - %s", itr->first.c_str() );
|
if( itr->second ) LOG(" - %s", itr->first.c_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
AString SourceFile;
|
AString SourceFile;
|
||||||
Printf(SourceFile, "players/%s.json", m_PlayerName.c_str() );
|
Printf(SourceFile, "players/%s.json", GetName().c_str() );
|
||||||
|
|
||||||
cFile f;
|
cFile f;
|
||||||
if (!f.Open(SourceFile, cFile::fmRead))
|
if (!f.Open(SourceFile, cFile::fmRead))
|
||||||
@ -1726,7 +1726,7 @@ bool cPlayer::LoadFromDisk()
|
|||||||
StatSerializer.Load();
|
StatSerializer.Load();
|
||||||
|
|
||||||
LOGD("Player \"%s\" was read from file, spawning at {%.2f, %.2f, %.2f} in world \"%s\"",
|
LOGD("Player \"%s\" was read from file, spawning at {%.2f, %.2f, %.2f} in world \"%s\"",
|
||||||
m_PlayerName.c_str(), GetPosX(), GetPosY(), GetPosZ(), m_LoadedWorldName.c_str()
|
GetName().c_str(), GetPosX(), GetPosY(), GetPosZ(), m_LoadedWorldName.c_str()
|
||||||
);
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -1782,12 +1782,12 @@ bool cPlayer::SaveToDisk()
|
|||||||
std::string JsonData = writer.write(root);
|
std::string JsonData = writer.write(root);
|
||||||
|
|
||||||
AString SourceFile;
|
AString SourceFile;
|
||||||
Printf(SourceFile, "players/%s.json", m_PlayerName.c_str() );
|
Printf(SourceFile, "players/%s.json", GetName().c_str() );
|
||||||
|
|
||||||
cFile f;
|
cFile f;
|
||||||
if (!f.Open(SourceFile, cFile::fmWrite))
|
if (!f.Open(SourceFile, cFile::fmWrite))
|
||||||
{
|
{
|
||||||
LOGERROR("ERROR WRITING PLAYER \"%s\" TO FILE \"%s\" - cannot open file", m_PlayerName.c_str(), SourceFile.c_str());
|
LOGERROR("ERROR WRITING PLAYER \"%s\" TO FILE \"%s\" - cannot open file", GetName().c_str(), SourceFile.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (f.Write(JsonData.c_str(), JsonData.size()) != (int)JsonData.size())
|
if (f.Write(JsonData.c_str(), JsonData.size()) != (int)JsonData.size())
|
||||||
@ -1798,10 +1798,10 @@ bool cPlayer::SaveToDisk()
|
|||||||
|
|
||||||
// Save the player stats.
|
// Save the player stats.
|
||||||
// We use the default world name (like bukkit) because stats are shared between dimensions/worlds.
|
// We use the default world name (like bukkit) because stats are shared between dimensions/worlds.
|
||||||
cStatSerializer StatSerializer(cRoot::Get()->GetDefaultWorld()->GetName(), m_PlayerName, &m_Stats);
|
cStatSerializer StatSerializer(cRoot::Get()->GetDefaultWorld()->GetName(), GetName(), &m_Stats);
|
||||||
if (!StatSerializer.Save())
|
if (!StatSerializer.Save())
|
||||||
{
|
{
|
||||||
LOGERROR("Could not save stats for player %s", m_PlayerName.c_str());
|
LOGERROR("Could not save stats for player %s", GetName().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +50,15 @@ cGridStructGen::cGridStructGen(
|
|||||||
m_MaxStructureSizeZ(a_MaxStructureSizeZ),
|
m_MaxStructureSizeZ(a_MaxStructureSizeZ),
|
||||||
m_MaxCacheSize(a_MaxCacheSize)
|
m_MaxCacheSize(a_MaxCacheSize)
|
||||||
{
|
{
|
||||||
|
size_t NumStructuresPerQuery = (size_t)((m_MaxStructureSizeX / m_GridSizeX + 1) * (m_MaxStructureSizeZ / m_GridSizeZ + 1));
|
||||||
|
if (NumStructuresPerQuery > m_MaxCacheSize)
|
||||||
|
{
|
||||||
|
m_MaxCacheSize = NumStructuresPerQuery * 4;
|
||||||
|
LOGINFO(
|
||||||
|
"cGridStructGen: The cache size is too small (%u), increasing the cache size to %u to avoid inefficiency.",
|
||||||
|
(unsigned)a_MaxCacheSize, (unsigned)m_MaxCacheSize
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1283,7 +1283,7 @@ cStructGenMineShafts::cStructGenMineShafts(
|
|||||||
int a_Seed, int a_GridSize, int a_MaxSystemSize,
|
int a_Seed, int a_GridSize, int a_MaxSystemSize,
|
||||||
int a_ChanceCorridor, int a_ChanceCrossing, int a_ChanceStaircase
|
int a_ChanceCorridor, int a_ChanceCrossing, int a_ChanceStaircase
|
||||||
) :
|
) :
|
||||||
super(a_Seed, a_GridSize, a_GridSize, 120 + a_MaxSystemSize * 10, 120 + a_MaxSystemSize * 10, 100),
|
super(a_Seed, a_GridSize, a_GridSize, a_MaxSystemSize, a_MaxSystemSize, 100),
|
||||||
m_Noise(a_Seed),
|
m_Noise(a_Seed),
|
||||||
m_GridSize(a_GridSize),
|
m_GridSize(a_GridSize),
|
||||||
m_MaxSystemSize(a_MaxSystemSize),
|
m_MaxSystemSize(a_MaxSystemSize),
|
||||||
|
@ -45,8 +45,14 @@ cGroupManager::cGroupManager()
|
|||||||
{
|
{
|
||||||
LOGD("-- Loading Groups --");
|
LOGD("-- Loading Groups --");
|
||||||
|
|
||||||
LoadGroups();
|
if (!LoadGroups())
|
||||||
CheckUsers();
|
{
|
||||||
|
LOGWARNING("ERROR: Groups could not load!");
|
||||||
|
}
|
||||||
|
if (!CheckUsers())
|
||||||
|
{
|
||||||
|
LOGWARNING("ERROR: User file could not be found!");
|
||||||
|
}
|
||||||
|
|
||||||
LOGD("-- Groups Successfully Loaded --");
|
LOGD("-- Groups Successfully Loaded --");
|
||||||
}
|
}
|
||||||
@ -70,13 +76,13 @@ void cGroupManager::GenerateDefaultUsersIni(cIniFile & a_IniFile)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cGroupManager::CheckUsers(void)
|
bool cGroupManager::CheckUsers()
|
||||||
{
|
{
|
||||||
cIniFile IniFile;
|
cIniFile IniFile;
|
||||||
if (!IniFile.ReadFile("users.ini"))
|
if (!IniFile.ReadFile("users.ini"))
|
||||||
{
|
{
|
||||||
GenerateDefaultUsersIni(IniFile);
|
GenerateDefaultUsersIni(IniFile);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int NumKeys = IniFile.GetNumKeys();
|
int NumKeys = IniFile.GetNumKeys();
|
||||||
@ -97,13 +103,15 @@ void cGroupManager::CheckUsers(void)
|
|||||||
}
|
}
|
||||||
} // for itr - Split[]
|
} // for itr - Split[]
|
||||||
} // for i - ini file keys
|
} // for i - ini file keys
|
||||||
|
// Always return true for now, just but we can handle writefile fails later.
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cGroupManager::LoadGroups()
|
bool cGroupManager::LoadGroups()
|
||||||
{
|
{
|
||||||
cIniFile IniFile;
|
cIniFile IniFile;
|
||||||
if (!IniFile.ReadFile("groups.ini"))
|
if (!IniFile.ReadFile("groups.ini"))
|
||||||
@ -180,6 +188,8 @@ void cGroupManager::LoadGroups()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Always return true, we can handle writefile fails later.
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@ class cGroupManager
|
|||||||
public:
|
public:
|
||||||
bool ExistsGroup(const AString & a_Name);
|
bool ExistsGroup(const AString & a_Name);
|
||||||
cGroup * GetGroup(const AString & a_Name);
|
cGroup * GetGroup(const AString & a_Name);
|
||||||
void LoadGroups(void);
|
bool LoadGroups();
|
||||||
void CheckUsers(void);
|
bool CheckUsers();
|
||||||
|
|
||||||
/** Writes the default header to the specified ini file, and saves it as "users.ini". */
|
/** Writes the default header to the specified ini file, and saves it as "users.ini". */
|
||||||
static void GenerateDefaultUsersIni(cIniFile & a_IniFile);
|
static void GenerateDefaultUsersIni(cIniFile & a_IniFile);
|
||||||
|
@ -234,7 +234,7 @@ void cProtocol172::SendChat(const cCompositeChat & a_Message)
|
|||||||
|
|
||||||
// Compose the complete Json string to send:
|
// Compose the complete Json string to send:
|
||||||
Json::Value msg;
|
Json::Value msg;
|
||||||
msg["text"] = ""; // The client crashes without this
|
msg["text"] = cClientHandle::FormatMessageType(m_Client->GetPlayer()->GetWorld()->ShouldUseChatPrefixes(), a_Message.GetMessageType(), a_Message.GetAdditionalMessageTypeData()); // The client crashes without this field being present
|
||||||
const cCompositeChat::cParts & Parts = a_Message.GetParts();
|
const cCompositeChat::cParts & Parts = a_Message.GetParts();
|
||||||
for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr)
|
for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr)
|
||||||
{
|
{
|
||||||
@ -289,6 +289,35 @@ void cProtocol172::SendChat(const cCompositeChat & a_Message)
|
|||||||
AddChatPartStyle(Part, p.m_Style);
|
AddChatPartStyle(Part, p.m_Style);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case cCompositeChat::ptShowAchievement:
|
||||||
|
{
|
||||||
|
const cCompositeChat::cShowAchievementPart & p = (const cCompositeChat::cShowAchievementPart &)**itr;
|
||||||
|
Part["translate"] = "chat.type.achievement";
|
||||||
|
|
||||||
|
Json::Value Ach;
|
||||||
|
Ach["action"] = "show_achievement";
|
||||||
|
Ach["value"] = p.m_Text;
|
||||||
|
|
||||||
|
Json::Value AchColourAndName;
|
||||||
|
AchColourAndName["color"] = "green";
|
||||||
|
AchColourAndName["translate"] = p.m_Text;
|
||||||
|
AchColourAndName["hoverEvent"] = Ach;
|
||||||
|
|
||||||
|
Json::Value Extra;
|
||||||
|
Extra.append(AchColourAndName);
|
||||||
|
|
||||||
|
Json::Value Name;
|
||||||
|
Name["text"] = p.m_PlayerName;
|
||||||
|
|
||||||
|
Json::Value With;
|
||||||
|
With.append(Name);
|
||||||
|
With.append(Extra);
|
||||||
|
|
||||||
|
Part["with"] = With;
|
||||||
|
AddChatPartStyle(Part, p.m_Style);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
msg["extra"].append(Part);
|
msg["extra"].append(Part);
|
||||||
} // for itr - Parts[]
|
} // for itr - Parts[]
|
||||||
|
Loading…
Reference in New Issue
Block a user