Talk:Scripts:Kicking for high ping

From BF2 Technical Information Wiki
Revision as of 05:12, 25 July 2005 by Kybber (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

If you have any questions or comments, please post them here, by clicking the '+' sign to the right of the 'edit' link above, or by following this link :-)

Contents

Cant get this to start....

This doesn't seem to do anything... how can i get it to start? I've even turned the bfno_debug = True on, and can see no console messages in the server console or in my game console.

v1.1

Have you tried v1.1? If not, please try that one. If it still doesn't work, please post everything you did while installing it, and I'll see if I can see what you're doing wrong. -Panic

Yes I am using 1.1 - Please have a look and see if you can help.

Yes I downloaded the code 2 days ago so I take it it is 1.1.

We have multiple servers running on one PC so I will give you the full description of what was done to one of them.

First we use a .bat file to start and keep bf2 up and running.

@echo off
cls
echo Protecting BF2-server from crashes...
echo If you want to close BF2 and this script, close the BF2 window and type Y depending on your language followed by Enter.
title BF2 Ranked #1 Watchdog
:bf2start
echo (%time% at %date%) BF2-server started.
start /wait "bf2_w32ded.exe Watchdog" "E:\HostedApps\BF2SERVER_1\bf2_w32ded.exe" +config "E:\HostedApps\BF2SERVER_1\config\bf2.con" +mapList "E:\HostedApps\BF2SERVER_1\config\_maplist.con" +overlayPath "E:\HostedApps\BF2SERVER_1"
echo (%time% at %date%) WARNING: BF2 closed or crashed, restarting.
goto bf2start

Our configs are in a config folder E:\HostedApps\BF2Server_1\config

We use bf2.con and _maplist.con. These are addressed in the command line in the bat file that starts it up. I don't really want to post our bf2.con file for obvious reasons, but can email it to you if you like.

Game runs fine, no probs with the above settings so hopefully it's not because of that.

So to implement the high ping thing we got have in the following folder E:\HostedApps\BF2Server_1\admin\standard_admin __init__.py which is

import autobalance
import tk_punish

autobalance.init()
tk_punish.init()	

import pingkick.py
pingkick.init()

and pingkick.py

# ------------------------------------------------------------------------
# Module: pingkick.py
# Authors: Kybber and Panic, Battlefield.no
# Version 1.1
# Description:
#   This script kicks players with high ping, based on three different
#   settings in the file 'adminsettings.con', loaded by the modified admin
#   script (sv.adminScript = bfno_v1.1.py). See requirements for details.
# Requirements:
#   None.
# Installation:
#   Save this script as 'pingkick.py' in your <bf2>/admin/standard_admin directory,
#   and add the lines 'import pingkick' and 'pingkick.init()' to the file
#   '<bf2>/admin/standard_admin/__init__.py'.
#
# Changes from 1.0 to 1.1:
# - Added support for stand-alone operation. (Will use bf2.adminoptions if available)
# - The script now only checks ping while game status is 'Playing'
# - Switched from 'bfno' to prefix 'pk' for ping kick settings in 'bf2.adminoptions'.
# - Other, minor updates.
# ------------------------------------------------------------------------

# ------------------------------------------------------------------------
#                     C O N F I G U R A T I O N
# ------------------------------------------------------------------------
# Settings for auto-kicking:
autokick = 1      # Enables/disables autockicking
pinglimit = 200   # The ping limit, obviously ;-p
warnings = 3      # The number of warnings a player get before being kicked`
interval = 30     # The interval between ping checks
# NB: These settings will be overridden by their counter-parts in
# bf2.adminoptions['pk.<autoKick|pingLimit|warnings|interval']
# if those are present.

# ------------------------------------------------------------------------
#                        I M P O R T
# ------------------------------------------------------------------------

import host
import bf2
from bf2 import g_debug

# ------------------------------------------------------------------------
#                       V A R I A B L E S
# ------------------------------------------------------------------------

# We need our own debug flag:
bfno_debug = True

# Some timers:
pktimer   = None  # Timer firing off the ping checker. Depends on the 'interval' variable.
kicktimer = None  # Timer that delays kicking after the final warning has been issued.
msgtimer  = None  # Timer that delays the "activated" message after entering bf2.GameStatus.Playing
# List of people to kick for high ping:
kicklist = None


# For keeping track of the game status:
gamestatus = None


# ------------------------------------------------------------------------
#                       F U N C T I O N S
# ------------------------------------------------------------------------
# ------------------------------------------------------------------------
# The init function run by the standard_admin/__init__ functions:
# ------------------------------------------------------------------------
def init():
global interval
if g_debug or bfno_debug: print 'PINGKICK: initializing pingkick script'
# Try to read the settings:
if not getSettings():
return
# Force at least 10 seconds between ping checks:
if interval < 10: interval = 10
# Print debug message if autokick is disabled:
if 1 != autokick:
if g_debug or bfno_debug: print 'PINGKICK: High ping autokick not enabled'

# Autokick is enabled, so hook it up:
else:
if g_debug or bfno_debug: print 'PINGKICK: Enabling kick for high ping. Limit = %s, max warnings = %s.' % (pinglimit, warnings)

# Register 'PlayerConnect' callback:
host.registerHandler('PlayerConnect', onPlayerConnect, 1)
host.registerGameStatusHandler(onGameStatusChanged)

# Reset TK Warnings
for p in bf2.playerManager.getPlayers(): 
onPlayerConnect(p)

# PingKickTimer:
enableCheckTimer()
# ------------------------------------------------------------------------
# ------------------------------------------------------------------------
# Get the settings from the bf2.adminsettings object:
# ------------------------------------------------------------------------
def getSettings():
global autokick,pinglimit,warnings,interval
readOk = False
# Try to access the autokick setting:
try:
if g_debug or bfno_debug: print "PINGKICK: Reading settings from bf2.adminoptions:" 
autokick  = int(bf2.adminoptions['pk.autoKick'])
pinglimit = int(bf2.adminoptions['pk.pingLimit'])
warnings  = int(bf2.adminoptions['pk.warnings'])
interval  = int(bf2.adminoptions['pk.interval'])
readOk    = True
except:
if g_debug or bfno_debug: print "PINGKICK: WARNING - Could not get settings from 'bf2.adminoptions'. Using default values:"
if g_debug: 
print "  autokick  : " + str(autokick)
print "  pinglimit : " + str(pinglimit)
print "  maxwarns  : " + str(warnings)
print "  interval  : " + str(interval)
return readOk
# ------------------------------------------------------------------------
# ------------------------------------------------------------------------
# Callback function for the "PlayerConnect" event:
# ------------------------------------------------------------------------
def onPlayerConnect(p):
"""Resets the ping warning counter for the player"""
p.pingWarnings = 0 # Reset the 'TK Warnings' counter.
# ------------------------------------------------------------------------
# ------------------------------------------------------------------------
# Callback function for the "PreGame" game status event:
# ------------------------------------------------------------------------
def onGameStatusChanged(status):
"""Enables the ping check timer"""
# Import variables, and update the game status:
global gamestatus, kicklist, msgtimer
gamestatus = status
if gamestatus == bf2.GameStatus.Playing and autokick:
if bfno_debug: print "PINGKICK: Setting msgtimer" 
msgtimer = bf2.Timer(onMsgTimer,10,1)
# Return if not PreGame:
elif gamestatus == bf2.GameStatus.PreGame:
if bfno_debug: print "PINGKICK: Game status changed to PreGame. Resetting warnings and re-enabling check-timer"
# Reset the kicklist
kicklist = None
# Read the settings again:
getSettings()
# Reset TK Warnings
for p in bf2.playerManager.getPlayers():
p.pingWarnings = 0
# Enable the ping check timer:
enableCheckTimer()
# ------------------------------------------------------------------------
# ------------------------------------------------------------------------
# Callback function for timer, that delays a message at round start:
# ------------------------------------------------------------------------
def onMsgTimer(data):
global msgtimer
if bfno_debug: print "PINGKICK: Entering onMsgTimer"
msg = "Activated! Kicking at " + str(pinglimit) + " after " + str(warnings) + " warnings."
sendMsg(msg)
msgtimer.destroy()
msgtimer = None
# ------------------------------------------------------------------------
# ------------------------------------------------------------------------
# Send text messages to the server, using rcon game.sayAll:
# ------------------------------------------------------------------------
def sendMsg(msg):
# Sure you can edit this, and remove 'bf2.no'. But hey, why not give us the credit? ;-)
host.rcon_invoke("game.sayAll \"BF2.NO PING KICKER: " + str(msg) + "\"")
# ------------------------------------------------------------------------
# ------------------------------------------------------------------------
# Enable the pktimer:
# ------------------------------------------------------------------------
def enableKickTimer():
"""Enables the timer that runs the 'kickPlayers' functions"""
global kicktimer
if bfno_debug: print "PINGKICK: Enabling the kicktimer..."
kicktimer = bf2.Timer(kickPlayers, 5, 1)
# ------------------------------------------------------------------------
# ------------------------------------------------------------------------
# Enable the pktimer:
# ------------------------------------------------------------------------
def enableCheckTimer():
"""Enables the timer that runs the 'checkPing' function"""
global pktimer
if pktimer:
return True
else:
# Create the timer:
if bfno_debug: print "PINGKICK: Timer not enabled. Enabling..."
pktimer = bf2.Timer(checkPing, interval, 1)
pktimer.setRecurring(interval)
# Print debug message telling the status of the timer:
if pktimer:
if bfno_debug: print "PINGKICK: Time = %s" % (pktimer.getTime()) 
return True
else:
if bfno_debug: print "PINGKICK: Not enabled"
return False
# ------------------------------------------------------------------------
# ------------------------------------------------------------------------
# Loop all players, checking their ping, kick high-pinger:
# ------------------------------------------------------------------------
def checkPing(data):
"""Checks ping of all players, and kicks high-pingers"""

global kicklist

# We only want to check ping during rounds:
if gamestatus != bf2.GameStatus.Playing: return

# Make sure our timer is enabled:
if not enableCheckTimer(): return

if bfno_debug: print "PINGKICK: Running checkPing"

# Loop all players
for p in bf2.playerManager.getPlayers():
name = str(p.getName())
# Check the ping if the limit hasn't been reached:
ping = None
try:
ping = p.getPing()
except:
pass
# If we have a valid ping, check it, and issue a warning if the ping exceeds the limit:
if ping:
#if g_debug: print "PINGKICK: " + name + " has " + str(ping) + " in ping and has " + str(p.pingWarnings) + " Ping-warnings"
if ping > pinglimit: 
p.pingWarnings += 1
if bfno_debug: print "PINGKICK: Player " + name + " has exceeded the ping limit " + str(p.pingWarnings) + " time(s)"
sendMsg("WARNING: " + name + " has exeeded the ping limit " + str(p.pingWarnings) + " time(s)")
# Issue a warning if a player has reached the maximum number of warnings. Will be kicked next time 'checkPing' is run:
if warnings == p.pingWarnings:
sendMsg("Kicking player " + name + " for high ping")
# Add the player to the kicklist:
if kicklist: kicklist.append(p.index)
else: kicklist = [p.index]

# Check of we shall enable the kicktimer:
if kicklist:
enableKickTimer()
# ------------------------------------------------------------------------
# ------------------------------------------------------------------------
# Function run by the kicktimer:
# ------------------------------------------------------------------------
def kickPlayers(data):
"""Loops through 'kicklist', and kicks players accordingly."""
#print "PINGKICK: kickPlayers..."
global kicklist,kicktimer
for i in kicklist:
p = bf2.playerManager.getPlayerByIndex(i)
# Check if this player has reached the limit for maximum warnongs
if warnings <= p.pingWarnings:
# Kick if limit is reached:
if g_debug or bfno_debug: print "PINGKICK: Kicking player " + p.getName() + " for high ping"
result = host.rcon_invoke("admin.kickPlayer " + str(p.index)) 
kicklist = None
kicktimer.destroy()
# ------------------------------------------------------------------------



I thought that was all I needed to do. I've turned the debug flag to True, but cannot see anything at all in the console. Please help get this sorted, HPB are ruining it for everybody.

Ah, here is the problem

There was a typo in the instructions until earlier today. The correct entry to put in your __init__.py file is not

import pingkick.py
pingkick.init()

but rather

import pingkick
pingkick.init()

Sorry about that. The instructions have been fixed. Hope this makes it work for you :)

--Kybber 17:10, 29 Jun 2005 (MDT)

NOPE

I've taken the .py off the end of the import line. Still not working.



    • same here..

It is not working for etiher

Make sure formatting of script is okay

I notice that the text you pasted in above has not been formatted correctly. Python is very specific on the indentation of code, so please make sure that indentation is correct.

If you copy-pasted the script from the wiki, then that may have messed up the formatting. You could try to redownload from the provided link.

Panic: Can you confirm that the downloadable file contains the latest working version (which we verified today)?

--Kybber 09:50, 30 Jun 2005 (MDT)

Panic, the code format of the downloaded file is still not correct. You have not used the Tab for indentation but Space. It takes alot of time to indent all the code --Quade 06:42, 25 Jul 2005 (MDT)

There's no need to use TABs; space has exactly the same effect. --Kybber 07:12, 25 Jul 2005 (MDT)

I don't think that's it.

I went through and added tabs to each line in the wiki so it would show up nicely when you read it. I have the latest 1.1 file downloaded... all that is changed are the 4 variables and I set the debug flag to true.

I don't even think this is starting, there is never any evidence in the server console or the in game console that it is doing anything.

How can I test if it is starting? I am sure it would work nicely if I could get it to run.

Have you enabled a logger?

Are you using the modified admin script? If not, then there is no logging available since the writer class isn't instantiated.

The best (only) way to check if it is working if you don't have a logger running, is to set a very low ping limit, start the server, log on and see if you get any sort of ingame message (green text at top left corner) about your ping being too high, followed by a kick after a number of warnings.

--Kybber 16:56, 30 Jun 2005 (MDT)

Ive done that.

I've set it to 0 and played on it ok, there is no messages. So it's not even starting... what would you recommend I do? Does it have anything to do with our startup lines? The +maplist +config +overlay flags?

Errors in other imported files?

I've noticed that if there's an error in any of my imported scripts, the entire __init__.py file will fail. It's quite possible that the high-ping kick script isn't the one causing problems.

1. If you're using the Modified Admin Script on Windows, apply the backslash fix mentioned in the Discussion page for that script. If you have other scripts that use the frontslash ("/") for filepaths, then consider applying the same fix to them.
2. Check your __init__.py file and make doubly sure there are no errors there.
3. Progressively test each file mentioned in your __init__.py file to make sure it's working.

3a)Remove every import and init from your __init__.py file, except the default ones.
3b)Add new files to __init__.py one at a time, and fire up your server after each one.

4. If you've made any modifications to scripts you've downloaded, consider re-downloading them.
5. Finally, remember that indentation is everything with Python. If you've got one tab placed wrong, the entire __init__.py file will fail.

Thanks!

Thanks alot for helping people with my script! :-) I've added v1.2 btw. -Panic

Ahem...

That's "our" script, Panic ;)

--Kybber 06:36, 3 Jul 2005 (MDT)

Privilege Error

Hi, someone tried to connect to my server and they had a reported ping of zero. It looked like the high ping script was trying to kick them but the console showed an error from punkbuster that it didn't have OS Privilege to kick. Sorry I couldn't copy and paste the error text. If I see it again I will try to grab it.

Any ideas about this? David

Pings of zero

Ping is always reported as zero while a player is loading the game up until the time at which he is able to click the join button. Regardless of whether he actually pushes the button at that time, the ping will be available to the script.

The PB problem you had: Are you sure you are not confusing it with the common client problem in which the installation was done as a non-administrative user, something which causes PB to complain that it has inadequate OS privileges since it is not allowed to scan everything it needs to? I don't see how PB could interfere with our script like that, since the script never touches on PB whatsoever.

--Kybber 04:41, 5 Jul 2005 (MDT)

Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox