Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/application/StarP2PNetworkingService_pc.cpp24
-rw-r--r--source/application/StarP2PNetworkingService_pc.hpp4
-rw-r--r--source/client/StarClientApplication.cpp76
-rw-r--r--source/client/StarClientApplication.hpp1
-rw-r--r--source/core/StarText.cpp2
-rw-r--r--source/game/StarRootLoader.cpp4
-rw-r--r--source/platform/StarP2PNetworkingService.hpp2
7 files changed, 99 insertions, 14 deletions
diff --git a/source/application/StarP2PNetworkingService_pc.cpp b/source/application/StarP2PNetworkingService_pc.cpp
index 2d20415..0e13dee 100644
--- a/source/application/StarP2PNetworkingService_pc.cpp
+++ b/source/application/StarP2PNetworkingService_pc.cpp
@@ -81,7 +81,11 @@ void PcP2PNetworkingService::setJoinRemote(HostAddressWithPort location) {
setJoinLocation(JoinRemote(location));
}
-void Star::PcP2PNetworkingService::setActivityData([[maybe_unused]] String const& title, [[maybe_unused]] Maybe<pair<uint16_t, uint16_t>> party) {
+void Star::PcP2PNetworkingService::setActivityData(
+ [[maybe_unused]] const char* title,
+ [[maybe_unused]] const char* details,
+ [[maybe_unused]] int64_t startTime,
+ [[maybe_unused]] Maybe<pair<uint16_t, uint16_t>> party) {
#ifdef STAR_ENABLE_DISCORD_INTEGRATION
MutexLocker discordLocker(m_state->discordMutex);
#endif
@@ -92,19 +96,25 @@ void Star::PcP2PNetworkingService::setActivityData([[maybe_unused]] String const
if (m_discordUpdatingActivity)
return;
- if (title != m_discordActivityTitle || party != m_discordPartySize || m_discordForceUpdateActivity) {
+ if (title != m_discordActivityTitle
+ || details != m_discordActivityDetails
+ || startTime != m_discordActivityStartTime || party != m_discordPartySize || m_discordForceUpdateActivity) {
m_discordForceUpdateActivity = false;
m_discordPartySize = party;
m_discordActivityTitle = title;
+ m_discordActivityDetails = details;
+ m_discordActivityStartTime = startTime;
discord::Activity activity = {};
activity.SetType(discord::ActivityType::Playing);
activity.SetName("Starbound");
- activity.SetState(title.utf8Ptr());
-
- if (auto p = party) {
- activity.GetParty().GetSize().SetCurrentSize(p->first);
- activity.GetParty().GetSize().SetMaxSize(p->second);
+ activity.SetState(title);
+ activity.SetDetails(details);
+ activity.GetTimestamps().SetStart(startTime);
+ if (party) {
+ auto& size = activity.GetParty().GetSize();
+ size.SetCurrentSize(party->first);
+ size.SetMaxSize(party->second);
}
if (auto lobby = m_discordServerLobby)
diff --git a/source/application/StarP2PNetworkingService_pc.hpp b/source/application/StarP2PNetworkingService_pc.hpp
index 20fbefb..293b6bf 100644
--- a/source/application/StarP2PNetworkingService_pc.hpp
+++ b/source/application/StarP2PNetworkingService_pc.hpp
@@ -18,7 +18,7 @@ public:
void setJoinUnavailable() override;
void setJoinLocal(uint32_t capacity) override;
void setJoinRemote(HostAddressWithPort location) override;
- void setActivityData(String const& title, Maybe<pair<uint16_t, uint16_t>>) override;
+ void setActivityData(const char* title, const char* details, int64_t startTime, Maybe<pair<uint16_t, uint16_t>>) override;
MVariant<P2PNetworkingPeerId, HostAddressWithPort> pullPendingJoin() override;
Maybe<pair<String, RpcPromiseKeeper<P2PJoinRequestReply>>> pullJoinRequest() override;
@@ -125,6 +125,8 @@ private:
HashMap<discord::UserId, DiscordP2PSocket*> m_discordOpenSockets;
String m_discordActivityTitle;
+ String m_discordActivityDetails;
+ int64_t m_discordActivityStartTime = 0;
Maybe<pair<uint16_t, uint16_t>> m_discordPartySize;
bool m_discordForceUpdateActivity = false;
bool m_discordUpdatingActivity = false;
diff --git a/source/client/StarClientApplication.cpp b/source/client/StarClientApplication.cpp
index b3460c1..7faf7ec 100644
--- a/source/client/StarClientApplication.cpp
+++ b/source/client/StarClientApplication.cpp
@@ -584,6 +584,7 @@ void ClientApplication::changeState(MainAppState newState) {
m_mainMixer->setUniverseClient(m_universeClient);
m_universeClient->setMainPlayer(m_player);
m_cinematicOverlay->setPlayer(m_player);
+ m_timeSinceJoin = (int64_t)Time::millisecondsSinceEpoch() / 1000;
auto assets = m_root->assets();
String loadingCinematic = assets->json("/client.config:loadingCinematic").toString();
@@ -748,8 +749,36 @@ void ClientApplication::updateTitle(float dt) {
appController()->setAcceptingTextInput(m_titleScreen->textInputActive());
auto p2pNetworkingService = appController()->p2pNetworkingService();
- if (p2pNetworkingService)
- p2pNetworkingService->setActivityData("In Main Menu", {});
+ if (p2pNetworkingService) {
+ auto getStateString = [](TitleState state) -> const char* {
+ switch (state) {
+ case TitleState::Main:
+ return "In Main Menu";
+ case TitleState::Options:
+ return "In Options";
+ case TitleState::Mods:
+ return "In Mods";
+ case TitleState::SinglePlayerSelectCharacter:
+ return "Selecting a character for singleplayer";
+ case TitleState::SinglePlayerCreateCharacter:
+ return "Creating a character for singleplayer";
+ case TitleState::MultiPlayerSelectCharacter:
+ return "Selecting a character for multiplayer";
+ case TitleState::MultiPlayerCreateCharacter:
+ return "Creating a character for multiplayer";
+ case TitleState::MultiPlayerConnect:
+ return "Awaiting multiplayer connection info";
+ case TitleState::StartSinglePlayer:
+ return "Loading Singleplayer";
+ case TitleState::StartMultiPlayer:
+ return "Connecting to Multiplayer";
+ default:
+ return "";
+ }
+ };
+
+ p2pNetworkingService->setActivityData("Not In Game", getStateString(m_titleScreen->currentState()), 0, {});
+ }
if (m_titleScreen->currentState() == TitleState::StartSinglePlayer) {
changeState(MainAppState::SinglePlayer);
@@ -791,6 +820,7 @@ void ClientApplication::updateTitle(float dt) {
void ClientApplication::updateRunning(float dt) {
try {
+ auto worldClient = m_universeClient->worldClient();
auto p2pNetworkingService = appController()->p2pNetworkingService();
bool clientIPJoinable = m_root->configuration()->get("clientIPJoinable").toBool();
bool clientP2PJoinable = m_root->configuration()->get("clientP2PJoinable").toBool();
@@ -817,8 +847,44 @@ void ClientApplication::updateRunning(float dt) {
}
}
- if (p2pNetworkingService)
- p2pNetworkingService->setActivityData("In Game", party);
+ if (p2pNetworkingService) {
+ auto getActivityDetail = [&](String const& tag) -> String {
+ if (tag == "playerName")
+ return Text::stripEscapeCodes(m_player->name());
+ if (tag == "playerHealth")
+ return strf("{}/{} HP", m_player->health(), m_player->maxHealth());
+ if (tag == "playerEnergy")
+ return strf("{}/{} HP", m_player->energy(), m_player->maxEnergy());
+ if (tag == "playerBreath")
+ return strf("{}/{} HP", m_player->breath(), m_player->maxBreath());
+ if (tag == "worldName") {
+ if (m_universeClient->clientContext()->playerWorldId().is<ClientShipWorldId>())
+ return "Player Ship";
+ else if (WorldTemplate const* worldTemplate = worldClient ? worldClient->currentTemplate().get() : nullptr) {
+ auto worldName = worldTemplate->worldName();
+ if (worldName.empty())
+ return "In World";
+ else
+ return Text::stripEscapeCodes(worldName);
+ }
+ else
+ return "Nowhere";
+ }
+ return "";
+ };
+
+ String finalDetails = "";
+ Json activityDetails = m_root->configuration()->getPath("discord.activityDetails");
+ if (activityDetails.isType(Json::Type::Array)) {
+ StringList detailsList;
+ for (auto& detail : activityDetails.iterateArray())
+ detailsList.append(getActivityDetail(*detail.stringPtr()));
+ finalDetails = detailsList.join("\n");
+ } else if (activityDetails.isType(Json::Type::String))
+ finalDetails = activityDetails.toString().lookupTags(getActivityDetail);
+
+ p2pNetworkingService->setActivityData("In Game", finalDetails.utf8Ptr(), m_timeSinceJoin, party);
+ }
if (!m_mainInterface->inputFocus() && !m_cinematicOverlay->suppressInput()) {
m_player->setShifting(isActionTaken(InterfaceAction::PlayerShifting));
@@ -932,7 +998,7 @@ void ClientApplication::updateRunning(float dt) {
if (checkDisconnection())
return;
- if (auto worldClient = m_universeClient->worldClient()) {
+ if (worldClient) {
m_worldPainter->update(dt);
auto& broadcastCallback = worldClient->broadcastCallback();
if (!broadcastCallback) {
diff --git a/source/client/StarClientApplication.hpp b/source/client/StarClientApplication.hpp
index f0eacb0..58abb9d 100644
--- a/source/client/StarClientApplication.hpp
+++ b/source/client/StarClientApplication.hpp
@@ -121,6 +121,7 @@ private:
Maybe<PendingMultiPlayerConnection> m_pendingMultiPlayerConnection;
Maybe<HostAddressWithPort> m_currentRemoteJoin;
+ int64_t m_timeSinceJoin = 0;
};
}
diff --git a/source/core/StarText.cpp b/source/core/StarText.cpp
index d507fd4..749fd90 100644
--- a/source/core/StarText.cpp
+++ b/source/core/StarText.cpp
@@ -36,6 +36,8 @@ namespace Text {
static auto stripEscapeRegex = std::regex(strf("\\{:c}[^;]*{:c}", CmdEsc, EndEsc));
String stripEscapeCodes(String const& s) {
+ if (s.empty())
+ return s;
return std::regex_replace(s.utf8(), stripEscapeRegex, "");
}
diff --git a/source/game/StarRootLoader.cpp b/source/game/StarRootLoader.cpp
index 1643791..b2be4e9 100644
--- a/source/game/StarRootLoader.cpp
+++ b/source/game/StarRootLoader.cpp
@@ -99,6 +99,10 @@ R"JSON(
"inventory" : {
"pickupToActionBar" : true
+ },
+
+ "discord" : {
+ "activityDetails" : "<playerName> | <worldName>"
}
}
)JSON");
diff --git a/source/platform/StarP2PNetworkingService.hpp b/source/platform/StarP2PNetworkingService.hpp
index 288902c..134e1b1 100644
--- a/source/platform/StarP2PNetworkingService.hpp
+++ b/source/platform/StarP2PNetworkingService.hpp
@@ -44,7 +44,7 @@ public:
// P2P friends can join this player at the given remote server
virtual void setJoinRemote(HostAddressWithPort location) = 0;
// Updates rich presence activity info
- virtual void setActivityData(String const& title, Maybe<pair<uint16_t, uint16_t>>) = 0;
+ virtual void setActivityData(const char* title, const char* details, int64_t startTime, Maybe<pair<uint16_t, uint16_t>>) = 0;
// If this player joins another peer's game using the P2P UI, this will return
// a pending join location