Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## [X.X.X] - 202X-XX-XX

### Added

- Storing platform from Discord's `activity.platform` field (or a special case for Steam Deck). Defaults to `pc` if not specified. Existing activity will have `pc` set as their platform.

## [0.2.0] - 2025-04-23

### Added
Expand Down
41 changes: 33 additions & 8 deletions oblivionis/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ def are_activities_equal(a, b) -> bool:
return x.name == y.name and x.application_id == y.application_id
return False

def application_id_from_activity(activity) -> str:
"""Returns application_id if present. Fallsback to name if not."""
if hasattr(activity, "application_id"):
return activity.application_id
# When playing on PS5, application_id seems to be missing
logger.warning("Activity %s does not have application_id, using name instead...", activity.name)
return activity.name

def game_from_activity(activity) -> str:
if activity.name == "Steam Deck":
Expand All @@ -47,10 +54,21 @@ def get_game_activity(activities):
def get_stored_activity(member, activity) -> dict | None:
"""Get an applicable activity from the in-memory storage."""
stored = activities.pop(member.id, None)
if stored and stored["application_id"] == activity.application_id:
if stored and stored["application_id"] == application_id_from_activity(activity):
return stored
return None

def platform_from_activity(activity) -> str:
"""Get the platform from the activity. Fallbacks to pc."""
if activity.name == "Steam Deck":
# Decky Discord Status plugin will sometimes say game name is "Steam Deck",
# and put actual game name in description (see game_from_activity())
return "steamdeck"
platform = activity.platform or "pc"
if platform == "desktop":
# Some games say "desktop", lets just lump it together with "pc"
platform = "pc"
return platform

@bot.event
async def on_guild_available(guild):
Expand Down Expand Up @@ -87,10 +105,14 @@ async def on_presence_update(before, after):
duration = datetime.datetime.now(datetime.UTC) - start
duration_seconds = round(duration.total_seconds())

game_name = game_from_activity(activity)
platform_name = platform_from_activity(activity)

logger.info(
"Member %s has stopped playing %s after %s seconds",
"Member %s has stopped playing %s (%s) after %s seconds",
after,
game_from_activity(activity),
game_name,
platform_name,
duration_seconds,
)
user, user_created = storage.User.get_or_create(
Expand All @@ -100,26 +122,29 @@ async def on_presence_update(before, after):
logger.info("Added new user '%s' to database", before.name)

game, game_created = storage.Game.get_or_create(
name=game_from_activity(activity)
name=game_name
)
if game_created:
logger.info("Added new game '%s' to database", game.name)
storage.Activity.create(user=user, game=game, seconds=duration_seconds)
storage.Activity.create(user=user, game=game, seconds=duration_seconds, platform=platform_name)
elif after_activity is not None:
application_id = application_id_from_activity(after_activity)
if (
after.id not in activities
or activities[after.id]["application_id"] != after_activity.application_id
or activities[after.id]["application_id"] != application_id
):
activities[after.id] = {
"application_id": after_activity.application_id,
"application_id": application_id,
"name": after_activity.name,
"start": after_activity.start,
"timestamp": datetime.datetime.now(datetime.UTC),
}

logger.info(
"Member %s has started playing %s",
"Member %s has started playing %s (%s)",
after,
game_from_activity(after_activity),
platform_from_activity(after_activity),
)


Expand Down
3 changes: 3 additions & 0 deletions oblivionis/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,11 @@ class Activity(BaseModel):
user = ForeignKeyField(User)
game = ForeignKeyField(Game)
seconds = IntegerField()
platform = CharField(default="pc")


def connect_db():
db.connect()
db.create_tables([User, Game, Activity])
# add platform column to activity table if it does not exist
db.execute_sql("ALTER TABLE activity ADD COLUMN IF NOT EXISTS platform VARCHAR DEFAULT 'pc'")
Loading