Karma fixes

This commit is contained in:
2026-05-07 13:48:54 -05:00
parent 972f34a25a
commit 4b10c13b29
+68 -30
View File
@@ -4,7 +4,7 @@ Advanced Karma Plugin for Funguy Bot
Provides comprehensive karma tracking with leaderboards, trends, and statistics.
Features:
* Give/take karma points from users using display names or Matrix IDs
* Give/take karma points from users using display names ONLY (Matrix IDs are rejected)
* Track karma history with timestamps
* View karma leaderboards (top/bottom)
* Rate limiting to prevent spam
@@ -12,7 +12,7 @@ Features:
Commands:
!karma - Show this help
!karma <user> - Show karma for a user
!karma <user> - Show karma for a user (display name only)
!karma++ <user> - Give +1 karma
!karma-- <user> - Give -1 karma
!karma top [n] - Show top karma entries
@@ -26,6 +26,8 @@ Shortcuts:
!-- <user> - Same as !karma-- <user>
<user>++ - Give +1 karma (inline)
<user>-- - Give -1 karma (inline)
NOTE: Matrix IDs (e.g., @user:server) are NOT accepted. Use display names only.
"""
import sqlite3
@@ -113,7 +115,7 @@ def get_connection():
# ---------------------------------------------------------------------------
# Display Name Resolution
# Display Name Resolution (Matrix IDs are rejected)
# ---------------------------------------------------------------------------
async def refresh_display_name_cache(bot, room_id):
@@ -163,13 +165,20 @@ async def refresh_display_name_cache(bot, room_id):
cache_timestamp[room_id] = now
def resolve_display_name(room_id, display_name, bot=None):
"""Resolve a display name to a Matrix user ID."""
global display_name_cache
def is_matrix_id(name):
"""Return True if the string looks like a Matrix ID (starts with @ and contains :)."""
return name.startswith('@') and ':' in name
# If it's already a valid Matrix ID, return it
if display_name.startswith('@') and ':' in display_name:
return display_name
def resolve_display_name(room_id, display_name, bot=None):
"""Resolve a display name to a Matrix user ID.
Returns None if the input is a Matrix ID (rejected) or if the name
cannot be resolved.
"""
# Reject Matrix IDs outright
if is_matrix_id(display_name):
return None
# Check the cache
if room_id in display_name_cache:
@@ -477,7 +486,7 @@ async def handle_command(room, message, bot, prefix, config):
# !karma++ username
args = match.args()
if not args:
await bot.api.send_markdown_message(room.room_id, "Usage: !karma++ <username>")
await bot.api.send_markdown_message(room.room_id, "Usage: !karma++ <username> (display name only, no Matrix ID)")
return
display_name = ' '.join(args)
await process_karma_vote(room, display_name, '++', message.sender, bot)
@@ -487,7 +496,7 @@ async def handle_command(room, message, bot, prefix, config):
# !karma-- username
args = match.args()
if not args:
await bot.api.send_markdown_message(room.room_id, "Usage: !karma-- <username>")
await bot.api.send_markdown_message(room.room_id, "Usage: !karma-- <username> (display name only, no Matrix ID)")
return
display_name = ' '.join(args)
await process_karma_vote(room, display_name, '--', message.sender, bot)
@@ -500,7 +509,7 @@ async def handle_command(room, message, bot, prefix, config):
# !karma ++ username (space between)
action = args[0]
if len(args) < 2:
await bot.api.send_markdown_message(room.room_id, f"Usage: !karma {action} <username>")
await bot.api.send_markdown_message(room.room_id, f"Usage: !karma {action} <username> (display name only)")
return
display_name = ' '.join(args[1:])
await process_karma_vote(room, display_name, action, message.sender, bot)
@@ -514,7 +523,7 @@ async def handle_command(room, message, bot, prefix, config):
elif full_cmd in ['++', '--']:
args = match.args()
if not args:
await bot.api.send_markdown_message(room.room_id, f"Usage: !{full_cmd} <username>\nExample: !{full_cmd} Nexilva")
await bot.api.send_markdown_message(room.room_id, f"Usage: !{full_cmd} <username> (display name only)\nExample: !{full_cmd} Nexilva")
return
display_name = ' '.join(args)
await process_karma_vote(room, display_name, full_cmd, message.sender, bot)
@@ -533,11 +542,18 @@ async def process_karma_vote(room, display_name, action, voter, bot):
logging.info(f"Karma vote: {voter_str} -> '{display_name}' ({action}, change={change:+d}) in room {room_id}")
# Reject Matrix IDs
if is_matrix_id(display_name):
await bot.api.send_markdown_message(room.room_id,
"❌ Please use the user's **display name** (e.g., 'Nexilva') Matrix IDs (like @user:server) are not allowed.")
return
# Resolve display name to user ID
user_id = resolve_display_name(room_id, display_name, bot)
if not user_id:
await bot.api.send_markdown_message(room.room_id, f"❌ Could not find user '{display_name}'. Please use their display name or Matrix ID (e.g., @username:server)")
await bot.api.send_markdown_message(room.room_id,
f"❌ Could not find user with display name '{display_name}'. Make sure they are in this room and that the name is spelled correctly (emojifriendly).")
return
# Prevent self-modification
@@ -574,14 +590,14 @@ async def handle_karma_command(room, message, bot, config):
room_id = room.room_id
if not args:
# Show help for !karma command in collapsible details tag with proper HTML lists
# Show help for !karma command (unchanged, but note in help that Matrix IDs are rejected)
help_text = f"""<details>
<summary>💗 <strong>Karma Plugin Help</strong> (click to expand)</summary>
<strong>Commands:</strong>
<ul>
<li><code>!karma</code> - Show this help</li>
<li><code>!karma &lt;user&gt;</code> - Show karma for a user (use display name or @user:server)</li>
<li><code>!karma &lt;user&gt;</code> - Show karma for a user (use display name ONLY, no Matrix ID)</li>
<li><code>!karma++ &lt;user&gt;</code> - Give +1 karma to a user</li>
<li><code>!karma-- &lt;user&gt;</code> - Give -1 karma to a user</li>
<li><code>!karma top [n]</code> - Show top karma leaders</li>
@@ -599,10 +615,16 @@ async def handle_karma_command(room, message, bot, config):
<li><code>&lt;user&gt;--</code> - Give -1 karma (inline)</li>
</ul>
<strong>Important:</strong>
<ul>
<li>❌ <strong>Matrix IDs (e.g., @user:server) are NOT accepted.</strong> Use the person's display name (what you see in chat).</li>
<li>✅ Examples: <code>!karma++ Nexilva</code> or <code>Nexilva++</code></li>
</ul>
<strong>Examples:</strong>
<ul>
<li><code>!karma Nexilva</code> - Check Nexilva's karma</li>
<li><code>!karma++ @hb:matrix.org</code> - Give HB +1 karma</li>
<li><code>!karma++ "🍄 HB🍄"</code> - Give HB +1 karma</li>
<li><code>!karma top 5</code> - Show top 5 leaders</li>
<li><code>Nexilva++</code> - Give Nexilva +1 karma (inline)</li>
</ul>
@@ -622,7 +644,7 @@ async def handle_karma_command(room, message, bot, config):
subcommand = args[0].lower()
# !karma top [n]
# !karma top [n] - unchanged
if subcommand == "top":
limit = 10
if len(args) > 1 and args[1].isdigit():
@@ -640,7 +662,7 @@ async def handle_karma_command(room, message, bot, config):
await bot.api.send_markdown_message(room.room_id, "No karma entries found in this room.")
return
# !karma bottom [n]
# !karma bottom [n] - unchanged
if subcommand == "bottom":
limit = 10
if len(args) > 1 and args[1].isdigit():
@@ -657,13 +679,16 @@ async def handle_karma_command(room, message, bot, config):
await bot.api.send_markdown_message(room.room_id, "No karma entries found in this room.")
return
# !karma rank <user>
# !karma rank <user> - reject Matrix ID
if subcommand == "rank" and len(args) >= 2:
display_name = ' '.join(args[1:])
if is_matrix_id(display_name):
await bot.api.send_markdown_message(room.room_id, "❌ Please use a display name, not a Matrix ID.")
return
user_id = resolve_display_name(room_id, display_name, bot)
if not user_id:
await bot.api.send_markdown_message(room.room_id, f"❌ Could not find user '{display_name}'")
await bot.api.send_markdown_message(room.room_id, f"❌ Could not find user with display name '{display_name}'")
return
rank, total = get_rank(room_id, user_id)
@@ -678,13 +703,16 @@ async def handle_karma_command(room, message, bot, config):
await bot.api.send_markdown_message(room.room_id, f"{display_name_resolved} has no karma yet in this room.")
return
# !karma history <user>
# !karma history <user> - reject Matrix ID
if subcommand == "history" and len(args) >= 2:
display_name = ' '.join(args[1:])
if is_matrix_id(display_name):
await bot.api.send_markdown_message(room.room_id, "❌ Please use a display name, not a Matrix ID.")
return
user_id = resolve_display_name(room_id, display_name, bot)
if not user_id:
await bot.api.send_markdown_message(room.room_id, f"❌ Could not find user '{display_name}'")
await bot.api.send_markdown_message(room.room_id, f"❌ Could not find user with display name '{display_name}'")
return
history = get_recent_history(room_id, user_id, bot, 5)
@@ -706,7 +734,7 @@ async def handle_karma_command(room, message, bot, config):
await bot.api.send_markdown_message(room.room_id, f"No karma history for {display_name_resolved} in this room.")
return
# !karma stats
# !karma stats - unchanged
if subcommand == "stats":
stats = get_stats(room_id)
response = f"📊 **Karma System Statistics for this Room**\n\n"
@@ -719,12 +747,15 @@ async def handle_karma_command(room, message, bot, config):
await bot.api.send_markdown_message(room.room_id, response)
return
# !karma <user> (show karma for specific user)
# !karma <user> (show karma for specific user) - reject Matrix ID
display_name = ' '.join(args)
if is_matrix_id(display_name):
await bot.api.send_markdown_message(room.room_id, "❌ Please use a display name, not a Matrix ID.")
return
user_id = resolve_display_name(room_id, display_name, bot)
if not user_id:
await bot.api.send_markdown_message(room.room_id, f"❌ Could not find user '{display_name}'")
await bot.api.send_markdown_message(room.room_id, f"❌ Could not find user with display name '{display_name}'")
return
points = get_karma(room_id, user_id)
@@ -755,6 +786,12 @@ async def handle_inline_karma(room, message, bot):
responses = []
for display_name, operator in matches:
display_name = display_name.strip()
# Reject Matrix IDs inline as well
if is_matrix_id(display_name):
logging.debug(f"Skipping inline Matrix ID: '{display_name}'")
continue
change = 1 if operator == '++' else -1
# Resolve display name to user ID
@@ -808,7 +845,7 @@ def setup(bot):
init_db()
logging.info("Advanced Karma plugin loaded successfully")
logging.info("Supports display names (e.g., 'Nexilva' or '🍄 HB🍄') and Matrix IDs")
logging.info("Matrix IDs are now rejected use display names only.")
logging.info("Commands: !karma, !karma++, !karma--, !++, !--, and inline ++/--")
logging.info("=" * 50)
@@ -817,14 +854,14 @@ def setup(bot):
# Plugin Metadata
# ---------------------------------------------------------------------------
__version__ = "1.0.0"
__version__ = "1.0.1"
__author__ = "Funguy Bot"
__description__ = "Room karma tracking system"
__description__ = "Room karma tracking system (display names only, no Matrix IDs)"
__help__ = """
<details>
<summary><strong>!karma</strong> Karma system</summary>
<ul>
<li><code>!karma &lt;user&gt;</code> Show points</li>
<li><code>!karma &lt;user&gt;</code> Show points (use display name, not Matrix ID)</li>
<li><code>!karma++ &lt;user&gt;</code> / <code>!-- &lt;user&gt;</code> Modify karma</li>
<li><code>!karma top [n]</code> / <code>!karma bottom [n]</code> Leaderboard</li>
<li><code>!karma rank &lt;user&gt;</code> Position</li>
@@ -832,5 +869,6 @@ __help__ = """
<li><code>!karma history &lt;user&gt;</code> Recent votes</li>
</ul>
<p>Shortcuts: <code>!++ user</code>, <code>!-- user</code>, and inline <code>user++</code> / <code>user--</code>.</p>
<p><strong>Important:</strong> Matrix IDs (like @user:server) are <strong>not accepted</strong>. Use the person's display name exactly as you see it in chat.</p>
</details>
"""