Jump to content
Official BF Editor Forums
DND

Antibaserape

Recommended Posts

Hi all,

I'm new to all this scripting and having trouble getting my head around trying to chance this script :huh:

I'm looking for some help to change this script from giving negative score to the attacker to kick/ban attacker for the round.

Any Help would be appreciated.

# ------------------------------------------------------------------------
# Module: AntiBaseRape.py
# Author: SHAnders
# Port to bf2cc/mm: graag42
#
# Version 1.11 
#
# Changes:
#   v1.1 -> 1.11
#   Fixed the timer to only be started once
#   v1.0 -> 1.1
#   Implemted a baseRapeWarning attribute on players to count safe base kills
#   Implemted allowed amount of safe base kills (3) 
#      up to this amount player only loses kill points + 1 score pr baseRapeWarning
#      over this amount player is allso killed
#   Implemtes a timer for removing 1 baseRapeWarning every 2 minutes
#
# Description:
#   Server side only admin script
#
#   This script will punish players who kill enemy within the area of a safe base
#   
# Requirements:
#   None.
#
# Installation as Admin script:
#   1: Save this script as 'AntiBaseRape.py' in your <bf2>/admin/standard_admin directory.
#   2: Add the lines 'import AntiBaseRape' and 'AntiBaseRape.init()' to the file
#      '<bf2>/admin/standard_admin/__init__.py'.
#
# TODO:
#   Since not all maps are alike, the requirements for base rape protiction
#   should be able to be altered individualy for each control point.
#
# Thanks to:
#   Battlefield.no for inspiration from their pingkick.py script
#
# ------------------------------------------------------------------------

import host
import bf2
import math
import mm_utils
from bf2.stats.constants import *
from bf2 import g_debug

# Set the version of your module here
__version__ = 1.11

# Set the required module versions here
__required_modules__ = {
'modmanager': 1.0
}

# Does this module support reload ( are all its reference closed on shutdown? )
__supports_reload__ = True

# Set the description of your module here
__description__ = "AntiBaseRape v%s" % __version__

# ------------------------------------------------------------------------
# Constants
# ------------------------------------------------------------------------

DEFAULT_SAFEBASE_RADIUS = 50 # Default safe area radius (normal commandpoint radius = 10)
ALLOWED_SAFEBASEKILLS = 3
SAFEBASEKILL_TIMER_INTERVAL = 120 # Intervals between removing a point from players.baseRapeWarning

# ------------------------------------------------------------------------
# Variables
# ------------------------------------------------------------------------

WarnReduceTimer = None # Timer that reduces the warnings at intervals

# ------------------------------------------------------------------------
# Init
# ------------------------------------------------------------------------

class BaseRape( object ) : 

  def __init__( self, modManager ):
     # ModManager reference
     self.mm = modManager

     # Internal shutdown state
     self.__state = 0

  def init( self ):
     if g_debug: print "AntiBaseRape init"
     if 0 == self.__state:
        host.registerHandler('PlayerConnect', self.onPlayerConnect, 1)   
        host.registerHandler('PlayerKilled', self.onPlayerKilled)

        # Update to the running state
        self.__state = 1

        # Start the timer that reduces warnings on the SAFEBASEKILL_TIMER_INTERVAL
        WarnReduceTimer = bf2.Timer(self.onSafeBaseKillTimer, SAFEBASEKILL_TIMER_INTERVAL, 1)
        WarnReduceTimer.setRecurring(SAFEBASEKILL_TIMER_INTERVAL)

        # Connect already connected players if reinitializing
        for p in bf2.playerManager.getPlayers():
           self.onPlayerConnect(p)
  # ------------------------------------------------------------------------


  # ------------------------------------------------------------------------
  #  onPlayerConnect
  # ------------------------------------------------------------------------
  def onPlayerConnect(self, player):
     self.resetPlayer(player)
  # ------------------------------------------------------------------------


  # ------------------------------------------------------------------------
  # onPlayerKilled
  # ------------------------------------------------------------------------
  def onPlayerKilled(self, victim, attacker, weapon, assists, object):
     # killed by self
     if attacker == victim:
        pass

     # killed by enemy
     elif attacker != None and attacker.getTeam() != victim.getTeam():
        self.checkForSafeBase(attacker, victim)
  # ------------------------------------------------------------------------


  def shutdown( self ):
     """Shutdown and stop processing."""

     # Unregister game handlers and do any other
     # other actions to ensure your module no longer affects
     # the game in anyway
     if WarnReduceTimer:
       WarnReduceTimer.destroy()
       WarnReduceTimer = None

     # Flag as shutdown as there is currently way to:
     # host.unregisterHandler
     self.__state = 2

  # ------------------------------------------------------------------------
  # Reset the number of warnings
  # ------------------------------------------------------------------------
  def resetPlayer(self, player):
     player.baseRapeWarning = 0
  # ------------------------------------------------------------------------


  # ------------------------------------------------------------------------
  # Check if victim was killed within safebase area
  # ------------------------------------------------------------------------
  def checkForSafeBase(self, attacker, victim):
     victimVehicle = victim.getVehicle()
     controlPoints = bf2.objectManager.getObjectsOfType('dice.hfe.world.ObjectTemplate.ControlPoint')
     for cp in controlPoints:
        if cp.cp_getParam('unableToChangeTeam') != 0 and cp.cp_getParam('team') != attacker.getTeam():
           distanceTo = self.getVectorDistance(victimVehicle.getPosition(), cp.getPosition())
           if DEFAULT_SAFEBASE_RADIUS > float(distanceTo):
              self.justify(attacker, victim, cp, distanceTo)
  # ------------------------------------------------------------------------


  # ------------------------------------------------------------------------
  # Punish attacker, give victim life back and inform all
  # ------------------------------------------------------------------------
  def justify(self, attacker, victim, controlPoint, distanceTo):
     victim.score.deaths += -1
     attacker.score.kills += -1
     attacker.score.score += -2 - attacker.baseRapeWarning
     attacker.baseRapeWarning += 1
     self.sendWarning(attacker, controlPoint, distanceTo)
     if attacker.baseRapeWarning > ALLOWED_SAFEBASEKILLS:
        attacker.score.TKs += 1
        if attacker.isAlive():
           vehicle = attacker.getVehicle()
           rootVehicle = getRootParent(vehicle)
           if getVehicleType(rootVehicle.templateName) == VEHICLE_TYPE_SOLDIER:
              rootVehicle.setDamage(0)
              # This should kill them !
           else:
              rootVehicle.setDamage(1) 
              # a vehicle will likely explode within 1 sec killing entire crew,
              # not so sure about base defenses though
  # ------------------------------------------------------------------------


  # ------------------------------------------------------------------------
  # Send Warning
  # ------------------------------------------------------------------------
  def sendWarning(self, player, controlPoint, distanceTo):
     mapName = bf2.gameLogic.getMapName()
     if player.baseRapeWarning > ALLOWED_SAFEBASEKILLS:
        mm_utils.msg_server(player.getName() + " is punished for repeated violating of the no kill rules within safe base area")
     else:
        mm_utils.msg_server(player.getName() + " has violated the no kill rules within safe base area " + str(player.baseRapeWarning) + " times now")
  # ------------------------------------------------------------------------


  # ------------------------------------------------------------------------
  # remove baseRapeWarnings over time
  # ------------------------------------------------------------------------
  def onSafeBaseKillTimer(self, data):
     for p in bf2.playerManager.getPlayers():
        if p.baseRapeWarning <= 0:
           p.baseRapeWarning = 0
        else:
           p.baseRapeWarning += -1
  # ------------------------------------------------------------------------


  # ------------------------------------------------------------------------
  # get distance between two positions
  # ------------------------------------------------------------------------
  def getVectorDistance(self, pos1, pos2):
     diffVec = [0.0, 0.0, 0.0]
     diffVec[0] = math.fabs(pos1[0] - pos2[0])
     diffVec[1] = math.fabs(pos1[1] - pos2[1])
     diffVec[2] = math.fabs(pos1[2] - pos2[2])

     return math.sqrt(diffVec[0] * diffVec[0] + diffVec[1] * diffVec[1] + diffVec[2] * diffVec[2])
  # ------------------------------------------------------------------------


# ------------------------------------------------------------------------
# ModManager Init
# ------------------------------------------------------------------------
def mm_load( modManager ):
"""Creates and returns your object."""
return BaseRape( modManager )

Share this post


Link to post
Share on other sites

POE2 mod has an anti baserape system... its a an area around the main base that opposing players cant enter... is that similar to what you mean?

Share this post


Link to post
Share on other sites

No not realy.

The AntiBaseRape.py script dose what I want. But I need to change how the attacker gets negative points if they kill in an uncap (safebase)

How it works now is if the Attacker kills someone in the uncap (safebase) they receive negative points off there score.

But what I'm trying to do is If the Attacker kills someone in the uncap they get kicked from the server

Share this post


Link to post
Share on other sites

# Thanks to:
#   Battlefield.no for inspiration from their pingkick.py script

That sounds interesting - if you could find that pingkick.py script you should be able to extract the kick function and put it into your punish routine. I'd probably add a counter so that a player gets a warning the first time and gets kicked on repetitions.

Share this post


Link to post
Share on other sites

Just looking up the pingkick one now...

I just got a email back from misiekbest he wrote the BF2Oldschool script. This is what he suggested

Anyway, the clue is to modify only 'justify' function.

It is run exactly after player will kill somebody from the opposite team near base cap.

If you want to kick just after kill, without any extra checking (for example if it was second or third kill) then this function (and code before) should look something like this (code needs sanity checking it is not formatted properly but im sure you will handle it )

What is a sanity checking ?

This is the code he sent me

KICK_REASON = "You have been kicked for baseraping!"

KICK_IN_MINUTES = 10

def justify(attacker, victim, controlPoint, distanceTo):

global KICK_REASON, KICK_IN_MINUTES

host.rcon_invoke("pb_sv_kick \""+str(attacker.getName())+"\"

"+str(KICK_IN_MINUTES)+" \""+str(KICK_REASON)+"\"")

This is the normal code for Punishing the baseraper

# ------------------------------------------------------------------------

# Punish attacker, give victim life back and inform all

# ------------------------------------------------------------------------

def justify(self, attacker, victim, distanceTo):

victim.score.deaths += -1

attacker.score.kills += -1

attacker.score.score += -10 - attacker.baseRapeWarning

attacker.baseRapeWarning += 1

self.sendWarning(attacker, distanceTo)

if attacker.baseRapeWarning > ALLOWED_SAFEBASEKILLS:

attacker.score.TKs += 1

attacker.score.score += -40 - attacker.baseRapeWarning

if attacker.isAlive():

vehicle = attacker.getVehicle()

rootVehicle = getRootParent(vehicle)

if getVehicleType(rootVehicle.templateName) == VEHICLE_TYPE_SOLDIER:

rootVehicle.setDamage(1)

# This should kill them !

else:

rootVehicle.setDamage(1)

# a vehicle will likely explode within 1 sec killing entire crew,

# not so sure about base defenses though

# ------------------------------------------------------------------------

Share this post


Link to post
Share on other sites

I think he means the indentation where python is very picky about :

KICK_REASON = "You have been kicked for baseraping!"
KICK_IN_MINUTES = 10

def justify(attacker, victim, controlPoint, distanceTo):
global KICK_REASON, KICK_IN_MINUTES
host.rcon_invoke("pb_sv_kick\""+str(attacker.getName())+"\""+str(KICK_IN_MINUTES)+"\""+str(KICK_REASON)+"\"")

He kicks the player through the admin 'pb_sv_kick' function by invoking it through the host.rc_invoke method, a common way to fire otherwise inaccessible functions from a python script. Compare with our sticky on top of the python forum.

Edited by mschoeldgen[Xww2]

Share this post


Link to post
Share on other sites

do I need the

KICK_REASON = "You have been kicked for baseraping!"

KICK_IN_MINUTES = 10

in the top of the script under "Constants" or can I add it anywere

I have read so many scripts now I'm totally lost :blink:

I will try that one you just posted fingers crossed

Share this post


Link to post
Share on other sites

Any variables declared with zero indentation (no tabs), are global, and can be accessed anywhere. ;)

Just make sure to include:

myVar = "hi"
def myFunction():
global myVar
myVar = "sup"

if you want to modify them inside a function (you can always read them though).

Edited by ScoutStrike

Share this post


Link to post
Share on other sites

I think he means the indentation where python is very picky about :

KICK_REASON = "You have been kicked for baseraping!"
KICK_IN_MINUTES = 10

def justify(attacker, victim, controlPoint, distanceTo):
global KICK_REASON, KICK_IN_MINUTES
host.rcon_invoke("pb_sv_kick\""+str(attacker.getName())+"\""+str(KICK_IN_MINUTES)+"\""+str(KICK_REASON)+"\"")

He kicks the player through the admin 'pb_sv_kick' function by invoking it through the host.rc_invoke method, a common way to fire otherwise inaccessible functions from a python script. Compare with our sticky on top of the python forum.

I have tryed it but could not get it to work :(

Share this post


Link to post
Share on other sites

Just an idea for a different approach without changing he script to much:

Wouldn't it be easier to use the script to give the attacker a large negative score (-500 for example) and then correctly set up the server to kick players with a certain negative score (below -50 for example)? This can be done very easily with the correct modmanager setup, the ban/kick last one round if set so. Seems like the solution you are looking for, without coding python.

Edited by Caliban55

Share this post


Link to post
Share on other sites

Yes thats how we had it before, but we are not aloud to run any script that interferes with the scoring system.

Ideally I'd like to get it to Warn on the first time and then kick on the second, But right now I'll be happy to get it to kick on the first time.

Share this post


Link to post
Share on other sites

# ------------------------------------------------------------------------
# Module: AntiBaseRape.py
# Author: SHAnders
# Port to bf2cc/mm: graag42
#
# Version 1.11 
#
# Changes:
#   v1.1 -> 1.11
#   Fixed the timer to only be started once
#   v1.0 -> 1.1
#   Implemted a baseRapeWarning attribute on players to count safe base kills
#   Implemted allowed amount of safe base kills (3) 
#	  up to this amount player only loses kill points + 1 score pr baseRapeWarning
#	  over this amount player is allso killed
#   Implemtes a timer for removing 1 baseRapeWarning every 2 minutes
#
# Description:
#   Server side only admin script
#
#   This script will punish players who kill enemy within the area of a safe base
#   
# Requirements:
#   None.
#
# Installation as Admin script:
#   1: Save this script as 'AntiBaseRape.py' in your <bf2>/admin/standard_admin directory.
#   2: Add the lines 'import AntiBaseRape' and 'AntiBaseRape.init()' to the file
#	  '<bf2>/admin/standard_admin/__init__.py'.
#
# TODO:
#   Since not all maps are alike, the requirements for base rape protiction
#   should be able to be altered individualy for each control point.
#
# Thanks to:
#   Battlefield.no for inspiration from their pingkick.py script
#
# ------------------------------------------------------------------------

import host
import bf2
import math
import mm_utils
from bf2.stats.constants import *
from bf2 import g_debug

# Set the version of your module here
__version__ = 1.11

# Set the required module versions here
__required_modules__ = {
'modmanager': 1.0
}

# Does this module support reload ( are all its reference closed on shutdown? )
__supports_reload__ = True

# Set the description of your module here
__description__ = "AntiBaseRape v%s" % __version__

# ------------------------------------------------------------------------
# Constants
# ------------------------------------------------------------------------

KICK_IN_MINUTES = 1
KICK_REASON = "Base Rape"

DEFAULT_SAFEBASE_RADIUS = 50 # Default safe area radius (normal commandpoint radius = 10)
ALLOWED_SAFEBASEKILLS = 3
SAFEBASEKILL_TIMER_INTERVAL = 120 # Intervals between removing a point from players.baseRapeWarning

# ------------------------------------------------------------------------
# Variables
# ------------------------------------------------------------------------

WarnReduceTimer = None # Timer that reduces the warnings at intervals

# ------------------------------------------------------------------------
# Init
# ------------------------------------------------------------------------

class BaseRape( object ) : 

  def __init__( self, modManager ):
  # ModManager reference
  self.mm = modManager

  # Internal shutdown state
  self.__state = 0

  def init( self ):
  if g_debug: print "AntiBaseRape init"
  if 0 == self.__state:
	 host.registerHandler('PlayerConnect', self.onPlayerConnect, 1)   
	 host.registerHandler('PlayerKilled', self.onPlayerKilled)

	 # Update to the running state
	 self.__state = 1

	 # Start the timer that reduces warnings on the SAFEBASEKILL_TIMER_INTERVAL
	 WarnReduceTimer = bf2.Timer(self.onSafeBaseKillTimer, SAFEBASEKILL_TIMER_INTERVAL, 1)
	 WarnReduceTimer.setRecurring(SAFEBASEKILL_TIMER_INTERVAL)

	 # Connect already connected players if reinitializing
	 for p in bf2.playerManager.getPlayers():
		self.onPlayerConnect(p)
  # ------------------------------------------------------------------------


  # ------------------------------------------------------------------------
  #  onPlayerConnect
  # ------------------------------------------------------------------------
  def onPlayerConnect(self, player):
  self.resetPlayer(player)
  # ------------------------------------------------------------------------


  # ------------------------------------------------------------------------
  # onPlayerKilled
  # ------------------------------------------------------------------------
  def onPlayerKilled(self, victim, attacker, weapon, assists, object):
  # killed by self
  if attacker == victim:
	 pass

  # killed by enemy
  elif attacker != None and attacker.getTeam() != victim.getTeam():
	 self.checkForSafeBase(attacker, victim)
  # ------------------------------------------------------------------------


  def shutdown( self ):
  """Shutdown and stop processing."""

  # Unregister game handlers and do any other
  # other actions to ensure your module no longer affects
  # the game in anyway
  if WarnReduceTimer:
	WarnReduceTimer.destroy()
	WarnReduceTimer = None

  # Flag as shutdown as there is currently way to:
  # host.unregisterHandler
  self.__state = 2

  # ------------------------------------------------------------------------
  # Reset the number of warnings
  # ------------------------------------------------------------------------
  def resetPlayer(self, player):
  player.baseRapeWarning = 0
  # ------------------------------------------------------------------------


  # ------------------------------------------------------------------------
  # Check if victim was killed within safebase area
  # ------------------------------------------------------------------------
  def checkForSafeBase(self, attacker, victim):
  victimVehicle = victim.getVehicle()
  controlPoints = bf2.objectManager.getObjectsOfType('dice.hfe.world.ObjectTemplate.ControlPoint')
  for cp in controlPoints:
	 if cp.cp_getParam('unableToChangeTeam') != 0 and cp.cp_getParam('team') != attacker.getTeam():
		distanceTo = self.getVectorDistance(victimVehicle.getPosition(), cp.getPosition())
		if DEFAULT_SAFEBASE_RADIUS > float(distanceTo):
		   self.justify(attacker, victim, cp, distanceTo)
  # ------------------------------------------------------------------------


  # ------------------------------------------------------------------------
  # Punish attacker, give victim life back and inform all
  # ------------------------------------------------------------------------
  def justify(self, attacker, victim, controlPoint, distanceTo):
  #victim.score.deaths += -1
  #attacker.score.kills += -1
  #attacker.score.score += -2 - attacker.baseRapeWarning
  attacker.baseRapeWarning += 1
  self.sendWarning(attacker, controlPoint, distanceTo)
  #if attacker.baseRapeWarning > ALLOWED_SAFEBASEKILLS:
	 #attacker.score.TKs += 1
	 #if attacker.isAlive():
		#vehicle = attacker.getVehicle()
		#rootVehicle = getRootParent(vehicle)
		#if getVehicleType(rootVehicle.templateName) == VEHICLE_TYPE_SOLDIER:
		   #rootVehicle.setDamage(0)
		   # This should kill them !
		#else:
		   #rootVehicle.setDamage(1) 
		   # a vehicle will likely explode within 1 sec killing entire crew,
		   # not so sure about base defenses though
  # ------------------------------------------------------------------------


  # ------------------------------------------------------------------------
  # Send Warning
  # ------------------------------------------------------------------------
  def sendWarning(self, player, controlPoint, distanceTo):
  mapName = bf2.gameLogic.getMapName()
  if player.baseRapeWarning > ALLOWED_SAFEBASEKILLS:
	 mm_utils.msg_server(player.getName() + " is punished for repeated violating of the no kill rules within safe base area")
	 host.rcon_invoke("pb_sv_kick\""+str(player.getName())+"\""+str(KICK_IN_MINUTES)+"\""+str(KICK_REASON)+"\"")
  else:
	 mm_utils.msg_server(player.getName() + " has violated the no kill rules within safe base area " + str(player.baseRapeWarning) + " times now")
  # ------------------------------------------------------------------------


  # ------------------------------------------------------------------------
  # remove baseRapeWarnings over time
  # ------------------------------------------------------------------------
  def onSafeBaseKillTimer(self, data):
  for p in bf2.playerManager.getPlayers():
	 if p.baseRapeWarning <= 0:
		p.baseRapeWarning = 0
	 else:
		p.baseRapeWarning += -1
  # ------------------------------------------------------------------------


  # ------------------------------------------------------------------------
  # get distance between two positions
  # ------------------------------------------------------------------------
  def getVectorDistance(self, pos1, pos2):
  diffVec = [0.0, 0.0, 0.0]
  diffVec[0] = math.fabs(pos1[0] - pos2[0])
  diffVec[1] = math.fabs(pos1[1] - pos2[1])
  diffVec[2] = math.fabs(pos1[2] - pos2[2])

  return math.sqrt(diffVec[0] * diffVec[0] + diffVec[1] * diffVec[1] + diffVec[2] * diffVec[2])
  # ------------------------------------------------------------------------


# ------------------------------------------------------------------------
# ModManager Init
# ------------------------------------------------------------------------
def mm_load( modManager ):
"""Creates and returns your object."""
return BaseRape( modManager )

I don't use MM so I can't test it, but this should do what you're attempting.

Of course, change the

KICK_IN_MINUTES = 1

KICK_REASON = "Base Rape"

to your liking.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...