Home / Pastebin / P2l1vNfNVRv5QvsYmHD4UmE97kOFEUvz
Back to Pastebin

floatlimit.py

dracorex  ·  March 31, 2026, 5:30 a.m.  ·  43 views
Plain Text

							
import hexchat

__module_name__ = "FloatLimit"
__module_version__ = "1.3"
__module_description__ = "Maintains a float limit (+l users+1) for specific channels on AustNet"

# Configuration
ALLOWED_SERVERS = ["austnet.org"] # Matches any server containing this string
ALLOWED_CHANNELS = ["#aussiechat"] # Start empty, use /floatlimit add #channel

timers = {}
channel_limits = {}

def is_allowed_context(context):
    server = context.get_info("server")
    channel = context.get_info("channel")
    
    if not server or not channel:
        return False
        
    server = server.lower()
    channel = channel.lower()
    
    server_allowed = any(allowed.lower() in server for allowed in ALLOWED_SERVERS)
    # If ALLOWED_CHANNELS is empty, we don't allow anything (as requested: "not all")
    channel_allowed = any(allowed.lower() == channel for allowed in ALLOWED_CHANNELS)
    
    return server_allowed and channel_allowed

def is_op(context):
    if not is_allowed_context(context):
        return False
        
    my_nick = context.get_info("nick")
    users = context.get_list("users")
    if not users:
        return False
    for user in users:
        if user.nick == my_nick:
            # Check for @ (Op), % (Half-Op), & (Admin), ~ (Owner)
            return bool(user.prefix and any(p in user.prefix for p in '@~&%'))
    return False

def update_limit(context):
    if not context or not is_op(context):
        return
        
    users = context.get_list("users")
    if not users:
        return
        
    channel = context.get_info("channel")
    server = context.get_info("server")
    if not channel or not server:
        return
        
    key = f"{server}-{channel}"
    new_limit = len(users) + 1
    
    if channel_limits.get(key) != new_limit:
        context.command(f"MODE {channel} +l {new_limit}")
        channel_limits[key] = new_limit

def on_join(word, word_eol, userdata):
    context = hexchat.get_context()
    if not is_allowed_context(context):
        return hexchat.PRI_NORM
        
    channel = context.get_info("channel")
    server = context.get_info("server")
    key = f"{server}-{channel}"
    
    if key in timers:
        hexchat.unhook(timers[key])
        
    def timer_cb(userdata):
        update_limit(context)
        if key in timers:
            del timers[key]
        return 0
        
    timers[key] = hexchat.hook_timer(30000, timer_cb)
    return hexchat.PRI_NORM

def on_part_or_kick(word, word_eol, userdata):
    context = hexchat.get_context()
    if not is_allowed_context(context):
        return hexchat.PRI_NORM
        
    def delayed_update(userdata):
        update_limit(context)
        return 0
    hexchat.hook_timer(500, delayed_update)
    return hexchat.PRI_NORM

def on_quit(word, word_eol, userdata):
    def delayed_update(userdata):
        for chan in hexchat.get_list("channels"):
            if chan.type == 2 and is_allowed_context(chan.context):
                update_limit(chan.context)
        return 0
    hexchat.hook_timer(500, delayed_update)
    return hexchat.PRI_NORM

def floatlimit_cb(word, word_eol, userdata):
    global ALLOWED_CHANNELS
    if len(word) < 2:
        print(f"FloatLimit: Current channels: {', '.join(ALLOWED_CHANNELS) if ALLOWED_CHANNELS else 'None'}")
        print("Usage: /floatlimit add #channel | /floatlimit del #channel")
        return hexchat.EAT_ALL

    cmd = word[1].lower()
    if cmd == "add" and len(word) > 2:
        chan = word[2].lower()
        if chan not in ALLOWED_CHANNELS:
            ALLOWED_CHANNELS.append(chan)
            print(f"FloatLimit: Added {chan}")
            update_limit(hexchat.get_context())
    elif cmd == "del" and len(word) > 2:
        chan = word[2].lower()
        if chan in ALLOWED_CHANNELS:
            ALLOWED_CHANNELS.remove(chan)
            print(f"FloatLimit: Removed {chan}")
    
    return hexchat.EAT_ALL

hexchat.hook_print("Join", on_join)
hexchat.hook_print("Part", on_part_or_kick)
hexchat.hook_print("Part with Reason", on_part_or_kick)
hexchat.hook_print("Kick", on_part_or_kick)
hexchat.hook_print("Quit", on_quit)
hexchat.hook_command("floatlimit", floatlimit_cb, help="/floatlimit add|del #channel")

print(f"{__module_name__} v{__module_version__} loaded. Use /floatlimit add #channel to enable it.")

Actions

Paste Info

ID: P2l1vNfNVRv5QvsYmHD4UmE97kOFEUvz
Language: Plain Text
Size: 4445 chars
Expires: Never