v1.4.4
This commit is contained in:
commit
9c94d113d3
10260 changed files with 1237388 additions and 0 deletions
245
source/game/StarTeamClient.cpp
Normal file
245
source/game/StarTeamClient.cpp
Normal file
|
@ -0,0 +1,245 @@
|
|||
#include "StarTeamClient.hpp"
|
||||
#include "StarJsonExtra.hpp"
|
||||
#include "StarWorldTemplate.hpp"
|
||||
#include "StarPlayer.hpp"
|
||||
#include "StarPlayerLog.hpp"
|
||||
#include "StarRoot.hpp"
|
||||
#include "StarAssets.hpp"
|
||||
#include "StarClientContext.hpp"
|
||||
#include "StarWorldClient.hpp"
|
||||
#include "StarJsonRpc.hpp"
|
||||
|
||||
namespace Star {
|
||||
|
||||
TeamClient::TeamClient(PlayerPtr mainPlayer, ClientContextPtr clientContext) {
|
||||
m_mainPlayer = mainPlayer;
|
||||
m_clientContext = clientContext;
|
||||
|
||||
m_hasPendingInvitation = false;
|
||||
m_pollInvitationsTimer = 0;
|
||||
|
||||
m_fullUpdateRunning = false;
|
||||
m_fullUpdateTimer = 0;
|
||||
|
||||
m_statusUpdateRunning = false;
|
||||
m_statusUpdateTimer = 0;
|
||||
}
|
||||
|
||||
bool TeamClient::isTeamLeader() {
|
||||
if (!m_teamUuid)
|
||||
return false;
|
||||
return m_teamLeader == m_mainPlayer->uuid();
|
||||
}
|
||||
|
||||
bool TeamClient::isTeamLeader(Uuid const& playerUuid) {
|
||||
if (!m_teamUuid)
|
||||
return false;
|
||||
return m_teamLeader == playerUuid;
|
||||
}
|
||||
|
||||
bool TeamClient::isMemberOfTeam() {
|
||||
return (bool)m_teamUuid;
|
||||
}
|
||||
|
||||
void TeamClient::invitePlayer(String const& playerName) {
|
||||
if (playerName.empty())
|
||||
return;
|
||||
|
||||
JsonObject request;
|
||||
request["inviteeName"] = playerName;
|
||||
request["inviterUuid"] = m_mainPlayer->uuid().hex();
|
||||
request["inviterName"] = m_mainPlayer->name();
|
||||
invokeRemote("team.invite", request, [](Json) {});
|
||||
}
|
||||
|
||||
void TeamClient::acceptInvitation(Uuid const& inviterUuid) {
|
||||
JsonObject request;
|
||||
request["inviterUuid"] = inviterUuid.hex();
|
||||
request["inviteeUuid"] = m_mainPlayer->uuid().hex();
|
||||
invokeRemote("team.acceptInvitation", request, [this](Json) { forceUpdate(); });
|
||||
}
|
||||
|
||||
Maybe<Uuid> TeamClient::currentTeam() const {
|
||||
return m_teamUuid;
|
||||
}
|
||||
|
||||
void TeamClient::makeLeader(Uuid const& playerUuid) {
|
||||
if (!m_teamUuid)
|
||||
return;
|
||||
if (!isTeamLeader())
|
||||
return;
|
||||
JsonObject request;
|
||||
request["teamUuid"] = m_teamUuid->hex();
|
||||
request["playerUuid"] = playerUuid.hex();
|
||||
invokeRemote("team.makeLeader", request, [this](Json) { forceUpdate(); });
|
||||
}
|
||||
|
||||
void TeamClient::removeFromTeam(Uuid const& playerUuid) {
|
||||
if (!m_teamUuid)
|
||||
return;
|
||||
if (!isTeamLeader() && playerUuid != m_mainPlayer->uuid())
|
||||
return;
|
||||
JsonObject request;
|
||||
request["teamUuid"] = m_teamUuid->hex();
|
||||
request["playerUuid"] = playerUuid.hex();
|
||||
invokeRemote("team.removeFromTeam", request, [this](Json) { forceUpdate(); });
|
||||
}
|
||||
|
||||
bool TeamClient::hasInvitationPending() {
|
||||
return m_hasPendingInvitation;
|
||||
}
|
||||
|
||||
std::pair<Uuid, String> TeamClient::pullInvitation() {
|
||||
m_hasPendingInvitation = false;
|
||||
return m_pendingInvitation;
|
||||
}
|
||||
|
||||
void TeamClient::update() {
|
||||
handleRpcResponses();
|
||||
|
||||
if (!m_hasPendingInvitation) {
|
||||
if (Time::monotonicTime() - m_pollInvitationsTimer > Root::singleton().assets()->json("/interface.config:invitationPollInterval").toFloat()) {
|
||||
m_pollInvitationsTimer = Time::monotonicTime();
|
||||
JsonObject request;
|
||||
request["playerUuid"] = m_mainPlayer->uuid().hex();
|
||||
invokeRemote("team.pollInvitation", request, [this](Json response) {
|
||||
if (response.isNull())
|
||||
return;
|
||||
if (m_hasPendingInvitation)
|
||||
return;
|
||||
m_pendingInvitation = {Uuid(response.getString("inviterUuid")), response.getString("inviterName")};
|
||||
m_hasPendingInvitation = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
if (!m_fullUpdateRunning) {
|
||||
if (Time::monotonicTime() - m_fullUpdateTimer > Root::singleton().assets()->json("/interface.config:fullUpdateInterval").toFloat()) {
|
||||
m_fullUpdateTimer = Time::monotonicTime();
|
||||
pullFullUpdate();
|
||||
}
|
||||
}
|
||||
if (!m_statusUpdateRunning) {
|
||||
if (Time::monotonicTime() - m_statusUpdateTimer > Root::singleton().assets()->json("/interface.config:statusUpdateInterval").toFloat()) {
|
||||
m_statusUpdateTimer = Time::monotonicTime();
|
||||
statusUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TeamClient::pullFullUpdate() {
|
||||
if (m_fullUpdateRunning)
|
||||
return;
|
||||
m_fullUpdateRunning = true;
|
||||
JsonObject request;
|
||||
request["playerUuid"] = m_mainPlayer->uuid().hex();
|
||||
|
||||
invokeRemote("team.fetchTeamStatus", request, [this](Json response) {
|
||||
m_fullUpdateRunning = false;
|
||||
|
||||
m_teamUuid = response.optString("teamUuid").apply(construct<Uuid>());
|
||||
|
||||
if (m_teamUuid) {
|
||||
m_teamLeader = Uuid(response.getString("leader"));
|
||||
m_members.clear();
|
||||
|
||||
for (auto m : response.getArray("members")) {
|
||||
Member member;
|
||||
member.name = m.getString("name");
|
||||
member.uuid = Uuid(m.getString("uuid"));
|
||||
member.entity = m.getInt("entity");
|
||||
member.healthPercentage = m.getFloat("health");
|
||||
member.energyPercentage = m.getFloat("energy");
|
||||
member.position[0] = m.getFloat("x");
|
||||
member.position[1] = m.getFloat("y");
|
||||
member.world = parseWorldId(m.getString("world"));
|
||||
member.warpMode = WarpModeNames.getLeft(m.getString("warpMode"));
|
||||
member.portrait = jsonToList<Drawable>(m.get("portrait"));
|
||||
m_members.push_back(member);
|
||||
}
|
||||
std::sort(m_members.begin(), m_members.end(), [](Member const& a, Member const& b) { return a.name < b.name; });
|
||||
} else {
|
||||
clearTeam();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void TeamClient::statusUpdate() {
|
||||
if (m_statusUpdateRunning)
|
||||
return;
|
||||
if (!m_teamUuid)
|
||||
return;
|
||||
m_statusUpdateRunning = true;
|
||||
JsonObject request;
|
||||
auto player = m_mainPlayer;
|
||||
|
||||
// TODO: write full player data less often?
|
||||
writePlayerData(request, player, true);
|
||||
|
||||
invokeRemote("team.updateStatus", request, [this](Json) {
|
||||
m_statusUpdateRunning = false;
|
||||
});
|
||||
}
|
||||
|
||||
List<TeamClient::Member> TeamClient::members() {
|
||||
return m_members;
|
||||
}
|
||||
|
||||
void TeamClient::forceUpdate() {
|
||||
m_statusUpdateTimer = 0;
|
||||
m_fullUpdateTimer = 0;
|
||||
m_pollInvitationsTimer = 0;
|
||||
}
|
||||
|
||||
void TeamClient::invokeRemote(String const& method, Json const& args, function<void(Json const&)> responseFunction) {
|
||||
auto promise = m_clientContext->rpcInterface()->invokeRemote(method, args);
|
||||
m_pendingResponses.append({move(promise), move(responseFunction)});
|
||||
}
|
||||
|
||||
void TeamClient::handleRpcResponses() {
|
||||
List<RpcResponseHandler> stillPendingResponses;
|
||||
while (m_pendingResponses.size() > 0) {
|
||||
auto handler = m_pendingResponses.takeLast();
|
||||
if (handler.first.finished()) {
|
||||
if (auto const& res = handler.first.result()) {
|
||||
if (handler.second)
|
||||
handler.second(*res);
|
||||
}
|
||||
} else {
|
||||
stillPendingResponses.append(move(handler));
|
||||
}
|
||||
}
|
||||
m_pendingResponses = stillPendingResponses;
|
||||
}
|
||||
|
||||
void TeamClient::writePlayerData(JsonObject& request, PlayerPtr player, bool fullWrite) const {
|
||||
request["playerUuid"] = player->uuid().hex();
|
||||
request["entity"] = player->entityId();
|
||||
request["health"] = player->health() / player->maxHealth();
|
||||
request["energy"] = player->energy() / player->maxEnergy();
|
||||
request["x"] = player->position()[0];
|
||||
request["y"] = player->position()[1];
|
||||
request["world"] = printWorldId(m_clientContext->playerWorldId());
|
||||
|
||||
WarpMode mode = WarpMode::None;
|
||||
if (player->log()->introComplete()) {
|
||||
if (m_clientContext->playerWorldId().is<CelestialWorldId>())
|
||||
mode = WarpMode::BeamOnly;
|
||||
else
|
||||
mode = player->isDeployed() ? WarpMode::DeployOnly : WarpMode::BeamOnly;
|
||||
}
|
||||
request["warpMode"] = WarpModeNames.getRight(mode);
|
||||
|
||||
if (fullWrite) {
|
||||
request["name"] = player->name();
|
||||
request["portrait"] = jsonFromList(player->portrait(PortraitMode::Head), mem_fn(&Drawable::toJson));
|
||||
}
|
||||
}
|
||||
|
||||
void TeamClient::clearTeam() {
|
||||
m_teamLeader = Uuid();
|
||||
m_teamUuid = {};
|
||||
m_members.clear();
|
||||
forceUpdate();
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue