v1.4.4
This commit is contained in:
commit
9c94d113d3
10260 changed files with 1237388 additions and 0 deletions
308
source/game/StarTeamManager.cpp
Normal file
308
source/game/StarTeamManager.cpp
Normal file
|
@ -0,0 +1,308 @@
|
|||
#include "StarTeamManager.hpp"
|
||||
#include "StarRandom.hpp"
|
||||
#include "StarJsonExtra.hpp"
|
||||
#include "StarRoot.hpp"
|
||||
#include "StarAssets.hpp"
|
||||
|
||||
namespace Star {
|
||||
|
||||
TeamManager::TeamManager() {
|
||||
m_pvpTeamCounter = 1;
|
||||
m_maxTeamSize = Root::singleton().configuration()->get("maxTeamSize").toUInt();
|
||||
}
|
||||
|
||||
JsonRpcHandlers TeamManager::rpcHandlers() {
|
||||
return JsonRpcHandlers{
|
||||
{"team.fetchTeamStatus", bind(&TeamManager::fetchTeamStatus, this, _1)},
|
||||
{"team.updateStatus", bind(&TeamManager::updateStatus, this, _1)},
|
||||
{"team.invite", bind(&TeamManager::invite, this, _1)},
|
||||
{"team.pollInvitation", bind(&TeamManager::pollInvitation, this, _1)},
|
||||
{"team.acceptInvitation", bind(&TeamManager::acceptInvitation, this, _1)},
|
||||
{"team.makeLeader", bind(&TeamManager::makeLeader, this, _1)},
|
||||
{"team.removeFromTeam", [&](Json request) -> Json { return removeFromTeam(request); }}
|
||||
};
|
||||
}
|
||||
|
||||
void TeamManager::setConnectedPlayers(StringMap<List<Uuid>> const& connectedPlayers) {
|
||||
m_connectedPlayers = move(connectedPlayers);
|
||||
}
|
||||
|
||||
void TeamManager::playerDisconnected(Uuid const& playerUuid) {
|
||||
RecursiveMutexLocker lock(m_mutex);
|
||||
|
||||
purgeInvitationsFor(playerUuid);
|
||||
purgeInvitationsFrom(playerUuid);
|
||||
|
||||
for (auto teamUuid : m_teams.keys()) {
|
||||
auto& team = m_teams[teamUuid];
|
||||
if (team.members.contains(playerUuid))
|
||||
removeFromTeam(playerUuid, teamUuid);
|
||||
}
|
||||
}
|
||||
|
||||
TeamNumber TeamManager::getPvpTeam(Uuid const& playerUuid) {
|
||||
RecursiveMutexLocker lock(m_mutex);
|
||||
for (auto const& teamPair : m_teams) {
|
||||
if (teamPair.second.members.contains(playerUuid))
|
||||
return teamPair.second.pvpTeamNumber;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
HashMap<Uuid, TeamNumber> TeamManager::getPvpTeams() {
|
||||
HashMap<Uuid, TeamNumber> result;
|
||||
for (auto const& teamPair : m_teams) {
|
||||
for (auto const& memberPair : teamPair.second.members)
|
||||
result[memberPair.first] = teamPair.second.pvpTeamNumber;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Maybe<Uuid> TeamManager::getTeam(Uuid const& playerUuid) const {
|
||||
for (auto const& teamPair : m_teams) {
|
||||
if (teamPair.second.members.contains(playerUuid))
|
||||
return teamPair.first;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void TeamManager::purgeInvitationsFor(Uuid const& playerUuid) {
|
||||
m_invitations.remove(playerUuid);
|
||||
}
|
||||
|
||||
void TeamManager::purgeInvitationsFrom(Uuid const& playerUuid) {
|
||||
eraseWhere(m_invitations, [playerUuid](auto const& invitation) {
|
||||
return invitation.second.inviterUuid == playerUuid;
|
||||
});
|
||||
}
|
||||
|
||||
bool TeamManager::playerWithUuidExists(Uuid const& playerUuid) const {
|
||||
for (auto const& p : m_connectedPlayers) {
|
||||
if (p.second.contains(playerUuid))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Uuid TeamManager::createTeam(Uuid const& leaderUuid) {
|
||||
RecursiveMutexLocker lock(m_mutex);
|
||||
|
||||
Uuid teamUuid;
|
||||
auto& team = m_teams[teamUuid]; // create
|
||||
|
||||
int limiter = 256;
|
||||
while (true) {
|
||||
team.pvpTeamNumber = m_pvpTeamCounter++;
|
||||
if (m_pvpTeamCounter == 0)
|
||||
m_pvpTeamCounter = 1;
|
||||
bool done = true;
|
||||
for (auto k : m_teams.keys()) {
|
||||
auto t = m_teams[k];
|
||||
if (t.pvpTeamNumber == team.pvpTeamNumber) {
|
||||
if (k != teamUuid)
|
||||
done = false;
|
||||
}
|
||||
}
|
||||
if (done)
|
||||
break;
|
||||
if (limiter-- == 0) {
|
||||
team.pvpTeamNumber = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
addToTeam(leaderUuid, teamUuid);
|
||||
team.leaderUuid = leaderUuid;
|
||||
|
||||
return teamUuid;
|
||||
}
|
||||
|
||||
bool TeamManager::addToTeam(Uuid const& playerUuid, Uuid const& teamUuid) {
|
||||
RecursiveMutexLocker lock(m_mutex);
|
||||
|
||||
if (!m_teams.contains(teamUuid))
|
||||
return false;
|
||||
|
||||
auto& team = m_teams.get(teamUuid);
|
||||
|
||||
if (team.members.contains(playerUuid))
|
||||
return false;
|
||||
|
||||
if (team.members.size() >= m_maxTeamSize)
|
||||
return false;
|
||||
|
||||
purgeInvitationsFor(playerUuid);
|
||||
|
||||
for (auto otherTeam : m_teams) {
|
||||
List<Uuid> alreadyMemberOf;
|
||||
if (otherTeam.second.members.contains(playerUuid))
|
||||
alreadyMemberOf.append(otherTeam.first);
|
||||
for (auto leaveTeamUuid : alreadyMemberOf)
|
||||
removeFromTeam(playerUuid, leaveTeamUuid);
|
||||
}
|
||||
|
||||
team.members.insert(playerUuid, TeamMember());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TeamManager::removeFromTeam(Uuid const& playerUuid, Uuid const& teamUuid) {
|
||||
RecursiveMutexLocker lock(m_mutex);
|
||||
|
||||
if (!m_teams.contains(teamUuid))
|
||||
return false;
|
||||
|
||||
auto& team = m_teams.get(teamUuid);
|
||||
|
||||
if (!team.members.contains(playerUuid))
|
||||
return false;
|
||||
|
||||
purgeInvitationsFrom(playerUuid);
|
||||
|
||||
team.members.remove(playerUuid);
|
||||
if (team.members.size() <= 1)
|
||||
m_teams.remove(teamUuid);
|
||||
else if (team.leaderUuid == playerUuid)
|
||||
team.leaderUuid = Random::randFrom(team.members).first;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Json TeamManager::fetchTeamStatus(Json const& arguments) {
|
||||
RecursiveMutexLocker lock(m_mutex);
|
||||
auto playerUuid = Uuid(arguments.getString("playerUuid"));
|
||||
JsonObject result;
|
||||
if (auto teamUuid = getTeam(playerUuid)) {
|
||||
auto& team = m_teams.get(*teamUuid);
|
||||
|
||||
result["teamUuid"] = teamUuid->hex();
|
||||
result["leader"] = team.leaderUuid.hex();
|
||||
JsonArray members;
|
||||
for (auto const& m : team.members) {
|
||||
JsonObject member;
|
||||
auto const& mem = m.second;
|
||||
member["name"] = mem.name;
|
||||
member["uuid"] = m.first.hex();
|
||||
member["leader"] = m.first == team.leaderUuid;
|
||||
member["entity"] = mem.entity;
|
||||
member["health"] = mem.healthPercentage;
|
||||
member["energy"] = mem.energyPercentage;
|
||||
member["x"] = mem.position[0];
|
||||
member["y"] = mem.position[1];
|
||||
member["world"] = printWorldId(mem.world);
|
||||
member["warpMode"] = WarpModeNames.getRight(mem.warpMode);
|
||||
member["portrait"] = jsonFromList(mem.portrait, mem_fn(&Drawable::toJson));
|
||||
members.push_back(member);
|
||||
}
|
||||
result["members"] = members;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Json TeamManager::updateStatus(Json const& arguments) {
|
||||
RecursiveMutexLocker lock(m_mutex);
|
||||
auto playerUuid = Uuid(arguments.getString("playerUuid"));
|
||||
if (auto teamUuid = getTeam(playerUuid)) {
|
||||
auto& team = m_teams.get(*teamUuid);
|
||||
auto& entry = team.members.get(playerUuid);
|
||||
if (arguments.contains("name"))
|
||||
entry.name = arguments.getString("name");
|
||||
if (arguments.contains("entity"))
|
||||
entry.entity = arguments.getInt("entity");
|
||||
entry.healthPercentage = arguments.getFloat("health");
|
||||
entry.energyPercentage = arguments.getFloat("energy");
|
||||
entry.position[0] = arguments.getFloat("x");
|
||||
entry.position[1] = arguments.getFloat("y");
|
||||
entry.warpMode = WarpModeNames.getLeft(arguments.getString("warpMode"));
|
||||
if (arguments.contains("world"))
|
||||
entry.world = parseWorldId(arguments.getString("world"));
|
||||
if (arguments.contains("portrait"))
|
||||
entry.portrait = jsonToList<Drawable>(arguments.get("portrait"));
|
||||
return {};
|
||||
} else {
|
||||
return "notAMemberOfTeam";
|
||||
}
|
||||
}
|
||||
|
||||
Json TeamManager::invite(Json const& arguments) {
|
||||
RecursiveMutexLocker lock(m_mutex);
|
||||
auto inviteeName = arguments.getString("inviteeName").toLower();
|
||||
|
||||
if (!m_connectedPlayers.contains(inviteeName))
|
||||
return "inviteeNotFound";
|
||||
|
||||
auto inviterUuid = Uuid(arguments.getString("inviterUuid"));
|
||||
|
||||
for (auto inviteeUuid : m_connectedPlayers[inviteeName]) {
|
||||
if (inviteeUuid == inviterUuid)
|
||||
continue;
|
||||
|
||||
Invitation invitation;
|
||||
invitation.inviterUuid = inviterUuid;
|
||||
invitation.inviterName = arguments.getString("inviterName");
|
||||
m_invitations[inviteeUuid] = invitation;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Json TeamManager::pollInvitation(Json const& arguments) {
|
||||
RecursiveMutexLocker lock(m_mutex);
|
||||
auto playerUuid = Uuid(arguments.getString("playerUuid"));
|
||||
if (m_invitations.contains(playerUuid)) {
|
||||
auto invite = m_invitations.take(playerUuid);
|
||||
JsonObject result;
|
||||
result["inviterUuid"] = invite.inviterUuid.hex();
|
||||
result["inviterName"] = invite.inviterName;
|
||||
return result;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Json TeamManager::acceptInvitation(Json const& arguments) {
|
||||
RecursiveMutexLocker lock(m_mutex);
|
||||
auto inviterUuid = Uuid(arguments.getString("inviterUuid"));
|
||||
auto inviteeUuid = Uuid(arguments.getString("inviteeUuid"));
|
||||
|
||||
if (!playerWithUuidExists(inviterUuid) || !playerWithUuidExists(inviteeUuid))
|
||||
return "acceptInvitationFailed";
|
||||
|
||||
purgeInvitationsFrom(inviteeUuid);
|
||||
|
||||
Uuid teamUuid;
|
||||
if (auto existingTeamUuid = getTeam(inviterUuid))
|
||||
teamUuid = *existingTeamUuid;
|
||||
else
|
||||
teamUuid = createTeam(inviterUuid);
|
||||
|
||||
auto success = addToTeam(inviteeUuid, teamUuid);
|
||||
return success ? Json() : "acceptInvitationFailed";
|
||||
}
|
||||
|
||||
Json TeamManager::removeFromTeam(Json const& arguments) {
|
||||
auto playerUuid = Uuid(arguments.getString("playerUuid"));
|
||||
auto teamUuid = Uuid(arguments.getString("teamUuid"));
|
||||
|
||||
auto success = removeFromTeam(playerUuid, teamUuid);
|
||||
return success ? Json() : "removeFromTeamFailed";
|
||||
}
|
||||
|
||||
Json TeamManager::makeLeader(Json const& arguments) {
|
||||
RecursiveMutexLocker lock(m_mutex);
|
||||
auto playerUuid = Uuid(arguments.getString("playerUuid"));
|
||||
auto teamUuid = Uuid(arguments.getString("teamUuid"));
|
||||
|
||||
if (!m_teams.contains(teamUuid))
|
||||
return "noSuchTeam";
|
||||
|
||||
auto& team = m_teams.get(teamUuid);
|
||||
|
||||
if (!team.members.contains(playerUuid))
|
||||
return "notAMemberOfTeam";
|
||||
|
||||
team.leaderUuid = playerUuid;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue