Karma fixes
This commit is contained in:
+68
-30
@@ -4,7 +4,7 @@ Advanced Karma Plugin for Funguy Bot
|
|||||||
Provides comprehensive karma tracking with leaderboards, trends, and statistics.
|
Provides comprehensive karma tracking with leaderboards, trends, and statistics.
|
||||||
|
|
||||||
Features:
|
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
|
* Track karma history with timestamps
|
||||||
* View karma leaderboards (top/bottom)
|
* View karma leaderboards (top/bottom)
|
||||||
* Rate limiting to prevent spam
|
* Rate limiting to prevent spam
|
||||||
@@ -12,7 +12,7 @@ Features:
|
|||||||
|
|
||||||
Commands:
|
Commands:
|
||||||
!karma - Show this help
|
!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-- <user> - Give -1 karma
|
!karma-- <user> - Give -1 karma
|
||||||
!karma top [n] - Show top karma entries
|
!karma top [n] - Show top karma entries
|
||||||
@@ -26,6 +26,8 @@ Shortcuts:
|
|||||||
!-- <user> - Same as !karma-- <user>
|
!-- <user> - Same as !karma-- <user>
|
||||||
<user>++ - Give +1 karma (inline)
|
<user>++ - Give +1 karma (inline)
|
||||||
<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
|
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):
|
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
|
cache_timestamp[room_id] = now
|
||||||
|
|
||||||
|
|
||||||
def resolve_display_name(room_id, display_name, bot=None):
|
def is_matrix_id(name):
|
||||||
"""Resolve a display name to a Matrix user ID."""
|
"""Return True if the string looks like a Matrix ID (starts with @ and contains :)."""
|
||||||
global display_name_cache
|
return name.startswith('@') and ':' in name
|
||||||
|
|
||||||
# If it's already a valid Matrix ID, return it
|
|
||||||
if display_name.startswith('@') and ':' in display_name:
|
def resolve_display_name(room_id, display_name, bot=None):
|
||||||
return display_name
|
"""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
|
# Check the cache
|
||||||
if room_id in display_name_cache:
|
if room_id in display_name_cache:
|
||||||
@@ -477,7 +486,7 @@ async def handle_command(room, message, bot, prefix, config):
|
|||||||
# !karma++ username
|
# !karma++ username
|
||||||
args = match.args()
|
args = match.args()
|
||||||
if not 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
|
return
|
||||||
display_name = ' '.join(args)
|
display_name = ' '.join(args)
|
||||||
await process_karma_vote(room, display_name, '++', message.sender, bot)
|
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
|
# !karma-- username
|
||||||
args = match.args()
|
args = match.args()
|
||||||
if not 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
|
return
|
||||||
display_name = ' '.join(args)
|
display_name = ' '.join(args)
|
||||||
await process_karma_vote(room, display_name, '--', message.sender, bot)
|
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)
|
# !karma ++ username (space between)
|
||||||
action = args[0]
|
action = args[0]
|
||||||
if len(args) < 2:
|
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
|
return
|
||||||
display_name = ' '.join(args[1:])
|
display_name = ' '.join(args[1:])
|
||||||
await process_karma_vote(room, display_name, action, message.sender, bot)
|
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 ['++', '--']:
|
elif full_cmd in ['++', '--']:
|
||||||
args = match.args()
|
args = match.args()
|
||||||
if not 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
|
return
|
||||||
display_name = ' '.join(args)
|
display_name = ' '.join(args)
|
||||||
await process_karma_vote(room, display_name, full_cmd, message.sender, bot)
|
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}")
|
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
|
# Resolve display name to user ID
|
||||||
user_id = resolve_display_name(room_id, display_name, bot)
|
user_id = resolve_display_name(room_id, display_name, bot)
|
||||||
|
|
||||||
if not user_id:
|
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 (emoji‑friendly).")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Prevent self-modification
|
# Prevent self-modification
|
||||||
@@ -574,14 +590,14 @@ async def handle_karma_command(room, message, bot, config):
|
|||||||
room_id = room.room_id
|
room_id = room.room_id
|
||||||
|
|
||||||
if not args:
|
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>
|
help_text = f"""<details>
|
||||||
<summary>💗 <strong>Karma Plugin Help</strong> (click to expand)</summary>
|
<summary>💗 <strong>Karma Plugin Help</strong> (click to expand)</summary>
|
||||||
|
|
||||||
<strong>Commands:</strong>
|
<strong>Commands:</strong>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>!karma</code> - Show this help</li>
|
<li><code>!karma</code> - Show this help</li>
|
||||||
<li><code>!karma <user></code> - Show karma for a user (use display name or @user:server)</li>
|
<li><code>!karma <user></code> - Show karma for a user (use display name ONLY, no Matrix ID)</li>
|
||||||
<li><code>!karma++ <user></code> - Give +1 karma to a user</li>
|
<li><code>!karma++ <user></code> - Give +1 karma to a user</li>
|
||||||
<li><code>!karma-- <user></code> - Give -1 karma to a user</li>
|
<li><code>!karma-- <user></code> - Give -1 karma to a user</li>
|
||||||
<li><code>!karma top [n]</code> - Show top karma leaders</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><user>--</code> - Give -1 karma (inline)</li>
|
<li><code><user>--</code> - Give -1 karma (inline)</li>
|
||||||
</ul>
|
</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>
|
<strong>Examples:</strong>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>!karma Nexilva</code> - Check Nexilva's karma</li>
|
<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>!karma top 5</code> - Show top 5 leaders</li>
|
||||||
<li><code>Nexilva++</code> - Give Nexilva +1 karma (inline)</li>
|
<li><code>Nexilva++</code> - Give Nexilva +1 karma (inline)</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -622,7 +644,7 @@ async def handle_karma_command(room, message, bot, config):
|
|||||||
|
|
||||||
subcommand = args[0].lower()
|
subcommand = args[0].lower()
|
||||||
|
|
||||||
# !karma top [n]
|
# !karma top [n] - unchanged
|
||||||
if subcommand == "top":
|
if subcommand == "top":
|
||||||
limit = 10
|
limit = 10
|
||||||
if len(args) > 1 and args[1].isdigit():
|
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.")
|
await bot.api.send_markdown_message(room.room_id, "No karma entries found in this room.")
|
||||||
return
|
return
|
||||||
|
|
||||||
# !karma bottom [n]
|
# !karma bottom [n] - unchanged
|
||||||
if subcommand == "bottom":
|
if subcommand == "bottom":
|
||||||
limit = 10
|
limit = 10
|
||||||
if len(args) > 1 and args[1].isdigit():
|
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.")
|
await bot.api.send_markdown_message(room.room_id, "No karma entries found in this room.")
|
||||||
return
|
return
|
||||||
|
|
||||||
# !karma rank <user>
|
# !karma rank <user> - reject Matrix ID
|
||||||
if subcommand == "rank" and len(args) >= 2:
|
if subcommand == "rank" and len(args) >= 2:
|
||||||
display_name = ' '.join(args[1:])
|
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)
|
user_id = resolve_display_name(room_id, display_name, bot)
|
||||||
|
|
||||||
if not user_id:
|
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
|
return
|
||||||
|
|
||||||
rank, total = get_rank(room_id, user_id)
|
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.")
|
await bot.api.send_markdown_message(room.room_id, f"❌ {display_name_resolved} has no karma yet in this room.")
|
||||||
return
|
return
|
||||||
|
|
||||||
# !karma history <user>
|
# !karma history <user> - reject Matrix ID
|
||||||
if subcommand == "history" and len(args) >= 2:
|
if subcommand == "history" and len(args) >= 2:
|
||||||
display_name = ' '.join(args[1:])
|
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)
|
user_id = resolve_display_name(room_id, display_name, bot)
|
||||||
|
|
||||||
if not user_id:
|
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
|
return
|
||||||
|
|
||||||
history = get_recent_history(room_id, user_id, bot, 5)
|
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.")
|
await bot.api.send_markdown_message(room.room_id, f"No karma history for {display_name_resolved} in this room.")
|
||||||
return
|
return
|
||||||
|
|
||||||
# !karma stats
|
# !karma stats - unchanged
|
||||||
if subcommand == "stats":
|
if subcommand == "stats":
|
||||||
stats = get_stats(room_id)
|
stats = get_stats(room_id)
|
||||||
response = f"📊 **Karma System Statistics for this Room**\n\n"
|
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)
|
await bot.api.send_markdown_message(room.room_id, response)
|
||||||
return
|
return
|
||||||
|
|
||||||
# !karma <user> (show karma for specific user)
|
# !karma <user> (show karma for specific user) - reject Matrix ID
|
||||||
display_name = ' '.join(args)
|
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)
|
user_id = resolve_display_name(room_id, display_name, bot)
|
||||||
|
|
||||||
if not user_id:
|
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
|
return
|
||||||
|
|
||||||
points = get_karma(room_id, user_id)
|
points = get_karma(room_id, user_id)
|
||||||
@@ -755,6 +786,12 @@ async def handle_inline_karma(room, message, bot):
|
|||||||
responses = []
|
responses = []
|
||||||
for display_name, operator in matches:
|
for display_name, operator in matches:
|
||||||
display_name = display_name.strip()
|
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
|
change = 1 if operator == '++' else -1
|
||||||
|
|
||||||
# Resolve display name to user ID
|
# Resolve display name to user ID
|
||||||
@@ -808,7 +845,7 @@ def setup(bot):
|
|||||||
init_db()
|
init_db()
|
||||||
|
|
||||||
logging.info("Advanced Karma plugin loaded successfully")
|
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("Commands: !karma, !karma++, !karma--, !++, !--, and inline ++/--")
|
||||||
logging.info("=" * 50)
|
logging.info("=" * 50)
|
||||||
|
|
||||||
@@ -817,14 +854,14 @@ def setup(bot):
|
|||||||
# Plugin Metadata
|
# Plugin Metadata
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
__version__ = "1.0.0"
|
__version__ = "1.0.1"
|
||||||
__author__ = "Funguy Bot"
|
__author__ = "Funguy Bot"
|
||||||
__description__ = "Room karma tracking system"
|
__description__ = "Room karma tracking system (display names only, no Matrix IDs)"
|
||||||
__help__ = """
|
__help__ = """
|
||||||
<details>
|
<details>
|
||||||
<summary><strong>!karma</strong> – Karma system</summary>
|
<summary><strong>!karma</strong> – Karma system</summary>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>!karma <user></code> – Show points</li>
|
<li><code>!karma <user></code> – Show points (use display name, not Matrix ID)</li>
|
||||||
<li><code>!karma++ <user></code> / <code>!-- <user></code> – Modify karma</li>
|
<li><code>!karma++ <user></code> / <code>!-- <user></code> – Modify karma</li>
|
||||||
<li><code>!karma top [n]</code> / <code>!karma bottom [n]</code> – Leaderboard</li>
|
<li><code>!karma top [n]</code> / <code>!karma bottom [n]</code> – Leaderboard</li>
|
||||||
<li><code>!karma rank <user></code> – Position</li>
|
<li><code>!karma rank <user></code> – Position</li>
|
||||||
@@ -832,5 +869,6 @@ __help__ = """
|
|||||||
<li><code>!karma history <user></code> – Recent votes</li>
|
<li><code>!karma history <user></code> – Recent votes</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>Shortcuts: <code>!++ user</code>, <code>!-- user</code>, and inline <code>user++</code> / <code>user--</code>.</p>
|
<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>
|
</details>
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user