<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://bf2tech.uturista.pt/index.php?action=history&amp;feed=atom&amp;title=Scripts%3ATK_punish_announcer</id>
	<title>Scripts:TK punish announcer - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://bf2tech.uturista.pt/index.php?action=history&amp;feed=atom&amp;title=Scripts%3ATK_punish_announcer"/>
	<link rel="alternate" type="text/html" href="https://bf2tech.uturista.pt/index.php?title=Scripts:TK_punish_announcer&amp;action=history"/>
	<updated>2026-08-06T01:15:13Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.40.1</generator>
	<entry>
		<id>https://bf2tech.uturista.pt/index.php?title=Scripts:TK_punish_announcer&amp;diff=135&amp;oldid=prev</id>
		<title>Pireax: Created page with &quot;__TOC__ = Introduction =  One of the major frustrations in BF2 is the often observed abuse of the PTK function. Since it is so easily available, many people punish others for...&quot;</title>
		<link rel="alternate" type="text/html" href="https://bf2tech.uturista.pt/index.php?title=Scripts:TK_punish_announcer&amp;diff=135&amp;oldid=prev"/>
		<updated>2018-06-22T15:38:55Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;__TOC__ = Introduction =  One of the major frustrations in BF2 is the often observed abuse of the PTK function. Since it is so easily available, many people punish others for...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;__TOC__&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
One of the major frustrations in BF2 is the often observed abuse of the PTK function. Since it is so easily available, many people punish others for TKs even when it&amp;#039;s their own fault. At [http://www.battlefield.no/ Battlefield.no] we do not accept this behaviour, but it can be very hard for admins to take notice of people doing this. We have therefore made a modification to the tk_punish.py-script which is included with BF2.&lt;br /&gt;
&lt;br /&gt;
= Features =&lt;br /&gt;
&lt;br /&gt;
For each player a running tally of the number of forgives and punishes is kept. Whenever someone punishes a TK, a global announcement is made on the server indicating how many punishes and forgives this person has made. This makes it easy to spot people abusing the PTK-system.&lt;br /&gt;
&lt;br /&gt;
This script is a drop-in replacement for the original tk_punish.py which comes with BF2. It is based on the script from the 1.12 release (build 1.1.2554-356). No functionality of the original script has been removed, so this script should be allowed on ranked servers.&lt;br /&gt;
&lt;br /&gt;
= Getting started =&lt;br /&gt;
&lt;br /&gt;
Copy the script from below and replace your current tk_punish.py which you can find under bf2/admin/standard_admin. Remember to make a backup of the original script first!&lt;br /&gt;
&lt;br /&gt;
= The code =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The code&lt;br /&gt;
&lt;br /&gt;
# tk punish system&lt;br /&gt;
&lt;br /&gt;
import bf2&lt;br /&gt;
import host&lt;br /&gt;
from bf2 import g_debug&lt;br /&gt;
&lt;br /&gt;
TK_PUNISH_TIME = 20&lt;br /&gt;
TK_PUNISH_COMMANDID = 100&lt;br /&gt;
TK_FORGIVE_COMMANDID = 101&lt;br /&gt;
&lt;br /&gt;
hasPendingTks = {}&lt;br /&gt;
updateTimer = None&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class TkData:&lt;br /&gt;
        def __init__(self):&lt;br /&gt;
                self.punished = 0&lt;br /&gt;
                self.pending = []&lt;br /&gt;
                self.lastTKedBy = None&lt;br /&gt;
                self.givenPunish = 0 # bf.no modification&lt;br /&gt;
                self.givenForgive = 0 # bf.no modification&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def init():&lt;br /&gt;
        if g_debug: print &amp;quot;initializing tk-punish script&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        host.registerHandler(&amp;#039;PlayerConnect&amp;#039;, onPlayerConnect, 1)&lt;br /&gt;
        host.registerHandler(&amp;#039;PlayerKilled&amp;#039;, onPlayerKilled)&lt;br /&gt;
        host.registerHandler(&amp;#039;ClientCommand&amp;#039;, onClientCommand)&lt;br /&gt;
&lt;br /&gt;
        # Connect already connected players if reinitializing&lt;br /&gt;
        for p in bf2.playerManager.getPlayers():&lt;br /&gt;
                onPlayerConnect(p)&lt;br /&gt;
       &lt;br /&gt;
        checkEnable()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def checkEnable():&lt;br /&gt;
        global updateTimer&lt;br /&gt;
       &lt;br /&gt;
        if not bf2.serverSettings.getTKPunishEnabled():&lt;br /&gt;
                if updateTimer:&lt;br /&gt;
                        updateTimer.destroy()&lt;br /&gt;
                        updateTimer = None&lt;br /&gt;
                return False&lt;br /&gt;
        else:&lt;br /&gt;
                if not updateTimer:&lt;br /&gt;
                        #if g_debug: print &amp;quot;Started timer&amp;quot;&lt;br /&gt;
                        updateTimer = bf2.Timer(onUpdate, 10, 1)&lt;br /&gt;
                        updateTimer.setRecurring(10)&lt;br /&gt;
                       &lt;br /&gt;
                return True&lt;br /&gt;
       &lt;br /&gt;
&lt;br /&gt;
def onUpdate(data):&lt;br /&gt;
        if not checkEnable(): return&lt;br /&gt;
        global hasPendingTks&lt;br /&gt;
&lt;br /&gt;
        #if len(hasPendingTks) &amp;gt; 0:&lt;br /&gt;
        #       if g_debug: print &amp;quot;update: Has pending tks!&amp;quot;&lt;br /&gt;
        #else:&lt;br /&gt;
        #       if g_debug: print &amp;quot;update:No pending tks.&amp;quot;&lt;br /&gt;
               &lt;br /&gt;
&lt;br /&gt;
        currentTime = host.timer_getWallTime()&lt;br /&gt;
&lt;br /&gt;
        newPending = {}&lt;br /&gt;
        for attacker in hasPendingTks.iterkeys():&lt;br /&gt;
                newList = []&lt;br /&gt;
                #if g_debug: print &amp;quot;attacker pending list:&amp;quot;, len(attacker.tkData.pending)&lt;br /&gt;
                for tk in attacker.tkData.pending:&lt;br /&gt;
                        tkDate = tk[0]&lt;br /&gt;
                        tkVictim = tk[1]&lt;br /&gt;
                        #if g_debug: print &amp;quot;check %d %s&amp;quot; % (tkDate, tkVictim.getName())&lt;br /&gt;
&lt;br /&gt;
                        # if there is a pending TK with time expired&lt;br /&gt;
                        if tkDate + TK_PUNISH_TIME &amp;lt; currentTime:&lt;br /&gt;
                                if bf2.serverSettings.getTKPunishByDefault():&lt;br /&gt;
                                        attacker.tkData.punished += 1&lt;br /&gt;
                                        checkPunishLimit(attacker)&lt;br /&gt;
                                        # bf.no addons:&lt;br /&gt;
                                        tkVictim.tkData.givenPunish += 1&lt;br /&gt;
                                        result = host.rcon_invoke(&amp;#039;game.sayAll &amp;quot;TKPUNISH: %s punishes %s for teamkill (%s has %d punishes and %d forgives)&amp;quot;&amp;#039; % (tkVictim.getName(), attacker.getName(), tkVictim.getName(), tkVictim.tkData.givenPunish, tkVictim.tkData.givenForgive))&lt;br /&gt;
                                        # *************&lt;br /&gt;
                                #       if g_debug: print &amp;quot;Default punished &amp;quot;, attacker.getName()&lt;br /&gt;
                                else:&lt;br /&gt;
                                        # bf.no addons:&lt;br /&gt;
                                        tkVictim.tkData.givenForgive += 1&lt;br /&gt;
                                #       if g_debug: print &amp;quot;Timeouted pending tk for &amp;quot;, attacker.getName()&lt;br /&gt;
                                        # pass&lt;br /&gt;
&lt;br /&gt;
                                # remove player from global list, if it was the last tk&lt;br /&gt;
                                if len(attacker.tkData.pending) == 1:&lt;br /&gt;
                                        pass&lt;br /&gt;
                                else:&lt;br /&gt;
                                        newPending[attacker] = 1&lt;br /&gt;
                       &lt;br /&gt;
                        else:&lt;br /&gt;
                                newList += [tk]&lt;br /&gt;
                                newPending[attacker] = 1&lt;br /&gt;
               &lt;br /&gt;
                attacker.tkData.pending = newList&lt;br /&gt;
&lt;br /&gt;
        hasPendingTks = newPending&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def checkPunishLimit(player):&lt;br /&gt;
        #if g_debug: print &amp;quot;player %s has %d punishes&amp;quot; % (player.getName(), player.tkData.punished)&lt;br /&gt;
&lt;br /&gt;
        if player.tkData.punished &amp;gt;= bf2.serverSettings.getTKNumPunishToKick():&lt;br /&gt;
                if g_debug: print &amp;quot;%s reached punish limit&amp;quot; % player.getName()&lt;br /&gt;
                if g_debug: print &amp;quot;Banning player!&amp;quot;&lt;br /&gt;
                result = host.rcon_invoke(&amp;quot;admin.banPlayerKey &amp;quot; + str(player.index) + &amp;quot; Round&amp;quot;)&lt;br /&gt;
               &lt;br /&gt;
       &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# event actions&lt;br /&gt;
&lt;br /&gt;
def onPlayerConnect(player):&lt;br /&gt;
        player.tkData = TkData()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def onClientCommand(command, issuer, args):&lt;br /&gt;
        if not checkEnable(): return&lt;br /&gt;
       &lt;br /&gt;
        #if g_debug: print &amp;quot;received client command&amp;quot;&lt;br /&gt;
        if command == TK_PUNISH_COMMANDID:&lt;br /&gt;
                executePunishAction(issuer, True)&lt;br /&gt;
        elif command == TK_FORGIVE_COMMANDID:&lt;br /&gt;
                executePunishAction(issuer, False)&lt;br /&gt;
&lt;br /&gt;
               &lt;br /&gt;
&lt;br /&gt;
def onPlayerKilled(victim, attacker, weapon, assists, object):&lt;br /&gt;
&lt;br /&gt;
        if not checkEnable(): return&lt;br /&gt;
&lt;br /&gt;
        if not victim or not attacker or victim == attacker or victim.getTeam() != attacker.getTeam(): return&lt;br /&gt;
       &lt;br /&gt;
        # verify that TK was really given&lt;br /&gt;
&lt;br /&gt;
        # no teamkills from wrecks&lt;br /&gt;
        if object != None and object.getIsWreck():&lt;br /&gt;
                return&lt;br /&gt;
               &lt;br /&gt;
        # no teamkills from artillery&lt;br /&gt;
        if weapon:&lt;br /&gt;
                attackerVehicle = bf2.objectManager.getRootParent(weapon)&lt;br /&gt;
                if attackerVehicle.isPlayerControlObject and attackerVehicle.getIsRemoteControlled():&lt;br /&gt;
                        return&lt;br /&gt;
               &lt;br /&gt;
        # ok, we have a teamkill&lt;br /&gt;
        currentTime = host.timer_getWallTime()&lt;br /&gt;
        attacker.tkData.pending += [(currentTime, victim)]&lt;br /&gt;
        hasPendingTks[attacker] = 1&lt;br /&gt;
               &lt;br /&gt;
        victim.tkData.lastTKedBy = attacker # can only punish / forgive the last TK&amp;#039;er&lt;br /&gt;
       &lt;br /&gt;
        bf2.gameLogic.sendClientCommand(victim.index, 100, (2, victim.index, attacker.index, TK_PUNISH_TIME))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def executePunishAction(victim, punish):&lt;br /&gt;
        if not checkEnable() or not victim or not victim.isValid(): return&lt;br /&gt;
        attacker = victim.tkData.lastTKedBy&lt;br /&gt;
        if attacker == None or not attacker.isValid(): return&lt;br /&gt;
&lt;br /&gt;
        global hasPendingTks&lt;br /&gt;
&lt;br /&gt;
        if punish:&lt;br /&gt;
                if g_debug: print &amp;quot;%s tkPunished %s&amp;quot; % (victim.getName(), attacker.getName())&lt;br /&gt;
        else:&lt;br /&gt;
                if g_debug: print &amp;quot;%s tkForgive %s&amp;quot; % (victim.getName(), attacker.getName())&lt;br /&gt;
&lt;br /&gt;
        currentTime = host.timer_getWallTime()&lt;br /&gt;
       &lt;br /&gt;
        newList = []&lt;br /&gt;
        for tk in attacker.tkData.pending:&lt;br /&gt;
                tkDate = tk[0]&lt;br /&gt;
                tkVictim = tk[1]&lt;br /&gt;
               &lt;br /&gt;
                # if the attacker had a pending tk, and time has not run out&lt;br /&gt;
                if tkVictim == victim and tkDate + TK_PUNISH_TIME &amp;gt; currentTime:&lt;br /&gt;
                        if punish:&lt;br /&gt;
                                attacker.tkData.punished += 1&lt;br /&gt;
                                bf2.gameLogic.sendClientCommand(-1, 100, (0, victim.index, attacker.index)) # 100 = tkpunish event, 0 = punish&lt;br /&gt;
                                if g_debug: print &amp;quot;%s punished %s, now has %d punishes&amp;quot; % (victim.getName(), attacker.getName(), attacker.tkData.punished)&lt;br /&gt;
                                # bf.no addons:&lt;br /&gt;
                                victim.tkData.givenPunish += 1&lt;br /&gt;
                                result = host.rcon_invoke(&amp;#039;game.sayAll &amp;quot;TKPUNISH: %s punishes %s for teamkill (%s has %d punishes and %d forgives)&amp;quot;&amp;#039; % (victim.getName(), attacker.getName(), victim.getName(), victim.tkData.givenPunish, victim.tkData.givenForgive))&lt;br /&gt;
                                # *************&lt;br /&gt;
                        else:&lt;br /&gt;
                                bf2.gameLogic.sendClientCommand(-1, 100, (1, victim.index, attacker.index)) # 100 = tkpunish event, 1 = forgive&lt;br /&gt;
                                if g_debug: print &amp;quot;%s forgave %s&amp;quot; % (victim.getName(), attacker.getName())&lt;br /&gt;
                                # bf.no addons:&lt;br /&gt;
                                victim.tkData.givenForgive += 1&lt;br /&gt;
                else:&lt;br /&gt;
                        newList += [tk]&lt;br /&gt;
                       &lt;br /&gt;
        attacker.tkData.pending = newList&lt;br /&gt;
       &lt;br /&gt;
        if len(attacker.tkData.pending) == 0:&lt;br /&gt;
                del hasPendingTks[attacker]&lt;br /&gt;
       &lt;br /&gt;
        checkPunishLimit(attacker)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pireax</name></author>
	</entry>
</feed>