Results 1 to 8 of 8
  1. #1

    Insane Limits V0.9: Move AFK players

    Quote Originally Posted by IAF SDS View Post
    Hi Papa.

    Here's my request for the test limit re AFKs to work as follows for Conquest, Domination, and ChainLink:

    The limit will detect that one team is ahead of the other AND that the losing team has AFK players (time of inactivity configurable if possible). It will then admin move one AFK player to the winning team for every 100 tickets (configurable) the winning team is ahead. For example, by the time the winning team was ahead by 200 tickets, it would have moved two AFK players to the winning team (one afk for every 100 tickets ahead).

    As for messages, only plugin tab console messages are necessary in the color ^5 Cornflower Blue please and without any messages shown to the players. Perhaps something like this in the plugin's console:

    Moved AFK player NameHere from US (800 tickets) to CN (900 tickets)

    Thanks Papa.
    It's too difficult to move only one AFK per 100 tickets difference. There are too many complications, like, if there are no AFK when the ticket difference is 100 tickets, and only 1 when tickets are 200 apart, what should happen?

    The best I can do is when there are 1 or more players on the afk list, I can move 1 player when the tickets are AFKTicketDifference or more apart, defaulted to 100. You can change the value of AFKTicketDifference . The check is made OnIntervalServer, so you also control how often everything is checked, default is 60 seconds. So, say there are 3 AFK players and tickets just turned 600 v 500. One AFK is moved. On the next interval, 60 seconds later, the gap has widened to 550 v 400. There are 2 AFK on the list, so now one more is moved. And so on until either the AFK list is empty or the ticket gap falls below AFKTicketDifference.

    AFK is guessed by noticing that a player has the same Score in round for MaxMinutesAFK, defaulted to 5. Note that the score may be more than zero, but if it doesn't change for the specified number of minutes, the player is considered AFK. Make sure your interval is set to less than half of MaxMinutesAFK, for example, if MaxMinutesAFK is 5 minutes, set the interval to no greater than 150 seconds (2.5 minutes). Also, set the interval no lower than 60 seconds, in order to allow enough time to update scores.

    Create a new limit to evaluate OnIntervalServer, call it "Move AFK", set the interval to 60 seconds or up to half of MaxMinutesAFK in seconds.

    Set first_check to this Code:

    Code:
    /* VERSION 0.9/R1 */
    double MaxMinutesAFK = 5.0; // CHANGE
    double AFKTicketDifference = 100; // CHANGE
    
    String key = "GuessingAFK_";
    
    int level = 2;
    
    try {
        level = Convert.ToInt32(plugin.getPluginVarValue("debug_level"));
    } catch (Exception e) {}
    
    // Debugging
    if (level >= 5) {
        plugin.ConsoleWrite("server.TimeRound = " + server.TimeRound.ToString("F1"));
    }
    
    
    List<PlayerInfoInterface> all = new List<PlayerInfoInterface>();
    all.AddRange(team1.players);
    all.AddRange(team2.players);
    List<PlayerInfoInterface> afk = new List<PlayerInfoInterface>();
    
    foreach (PlayerInfoInterface p in all) {
        double lastScore = 0;
        String k = key + p.Name;
        if (plugin.RoundData.issetDouble(k)) {
            lastScore = plugin.RoundData.getDouble(k);
        } else {
            plugin.RoundData.setDouble(k, lastScore);
            server.RoundData.setDouble(k, server.TimeRound);
            continue;
        }
    
        // If score hasn't changed, guess AFK
        if (lastScore == p.ScoreRound) {
            double afkSeconds = 0;
            double lastSeconds = server.TimeRound; // Remember server.TimeRound when player when AFK
            if (server.RoundData.issetDouble(k)) {
                lastSeconds = server.RoundData.getDouble(k);
            } else {
                server.RoundData.setDouble(k, server.TimeRound);
            }
            if (level >= 5) {
                plugin.ConsoleWrite("For " + p.FullName + " = " + lastSeconds.ToString("F1"));
            }
    
            afkSeconds = server.TimeRound - lastSeconds;
    
            if (afkSeconds < 0) {
                server.RoundData.setDouble(k, server.TimeRound);
                continue;
            }
    
            if (afkSeconds >= (MaxMinutesAFK * 60)) {
                afk.Add(p); // Add to AFK list
                if (level >= 4) {
                    plugin.ConsoleWrite("Adding " + p.FullName + " to AFK list after " + (afkSeconds/60).ToString("F1") + " minutes with score = " + p.ScoreRound.ToString("F0"));
                }
            } else {
                // logging
                if (level >= 4) {
                    plugin.ConsoleWrite("^9...Suspected AFK " + p.FullName + " for only " + (afkSeconds/60).ToString("F1") + " minutes with score = " + p.ScoreRound.ToString("F0"));
                }
            }
        } else {
            // Score changed, reset lastScore and lastSeconds
            plugin.RoundData.setDouble(k, p.ScoreRound);
            server.RoundData.setDouble(k, server.TimeRound);
        }
    }
    
    // Logging
    if (afk.Count > 0 && level >= 4) {
        String l = null;
        foreach (PlayerInfoInterface a in afk) {
            if (a.TeamId != 1)
                continue;
            if (l == null) {
                l = "Guessing AFK T1: " + a.FullName;
            } else {
                l = l + ", " + a.FullName;
            }
        }
        if (l != null)
            plugin.ConsoleWrite(l);
        l = null;
        foreach (PlayerInfoInterface a in afk) {
            if (a.TeamId != 2)
                continue;
            if (l == null) {
                l = "Guessing AFK T2: " + a.FullName;
            } else {
                l = l + ", " + a.FullName;
            }
        }
        if (l != null)
            plugin.ConsoleWrite(l);
    }
    
    if (afk.Count == 0)
        return false; // No AFK
    
    // Check if the ticket gap is big enough
    double t1 = server.RemainTickets(1);
    double t2 = server.RemainTickets(2);
    double gap = Math.Abs(t1 - t2);
    if (gap < AFKTicketDifference)
        return false;
    
    // Logging
    if (level >= 4) {
        plugin.ConsoleWrite("Ticket gap " + gap.ToString("F0") + " is greater than " + AFKTicketDifference.ToString("F0"));
    }
    
    // Which team?
    int winner = 0;
    int loser = 0;
    double winRem = 0;
    double loseRem = 0;
    if (server.Gamemode.Contains("TeamDeath")) { // count up, lower remaining tickets is winning
        if (t1 < t2) {
            winner = 1;
            loser = 2;
            winRem = server.Tickets(1);
            loseRem = server.Tickets(2);
        } else {
            winner = 2;
            loser = 1;
            winRem = server.Tickets(2);
            loseRem = server.Tickets(1);
        }
    } else { // count down, higher remaining tickets is winning
        if (t1 > t2) {
            winner = 1;
            loser = 2;
            winRem = t1;
            loseRem = t2;
        } else {
            winner = 2;
            loser = 1;
            winRem = t2;
            loseRem = t1;
        }
    }
    int winFaction = server.GetFaction(winner);
    int loseFaction = server.GetFaction(loser);
    String[] facts = new String[]{"US","RU","CN"};
    
    PlayerInfoInterface stooge = null;
    
    // Find an AFK on the losing team
    foreach (PlayerInfoInterface a in afk) {
        if (a.TeamId == loser) {
            stooge = a;
            break;
        }
    }
    
    // Can't find an AFK on the losing team
    if (stooge == null) {
        // Logging
        if (level >= 4) {
            plugin.ConsoleWrite("No AFK to move from losing team " + facts[loseFaction] + " to winning team " + facts[winFaction] + " at this time");
        }
        return false;
    }
    
    // found one!
    server.RoundData.setDouble(key + stooge.Name, server.TimeRound);
    plugin.MovePlayer(stooge.Name, winner, 0, true);
    plugin.ConsoleWrite("^5Moved AFK player " + stooge.FullName + " from " + facts[loseFaction] + " (" + loseRem.ToString("F0") + " tickets) to " + facts[winFaction] + " (" + winRem.ToString("F0") + " tickets)");
    
    
    return false;
    NOTE

    To make this work for BF3, find these lines of code:

    Code:
    int winFaction = server.GetFaction(winner);
    int loseFaction = server.GetFaction(loser);
    And change them to this:

    Code:
    int winFaction = winner - 1;
    int loseFaction = loser - 1;
    Last edited by PapaCharlie9; 13-09-2014 at 18:19.
    Don't send me private messages (PMs) unless you really need privacy, like your game server password. If you just have a question or need help, post in one of the threads. It's extra work for me to answer questions and give help in private messages and no one else gets the benefit of the answer.

  2. #2
    Thanks Papa.

    Regarding setting the Unswitcher to LatePhaseOnly for biggest and winning to avoid having the moves of the AFK look like a player switching to the winning team which would normally get unswitched, could we avoid this issue by having the moves look like admin moves since MB respects admin moves and won't unswitch them?

    It's problematic to let them switch to the winning team since it could undue any benefit from the limit when strong players freely switch to the winning team.
    Last edited by IAF SDS; 17-08-2014 at 04:06.

  3. #3
    Quote Originally Posted by IAF SDS View Post
    Thanks Papa.

    Regarding setting the Unswitcher to LatePhaseOnly for biggest and winning to avoid having the moves of the AFK look like a player switching to the winning team which would normally get unswitched, could we avoid this issue by having the moves look like admin moves since MB respects admin moves and won't unswitch them?
    They ARE admin moves and MB is supposed to detect and ignore those, but it doesn't always work. You can try it without reducing the Unswitcher settings, but some of the AFK moves won't work. Maybe that's not so bad, since they are AFK, they won't complain about being spammed and ping-ponged back and forth between teams.

    There's either something wrong with MB that I haven't been able to figure out, or the game server is not as deterministic as one would hope. I already know for a fact that the game server sometimes sends the command to move a player AFTER the player changed teams event, which makes things very difficult. When a player team change event comes in, I have no idea if it is the player moving himself or if it was an admin move. I have to wait and see if an admin move command comes next, and since there are all kinds of other crap that can come between the event and the command, like listPlayers, serverInfo, onKill, etc., it gets quite complicated. In other words, don't expect MB to be fixed any time soon, if ever.
    Don't send me private messages (PMs) unless you really need privacy, like your game server password. If you just have a question or need help, post in one of the threads. It's extra work for me to answer questions and give help in private messages and no one else gets the benefit of the answer.

  4. #4
    You know, I've seen MB show in the plugin tab's console that it moved players to balance team numbers, but I noticed those moves didn't really happen. I've seen this happen a couple times and figured it was a fluke. It sounds like it is related to what you described above.

    I'll try it out and let you know how it works. Thanks again Papa.

  5. #5
    Senior Member
    Join Date
    Nov 2010
    Location
    United Kingdom
    Posts
    391
    I skimmed across this post and it kinda sounds like the issue I was having with the seeder balancer, what I kinda put my finger on what the "squad up" feature dice put in when you join in your friends. The conflict started to happen where it would try to balance the seeders who were afk but as it was splitting up the team (they joined on there friend instead of the normal way) the game either didn't switch them or just put them back confusing any plugin I was running to make the teams even. Not sure if you guys thought of it or if its now turned off but I just ended up stopping to try and balancer the afk people due to it causing big issues with team balance.

  6. #6
    Hi Papa.

    Im testing the limit above in BF3 but it doesn't appear to be working (I also don't see any of the ^5 Cornflower Blue messages the way I do in BF4). It works in BF4 with my added expression, but no luck in BF3.

    When you have a moment, I would appreciate your help with a version for BF3 please.

    Thanks.
    Last edited by IAF SDS; 13-09-2014 at 20:59.

  7. #7
    See update to post #1 for BF3 adjustments.
    Don't send me private messages (PMs) unless you really need privacy, like your game server password. If you just have a question or need help, post in one of the threads. It's extra work for me to answer questions and give help in private messages and no one else gets the benefit of the answer.

  8. #8
    Thanks Papa.

 

 

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •