# Does not work FPS WATCH script

**URL:** <https://cod4x.ovh/t/does-not-work-fps-watch-script/1609>\
**Category:** CoD4x | Mods & Script Support\
**Created:** [February 18, 2023, 1:05am UTC](https://cod4x.ovh/t/does-not-work-fps-watch-script/1609 "2023-02-18T01:05:38Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Powerless](https://cod4x.ovh/user_avatar/cod4x.ovh/powerless/32/366_2.png) [@Powerless](https://cod4x.ovh/u/Powerless)\
**Post date:** [February 18, 2023, 1:05am UTC](https://cod4x.ovh/t/does-not-work-fps-watch-script/1609/1 "2023-02-18T01:05:38Z")

</div>

Hello! The first time I tried to install the script on my promod server, but it doesn’t work. What did I do wrong ?

Script directory:  
main-server-files/mods/pmlkam\_262/maps/mp/gametypes/\_fpswatch.gsx

```auto
//Script by |RS|PowahRanger
//Discord PowahRanger#0001
//Royal-Soldiers.com

fpsWatch2()
{
wait 5;
Violations = 0;
 
self endon( "disconnect" );

fps1 = self GetCountedFPS();
	if (fps1 > 151)
	{
	Violations++;
	wait 5;
	}
	else
	{
	wait 5;
	}
fps2 = self GetCountedFPS();
	if (fps2 > 151)
	{
	Violations++;
		wait 5;
	}
	else
	{
	wait 5;
	}
fps3 = self GetCountedFPS();
	if (fps3 > 151)
	{
	Violations++;
	wait 5;
	}
	else
	{
	wait 5;
	}
fps4 = self GetCountedFPS();
	if (fps4 > 151)
	{
	Violations++;
	wait 5;
	}
	else
	{
	wait 5;
	}
fps5 = self GetCountedFPS();
	if (fps5 > 151)
	{
	Violations++;
	wait 5;
	}
	else
	{
	wait 5;
	}
fps6 = self GetCountedFPS();
	if (fps6 > 151)
	{
	Violations++;
	wait 5;
	}
	else
	{
	wait 5;
	}
fps7 = self GetCountedFPS();
	if (fps7 > 151)
	{
	Violations++;
	wait 5;
	}
	else
	{
	wait 5;
	}

	if( Violations > 5 )
	{
//	exec ( "say" + self + "^1is Using 333FPS! ^7Kicking...");
	exec( "kick " + self getEntityNumber() + " 333 FPS is not allowed" );
	wait 1;
	Violations = 0;
	return;
	}	
	else
	{
	exec ( "say" + self + "^1is Using 333FPS! ^7Kicking...");
	Violations = 0;
	return;
	}
	
}

```

in file main-server-files/mods/pmlkam\_262/maps/mp/gametypes/\_globallogic.gsc i wrote:

```auto
 CodeCallback_StartGameType()
{
    // If the gametype has not beed started, run the startup
    if(!isDefined(level.gametypestarted) || !level.gametypestarted)
    {
        [[level.callbackStartGameType]]();

        level.gametypestarted = true; // so we know that the gametype has been started up
        
 
                level thread maps\mp\gametypes\_fpswatch::init();
               
    }
} 

```

But nothing happens. What did I do wrong ?

---

<div class="post-metadata">

**Author:** ![Sh3llK0de](https://cod4x.ovh/user_avatar/cod4x.ovh/sh3llk0de/32/161_2.png) [@Sh3llK0de](https://cod4x.ovh/u/Sh3llK0de)\
**Post date:** [February 18, 2023, 2:32am UTC](https://cod4x.ovh/t/does-not-work-fps-watch-script/1609/2 "2023-02-18T02:32:32Z")

</div>

I don’t see an “init()” function in \_fpswatch script…can’t call something that not there. You should be calling the fpsWatch2 function on the player when they connect.

Example:  
self thread maps\mp\gametypes\_fpswatch::fpsWatch2();

---

<div class="post-metadata">

**Author:** ![Powerless](https://cod4x.ovh/user_avatar/cod4x.ovh/powerless/32/366_2.png) [@Powerless](https://cod4x.ovh/u/Powerless)\
**Post date:** [February 18, 2023, 11:03am UTC](https://cod4x.ovh/t/does-not-work-fps-watch-script/1609/3 "2023-02-18T11:03:03Z")

</div>

I solved the problem, thank you.

Maybe someone will come in handy:

how to install script for promodlive:

1. create \_callbacksetup.gsc in “mods/pmlkam\_262/maps/mp/gametypes”  
in \_callbacksetup.gsc copy

```auto
//	Callback Setup
//	This script provides the hooks from code into script for the gametype callback functions.

//=============================================================================
// Code Callback functions

/*================
Called by code after the level's main script function has run.
================*/
CodeCallback_StartGameType()
{
	// If the gametype has not beed started, run the startup
	if(!isDefined(level.gametypestarted) || !level.gametypestarted)
	{
		[[level.callbackStartGameType]]();

		level.gametypestarted = true; // so we know that the gametype has been started up

                thread _fpswatch::init();
	}
}

/*================
Called when a player begins connecting to the server.
Called again for every map change or tournement restart.
Return undefined if the client should be allowed, otherwise return
a string with the reason for denial.
Otherwise, the client will be sent the current gamestate
and will eventually get to ClientBegin.
firstTime will be qtrue the very first time a client connects
to the server machine, but qfalse on map changes and tournement
restarts.
================*/
CodeCallback_PlayerConnect()
{
	self endon("disconnect");
	[[level.callbackPlayerConnect]]();
}

/*================
Called when a player drops from the server.
Will not be called between levels.
self is the player that is disconnecting.
================*/
CodeCallback_PlayerDisconnect()
{
	self notify("disconnect");
	[[level.callbackPlayerDisconnect]]();
}

/*================
Called when a player has taken damage.
self is the player that took damage.
================*/
CodeCallback_PlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset)
{
	self endon("disconnect");
	[[level.callbackPlayerDamage]](eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset);
}

/*================
Called when a player has been killed.
self is the player that was killed.
================*/
CodeCallback_PlayerKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration)
{
	self endon("disconnect");
	[[level.callbackPlayerKilled]](eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration);
}

/*================
Called when a player has been killed, but has last stand perk.
self is the player that was killed.
================*/
CodeCallback_PlayerLastStand(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration )
{
	self endon("disconnect");
	[[level.callbackPlayerLastStand]](eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration );
}

//=============================================================================

/*================
Setup any misc callbacks stuff like defines and default callbacks
================*/
SetupCallbacks()
{
	SetDefaultCallbacks();
	
	// Set defined for damage flags used in the playerDamage callback
	level.iDFLAGS_RADIUS = 1;
	level.iDFLAGS_NO_ARMOR = 2;
	level.iDFLAGS_NO_KNOCKBACK = 4;
	level.iDFLAGS_PENETRATION = 8;
	level.iDFLAGS_NO_TEAM_PROTECTION = 16;
	level.iDFLAGS_NO_PROTECTION = 32;
	level.iDFLAGS_PASSTHRU = 64;
}

/*================
Called from the gametype script to store off the default callback functions.
This allows the callbacks to be overridden by level script, but not lost.
================*/
SetDefaultCallbacks()
{
	level.callbackStartGameType = maps\mp\gametypes\_globallogic::Callback_StartGameType;
	level.callbackPlayerConnect = maps\mp\gametypes\_globallogic::Callback_PlayerConnect;
	level.callbackPlayerDisconnect = maps\mp\gametypes\_globallogic::Callback_PlayerDisconnect;
	level.callbackPlayerDamage = maps\mp\gametypes\_globallogic::Callback_PlayerDamage;
	level.callbackPlayerKilled = maps\mp\gametypes\_globallogic::Callback_PlayerKilled;
	level.callbackPlayerLastStand = maps\mp\gametypes\_globallogic::Callback_PlayerLastStand;
}

/*================
Called when a gametype is not supported.
================*/
AbortLevel()
{
	println("Aborting level - gametype is not supported");

	level.callbackStartGameType = ::callbackVoid;
	level.callbackPlayerConnect = ::callbackVoid;
	level.callbackPlayerDisconnect = ::callbackVoid;
	level.callbackPlayerDamage = ::callbackVoid;
	level.callbackPlayerKilled = ::callbackVoid;
	level.callbackPlayerLastStand = ::callbackVoid;
	
	setdvar("g_gametype", "dm");

	exitLevel(false);
}

/*================
================*/
callbackVoid()
{
}

```

script copy in “mods/pmlkam\_262”

i have:  
script \_fpswatch.gsx  
add in  
\_callbacksetup.gsc

```auto
CodeCallback_StartGameType()
{
	// If the gametype has not beed started, run the startup
	if(!isDefined(level.gametypestarted) || !level.gametypestarted)
	{
		[[level.callbackStartGameType]]();

		level.gametypestarted = true; // so we know that the gametype has been started up

                thread _fpswatch::init();
	}
}

```

/map\_restart and ready.

---

<div class="post-metadata">

**Author:** ![Hajas](https://cod4x.ovh/user_avatar/cod4x.ovh/hajas/32/275_2.png) [@Hajas](https://cod4x.ovh/u/Hajas)\
**Post date:** [February 21, 2023, 1:24pm UTC](https://cod4x.ovh/t/does-not-work-fps-watch-script/1609/4 "2023-02-21T13:24:46Z")

</div>

GetCountedFPS() doesn’t work well sadly, will sometimes get very weird and high values, so can’t be trusted to kick or ban a player. Players with high hz monitors will eventually pass from 333.

The best way to avoid that cheat is force the VSync, that’s what I did.

---

<div class="post-metadata">

**Author:** ![Powerless](https://cod4x.ovh/user_avatar/cod4x.ovh/powerless/32/366_2.png) [@Powerless](https://cod4x.ovh/u/Powerless)\
**Post date:** [February 25, 2023, 2:32am UTC](https://cod4x.ovh/t/does-not-work-fps-watch-script/1609/5 "2023-02-25T02:32:04Z")

</div>

Found in logs:

```auto
throwing script exception: pair 'say' and 'entity' has unmatching types 'string' and 'object'

^1 *******script runtime error*******
pair 'say' and 'entity' has unmatching types 'string' and 'object': (file '_fpswatch.gsx', line 103)
 exec ( "say" + self + "^1is Using FPS > 250! ^1Kicking...");
              *
^1started from:
(file '_fpswatch.gsx', line 90)
 wait 5;
 *
^1 ************************************
throwing script exception: pair 'undefined' and '^1is Using FPS > 250! ^1Kicking...' has unmatching types 'undefined' and 'string'

^1 *******script runtime error*******
pair 'undefined' and '^1is Using FPS > 250! ^1Kicking...' has unmatching types 'undefined' and 'string': (file '_fpswatch.gsx', line 103)
 exec ( "say" + self + "^1is Using FPS > 250! ^1Kicking...");
                     *
^1started from:
(file '_fpswatch.gsx', line 90)
 wait 5;
 *
^1 ************************************

^1 *******script runtime error*******
cannot cast undefined to string: (file '_fpswatch.gsx', line 103)
 exec ( "say" + self + "^1is Using FPS > 250! ^1Kicking...");
                     *
^1started from:
(file '_fpswatch.gsx', line 90)
 wait 5;
 *
^1 ************************************

```

Why ?

---

<div class="post-metadata">

**Author:** ![geplaza](https://cod4x.ovh/user_avatar/cod4x.ovh/geplaza/32/905_2.png) [@geplaza](https://cod4x.ovh/u/geplaza)\
**Post date:** [September 3, 2024, 12:45am UTC](https://cod4x.ovh/t/does-not-work-fps-watch-script/1609/6 "2024-09-03T00:45:53Z")

</div>

Hello, were you able to find a solution to the problem?

---

<div class="post-metadata">

**Author:** ![geplaza](https://cod4x.ovh/user_avatar/cod4x.ovh/geplaza/32/905_2.png) [@geplaza](https://cod4x.ovh/u/geplaza)\
**Post date:** [September 3, 2024, 12:47am UTC](https://cod4x.ovh/t/does-not-work-fps-watch-script/1609/7 "2024-09-03T00:47:32Z")

</div>

Hello friend, a question, I left you a message on discord. based on this same topic

---

<div class="post-metadata">

**Author:** ![workong](https://cod4x.ovh/user_avatar/cod4x.ovh/workong/32/1971_2.png) [@workong](https://cod4x.ovh/u/workong)\
**Post date:** [December 16, 2024, 8:40pm UTC](https://cod4x.ovh/t/does-not-work-fps-watch-script/1609/8 "2024-12-16T20:40:39Z")

</div>

pair ‘say’ and ‘entity’ has unmatching types ‘string’ and ‘object’

You cant do this: “exec ( “say” + self + “^1is Using FPS \> 250! ^1Kicking…”);”

you should do something like:

exec ( "say " + self.name + “^1is Using FPS \> 250! ^1Kicking…”);
