Merge branch 'master' into VillageGen
This commit is contained in:
commit
dff71823d4
@ -39,7 +39,8 @@ pre
|
||||
|
||||
body
|
||||
{
|
||||
min-width: 800px;
|
||||
min-width: 400px;
|
||||
max-width: 1200px;
|
||||
width: 95%;
|
||||
margin: 10px auto;
|
||||
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 performant C++ Minecraft server designed for use in memory and cpu-limited places, or just to make regular server perform better.
|
||||
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 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
|
||||
------------
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Check out the [CONTRIBUTING.md](https://github.com/mc-server/MCServer/blob/master/CONTRIBUTING.md) file for more details.
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
{
|
||||
if ((m_Player == NULL) || (m_State != csPlaying))
|
||||
{
|
||||
// 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);
|
||||
HandlePlayerLook(a_Rotation, a_Pitch, a_IsOnGround);
|
||||
HandlePlayerPos(a_PosX, a_PosY, a_PosZ, a_Stance, a_IsOnGround);
|
||||
}
|
||||
|
||||
|
||||
|
@ -80,9 +80,9 @@ public:
|
||||
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. **/
|
||||
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 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)
|
||||
{
|
||||
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_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,
|
||||
ptRunCommand,
|
||||
ptSuggestCommand,
|
||||
ptShowAchievement,
|
||||
} ;
|
||||
|
||||
class cBasePart
|
||||
@ -46,6 +47,7 @@ public:
|
||||
ePartType m_PartType;
|
||||
AString m_Text;
|
||||
AString m_Style;
|
||||
AString m_AdditionalStyleData;
|
||||
|
||||
cBasePart(ePartType a_PartType, const AString & a_Text, const AString & a_Style = "");
|
||||
|
||||
@ -107,6 +109,15 @@ public:
|
||||
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;
|
||||
|
||||
// tolua_begin
|
||||
@ -149,12 +160,19 @@ public:
|
||||
The default style is underlined yellow text. */
|
||||
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.
|
||||
Recognizes "http:" and "https:" URLs and @color-codes. */
|
||||
void ParseText(const AString & a_ParseText);
|
||||
|
||||
/** Sets the message type, which is indicated by prefixes added to the message when serializing. */
|
||||
void SetMessageType(eMessageType a_MessageType);
|
||||
/** Sets the message type, which is indicated by prefixes added to the message when serializing
|
||||
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. */
|
||||
void UnderlineUrls(void);
|
||||
@ -164,6 +182,9 @@ public:
|
||||
/** Returns the message type set previously by SetMessageType(). */
|
||||
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.
|
||||
Used for older protocols that don't support composite chat
|
||||
and for console-logging. */
|
||||
@ -184,6 +205,9 @@ protected:
|
||||
/** The message type, as indicated by prefixes. */
|
||||
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.
|
||||
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;
|
||||
float w = m_Width / 2;
|
||||
double w = m_Width / 2;
|
||||
if (
|
||||
(((X + 1) - GetPosX() < w) && (GetWorld()->GetBlock(X + 1, Y, Z) == E_BLOCK_CACTUS)) ||
|
||||
(((GetPosX() - (X - 1)) - 1 < w) && (GetWorld()->GetBlock(X - 1, Y, Z) == E_BLOCK_CACTUS)) ||
|
||||
((Y > 0) && (Y < cChunkDef::Height)) &&
|
||||
((((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)) ||
|
||||
(((GetPosZ() - (Z - 1)) - 1 < 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)))
|
||||
((GetPosZ() - Z < w) && (GetWorld()->GetBlock(X, Y, Z - 1) == E_BLOCK_CACTUS)) ||
|
||||
(((GetPosY() - Y < 1) && (GetWorld()->GetBlock(X, Y, Z) == E_BLOCK_CACTUS))))
|
||||
)
|
||||
{
|
||||
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",
|
||||
m_PlayerName.c_str(), a_Xp_delta, m_CurrentXp);
|
||||
GetName().c_str(), a_Xp_delta, m_CurrentXp);
|
||||
|
||||
// Set experience to be updated
|
||||
m_bDirtyExperience = true;
|
||||
@ -391,7 +391,7 @@ short cPlayer::DeltaExperience(short a_Xp_delta)
|
||||
|
||||
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_BowCharge = 0;
|
||||
}
|
||||
@ -402,7 +402,7 @@ void cPlayer::StartChargingBow(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;
|
||||
m_IsChargingBow = false;
|
||||
m_BowCharge = 0;
|
||||
@ -415,7 +415,7 @@ int cPlayer::FinishChargingBow(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_BowCharge = 0;
|
||||
}
|
||||
@ -1179,8 +1179,8 @@ unsigned int cPlayer::AwardAchievement(const eStatistic a_Ach)
|
||||
{
|
||||
// First time, announce it
|
||||
cCompositeChat Msg;
|
||||
Msg.AddTextPart(m_PlayerName + " has just earned the achievement ");
|
||||
Msg.AddTextPart(cStatInfo::GetName(a_Ach)); // TODO 2014-05-12 xdot: Use the proper cCompositeChat part (cAchievement)
|
||||
Msg.SetMessageType(mtSuccess);
|
||||
Msg.AddShowAchievementPart(GetName(), cStatInfo::GetName(a_Ach));
|
||||
m_World->BroadcastChat(Msg);
|
||||
|
||||
// Increment the statistic
|
||||
@ -1315,7 +1315,7 @@ void cPlayer::AddToGroup( const AString & a_GroupName )
|
||||
{
|
||||
cGroup* Group = cRoot::Get()->GetGroupManager()->GetGroup( a_GroupName );
|
||||
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();
|
||||
ResolvePermissions();
|
||||
}
|
||||
@ -1339,13 +1339,13 @@ void cPlayer::RemoveFromGroup( const AString & a_GroupName )
|
||||
|
||||
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();
|
||||
ResolvePermissions();
|
||||
}
|
||||
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() )
|
||||
{
|
||||
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
|
||||
@ -1463,7 +1463,7 @@ void cPlayer::ResolveGroups()
|
||||
{
|
||||
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;
|
||||
}
|
||||
ToIterate.push_back( *itr );
|
||||
@ -1615,19 +1615,19 @@ void cPlayer::LoadPermissionsFromDisk()
|
||||
cIniFile IniFile;
|
||||
if (IniFile.ReadFile("users.ini"))
|
||||
{
|
||||
AString Groups = IniFile.GetValueSet(m_PlayerName, "Groups", "Default");
|
||||
AString Groups = IniFile.GetValueSet(GetName(), "Groups", "Default");
|
||||
AStringVector Split = StringSplitAndTrim(Groups, ",");
|
||||
|
||||
for (AStringVector::const_iterator itr = Split.begin(), end = Split.end(); itr != end; ++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);
|
||||
}
|
||||
|
||||
AString Color = IniFile.GetValue(m_PlayerName, "Color", "-");
|
||||
AString Color = IniFile.GetValue(GetName(), "Color", "-");
|
||||
if (!Color.empty())
|
||||
{
|
||||
m_Color = Color[0];
|
||||
@ -1636,7 +1636,7 @@ void cPlayer::LoadPermissionsFromDisk()
|
||||
else
|
||||
{
|
||||
cGroupManager::GenerateDefaultUsersIni(IniFile);
|
||||
IniFile.AddValue("Groups", m_PlayerName, "Default");
|
||||
IniFile.AddValue("Groups", GetName(), "Default");
|
||||
AddToGroup("Default");
|
||||
}
|
||||
IniFile.WriteFile("users.ini");
|
||||
@ -1651,14 +1651,14 @@ bool cPlayer::LoadFromDisk()
|
||||
LoadPermissionsFromDisk();
|
||||
|
||||
// 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 )
|
||||
{
|
||||
if( itr->second ) LOG(" - %s", itr->first.c_str() );
|
||||
}
|
||||
|
||||
AString SourceFile;
|
||||
Printf(SourceFile, "players/%s.json", m_PlayerName.c_str() );
|
||||
Printf(SourceFile, "players/%s.json", GetName().c_str() );
|
||||
|
||||
cFile f;
|
||||
if (!f.Open(SourceFile, cFile::fmRead))
|
||||
@ -1726,7 +1726,7 @@ bool cPlayer::LoadFromDisk()
|
||||
StatSerializer.Load();
|
||||
|
||||
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;
|
||||
@ -1782,12 +1782,12 @@ bool cPlayer::SaveToDisk()
|
||||
std::string JsonData = writer.write(root);
|
||||
|
||||
AString SourceFile;
|
||||
Printf(SourceFile, "players/%s.json", m_PlayerName.c_str() );
|
||||
Printf(SourceFile, "players/%s.json", GetName().c_str() );
|
||||
|
||||
cFile f;
|
||||
if (!f.Open(SourceFile, cFile::fmWrite))
|
||||
{
|
||||
LOGERROR("ERROR WRITING PLAYER \"%s\" TO FILE \"%s\" - cannot open file", m_PlayerName.c_str(), SourceFile.c_str());
|
||||
LOGERROR("ERROR WRITING PLAYER \"%s\" TO FILE \"%s\" - cannot open file", GetName().c_str(), SourceFile.c_str());
|
||||
return false;
|
||||
}
|
||||
if (f.Write(JsonData.c_str(), JsonData.size()) != (int)JsonData.size())
|
||||
@ -1798,10 +1798,10 @@ bool cPlayer::SaveToDisk()
|
||||
|
||||
// Save the player stats.
|
||||
// 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())
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,15 @@ cGridStructGen::cGridStructGen(
|
||||
m_MaxStructureSizeZ(a_MaxStructureSizeZ),
|
||||
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_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_GridSize(a_GridSize),
|
||||
m_MaxSystemSize(a_MaxSystemSize),
|
||||
|
@ -45,8 +45,14 @@ cGroupManager::cGroupManager()
|
||||
{
|
||||
LOGD("-- Loading Groups --");
|
||||
|
||||
LoadGroups();
|
||||
CheckUsers();
|
||||
if (!LoadGroups())
|
||||
{
|
||||
LOGWARNING("ERROR: Groups could not load!");
|
||||
}
|
||||
if (!CheckUsers())
|
||||
{
|
||||
LOGWARNING("ERROR: User file could not be found!");
|
||||
}
|
||||
|
||||
LOGD("-- Groups Successfully Loaded --");
|
||||
}
|
||||
@ -70,13 +76,13 @@ void cGroupManager::GenerateDefaultUsersIni(cIniFile & a_IniFile)
|
||||
|
||||
|
||||
|
||||
void cGroupManager::CheckUsers(void)
|
||||
bool cGroupManager::CheckUsers()
|
||||
{
|
||||
cIniFile IniFile;
|
||||
if (!IniFile.ReadFile("users.ini"))
|
||||
{
|
||||
GenerateDefaultUsersIni(IniFile);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
int NumKeys = IniFile.GetNumKeys();
|
||||
@ -97,13 +103,15 @@ void cGroupManager::CheckUsers(void)
|
||||
}
|
||||
} // for itr - Split[]
|
||||
} // 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;
|
||||
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:
|
||||
bool ExistsGroup(const AString & a_Name);
|
||||
cGroup * GetGroup(const AString & a_Name);
|
||||
void LoadGroups(void);
|
||||
void CheckUsers(void);
|
||||
bool LoadGroups();
|
||||
bool CheckUsers();
|
||||
|
||||
/** Writes the default header to the specified ini file, and saves it as "users.ini". */
|
||||
static void GenerateDefaultUsersIni(cIniFile & a_IniFile);
|
||||
|
@ -234,7 +234,7 @@ void cProtocol172::SendChat(const cCompositeChat & a_Message)
|
||||
|
||||
// Compose the complete Json string to send:
|
||||
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();
|
||||
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);
|
||||
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);
|
||||
} // for itr - Parts[]
|
||||
|
Loading…
Reference in New Issue
Block a user