URI: 
       Add more syncpoints to prevent idle cheating. - annna - Annna the nice friendly bot.
  HTML git clone git://bitreich.org/annna/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/annna/
   DIR Log
   DIR Files
   DIR Refs
   DIR Tags
   DIR README
       ---
   DIR commit 17748414fa5683110077bdfb7c882322d307cde7
   DIR parent 255e6d75c84b3ec7f476d72aee6c7856189352f8
  HTML Author: Annna Robert-Houdin <annna@bitreich.org>
       Date:   Sun, 17 Sep 2023 21:37:54 +0200
       
       Add more syncpoints to prevent idle cheating.
       
       Diffstat:
         M modules/idlerpg/idlerpg-channel-se… |      75 ++++++++++++++++++++++++-------
       
       1 file changed, 59 insertions(+), 16 deletions(-)
       ---
   DIR diff --git a/modules/idlerpg/idlerpg-channel-service.py b/modules/idlerpg/idlerpg-channel-service.py
       @@ -86,18 +86,22 @@ def main(args):
            chanpath = "%s/%s" % (serverpath, channel)
        
            chaninpath = "%s/in" % (chanpath)
       -    say(chaninpath, "/names %s\n" % (channel))
       -
       -    serveroutlines = readin_file("%s/out" % (serverpath))
       -    namesstring = " 353 %s = %s :" % (ircuser, channel)
       -    users = []
       -    for line in serveroutlines[::-1]:
       -        if namesstring in line:
       -            for user in line.strip().split(namesstring)[1].split(" "):
       -                if user.startswith("@"):
       -                    user = user[1:]
       -                if user not in users:
       -                    users.append(user)
       +
       +    def get_channel_users():
       +        say(chaninpath, "/names %s\n" % (channel))
       +        serveroutlines = readin_file("%s/out" % (serverpath))
       +        namesstring = " 353 %s = %s :" % (ircuser, channel)
       +        users = []
       +        for line in serveroutlines[::-1]:
       +            if namesstring in line:
       +                for user in line.strip().split(namesstring)[1].split(" "):
       +                    if user.startswith("@"):
       +                        user = user[1:]
       +                    if user not in users:
       +                        users.append(user)
       +        return users
       +
       +    users = get_channel_users()
            if len(users) == 0:
                return 1
        
       @@ -114,6 +118,12 @@ def main(args):
            for hacker in hackers.keys():
                hackers[hacker][0] = int(hackers[hacker][0])
                hackers[hacker][5] = int(hackers[hacker][5])
       +        # All are offline by default.
       +        try:
       +            hackers[hacker][6] = 0
       +        except IndexError:
       +            hackers[hacker].append(0)
       +
            admins = readin_dictfile("%s/admins.txt" % (basepath))
        
            def random_hacker():
       @@ -130,6 +140,8 @@ def main(args):
                hacker.append(random.choice(list(weapons.keys())))
                # Level
                hacker.append(0)
       +        # Online
       +        hacker.append(1)
                return hacker
        
            def calamity(hackers, hacker):
       @@ -245,10 +257,19 @@ def main(args):
                hackerinfo += "%s has idled for %d seconds and has reached level %d." % (hacker, hackers[hacker][0], hackers[hacker][5])
                say(chaninpath, hackerinfo)
        
       -    for user in users:
       -        # Build a hacker for newly appeared irc user
       -        if user not in list(hackers.keys()) and user != ircuser:
       -            hackers[user] = random_hacker()
       +    def update_hackers_from_users(hackers, users):
       +        for user in users:
       +            # Build a hacker for newly appeared irc user
       +            if user not in list(hackers.keys()) and user != ircuser:
       +                hackers[user] = random_hacker()
       +            elif user in list(hackers.keys()):
       +                hackers[user][6] = 1
       +
       +    def sync_hackers_with_channel(hackers):
       +        users = get_channel_users()
       +        update_hackers_from_users(hackers, users)
       +
       +    update_hackers_from_users(hackers, users)
        
            inotifywm = pyinotify.WatchManager()
            inotifywm.add_watch("%s/out" % (chanpath), pyinotify.IN_MODIFY)
       @@ -270,6 +291,10 @@ def main(args):
                    break
                if rfds == [] and wfds == [] and sfds == []:
                    for hacker in hackers.keys():
       +                # Is offline.
       +                if hackers[hacker][6] == 0:
       +                    continue
       +
                        hackers[hacker][0] += 5
                        # Level up every 5 days.
                        newlevel = int(hackers[hacker][0]/(86400*5))
       @@ -357,17 +382,35 @@ def main(args):
                            if hacker not in hackers:
                                hackers[hacker] = random_hacker()
                                hacker_info(hackers, hacker)
       +                    else:
       +                        hackers[hacker][6] = 1
       +                    sync_hackers_with_channel(hackers)
                        elif "has left " in text:
                            penalty = "part"
                            hacker = hacker.split("(", 1)[0]
       +                    if hacker in hackers:
       +                        hackers[hacker][6] = 0
       +                    sync_hackers_with_channel(hackers)
                        elif "has quit " in text:
                            penalty = "quit"
                            hacker = hacker.split("(", 1)[0]
       +                    if hacker in hackers:
       +                        hackers[hacker][6] = 0
       +                    sync_hackers_with_channel(hackers)
                        elif "changed nick to " in text:
       +                    # TODO: Fix. It is now in channelmaster.
       +                    # Instead we sync on part and quit.
                            penalty = "nick"
       +                    newhacker = text.split("to ", 1)[1].split("\"")[1]
       +                    if newhacker not in hackers:
       +                        hackers[newhacker] = random_hacker()
       +                        hacker_info(hackers, newhacker)
                        elif "kicked " in text:
                            penalty = "kick"
                            hacker = text.split(" ", 3)[2]
       +                    if hacker in hackers:
       +                        hackers[hacker][6] = 0
       +                    sync_hackers_with_channel(hackers)
        
                    if hacker == ircuser:
                        continue