Bump version

Bump version

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/cjlesiw/arena-respawn.git/'


Add new example of http post request

Add new example of http post request

#include <amxmodx>
#include <curl>

#pragma semicolon 1
#pragma ctrlchar '\'

public plugin_init()
{
    register_plugin("HTTP: Post request", "1.0.0", "gamingEx aka. Kaido Ren");
    @requestBegin();
}

enum dataStruct { curl_slist: linkedList };

@requestBegin()
{
    new CURL: pCurl, curl_slist: pHeaders, sData[dataStruct];

    pHeaders = curl_slist_append(pHeaders, "Content-Type: application/json");
    pHeaders = curl_slist_append(pHeaders, "User-Agent: curl");

    sData[linkedList] = pHeaders;

    if ((pCurl = curl_easy_init())) {
        curl_easy_setopt(pCurl, CURLOPT_URL, "http://jsonplaceholder.typicode.com/posts");
        curl_easy_setopt(pCurl, CURLOPT_COPYPOSTFIELDS, "{\"title\": \"foo\", \"body\": \"bar\", \"userId\": 1}");
        curl_easy_setopt(pCurl, CURLOPT_CUSTOMREQUEST, "POST");
        curl_easy_setopt(pCurl, CURLOPT_HTTPHEADER, pHeaders);
        curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, "@responseWrite");

        curl_easy_perform(pCurl, "@requestComplete", sData, dataStruct);
    }
}

@responseWrite(const data[], const size, const nmemb)
{
    server_print("Response body: \n%s", data);

    return size * nmemb; // tell curl how many bytes we handled
}

@requestComplete(CURL: curl, CURLcode: code, const data[dataStruct])
{
    if (code != CURLE_OK) {
        new szError[128];
        curl_easy_strerror(code, szError, charsmax(szError));
        server_print("CURL: %s", szError);
    }

    curl_easy_cleanup(curl);
    curl_slist_free_all(data[linkedList]);
}

error: pathspec 'amx_examples/http_post_json.sma' did not match any file(s) known to git


Move to include, will make .inc soonish

Move to include, will make .inc soonish

/****************************************
 * mckayupdater.sp
 *
 * This file is used in Dr. McKay's plugins for Updater integration
 * For more info on Dr. McKay's plugins, see http://www.doctormckay.com
 * For more info on Updater, see https://forums.alliedmods.net/showthread.php?t=169095
 * You may copy and use this file, but please be sure to change the URL to your own!
 *
 * This file does the following tasks:
 * 		- Adds the plugin to Updater's updating pool (using UPDATER_BASE_URL/UPDATE_FILE (UPDATE_FILE should be defined prior to including this file))
 * 		- Creates a cvar CONVAR_PREFIX_auto_update to control whether Updater is enabled (CONVAR_PREFIX should be defined prior to including this file)
 * 		- Creates a version cvar CONVAR_PREFIX_version (CONVAR_PREFIX should be defined prior to including this file)
 * 		- Dynamically adds "A" to the version cvar based on whether Updater is installed and working
 *
 * If you need to put code into OnAllPluginsLoaded, define ALL_PLUGINS_LOADED_FUNC with a function (doesn't need to be public) to be called inside of OnAllPluginsLoaded
 * 		For example, #define ALL_PLUGINS_LOADED_FUNC AllPluginsLoaded
 * 		AllPluginsLoaded() { ... }
 *
 * If you need to put code into OnLibraryAdded, define LIBRARY_ADDED_FUNC with a function (doesn't need to be public) to be called inside of OnLibraryAdded
 * 		For example, #define LIBRARY_ADDED_FUNC LibraryAdded
 * 		LibraryAdded(const String:name[]) { ... }
 *
 * If you need to put code into OnLibraryRemoved, define LIBRARY_REMOVED_FUNC with a function (doesn't need to be public) to be called inside of OnLibraryRemoved
 * 		For example, #define LIBRARY_REMOVED_FUNC LibraryRemoved
 * 		LibraryRemoved(const String:name[]) { ... }
 *
 * Define RELOAD_ON_UPDATE and the plugin will reload itself upon being updated
 *
 */

#if defined _mckay_updater_included
 #endinput
#endif
#define _mckay_updater_included

#if defined REQUIRE_PLUGIN
 #undef REQUIRE_PLUGIN
#endif
#include <updater>
#define REQUIRE_PLUGIN

#define UPDATER_BASE_URL "http://hg.doctormckay.com/public-plugins/raw/default"

Handle cvarEnableUpdater;
Handle cvarVersion;

public void OnAllPluginsLoaded() {
	char cvarName[64];
	Format(cvarName, sizeof(cvarName), "%s_auto_update", CONVAR_PREFIX);
	cvarEnableUpdater = CreateConVar(cvarName, "1", "Enables automatic updating (has no effect if Updater is not installed)");

	Format(cvarName, sizeof(cvarName), "%s_version", CONVAR_PREFIX);
	cvarVersion = CreateConVar(cvarName, PLUGIN_VERSION, "Plugin Version", FCVAR_DONTRECORD|FCVAR_CHEAT|FCVAR_NOTIFY);

	HookConVarChange(cvarEnableUpdater, CheckUpdaterStatus);
	HookConVarChange(cvarVersion, CheckUpdaterStatus);
	CheckUpdaterStatus(null, "", "");

#if defined ALL_PLUGINS_LOADED_FUNC
	ALL_PLUGINS_LOADED_FUNC();
#endif
}

public void OnLibraryAdded(const char[] name) {
	CheckUpdaterStatus(null, "", "");

#if defined LIBRARY_ADDED_FUNC
	LIBRARY_ADDED_FUNC(name);
#endif
}

public void OnLibraryRemoved(const char[] name) {
	CheckUpdaterStatus(null, "", "");

#if defined LIBRARY_REMOVED_FUNC
	LIBRARY_REMOVED_FUNC(name);
#endif
}

public void CheckUpdaterStatus(Handle convar, const char[] name, const char[] value) {
	if(cvarVersion == null) {
		return; // Version cvar not created yet
	}

	if(LibraryExists("updater") && GetConVarBool(cvarEnableUpdater)) {
		char url[512], version[12];
		Format(url, sizeof(url), "%s/%s", UPDATER_BASE_URL, UPDATE_FILE);
		Updater_AddPlugin(url); // Has no effect if we're already in Updater's pool

		Format(version, sizeof(version), "%sA", PLUGIN_VERSION);
		SetConVarString(cvarVersion, version);
	} else {
		SetConVarString(cvarVersion, PLUGIN_VERSION);
	}
}

public Action Updater_OnPluginChecking() {
	if(!GetConVarBool(cvarEnableUpdater)) {
		return Plugin_Handled;
	}
	return Plugin_Continue;
}

#if defined RELOAD_ON_UPDATE
public Updater_OnPluginUpdated() {
	ReloadPlugin();
}
#endif

error: pathspec 'scripting/include/mckayupdater.sp' did not match any file(s) known to git


Create ins_supply.sp

Create ins_supply.sp

/**
 * [INS] Supply Point Manager
 *
 * This plugin will set the supply points (tokens) for players on connect to server.
 * Will determine and give highest possible supply to player, based on settings completed.
 *
 * 0.2 = "ALPHA" Added Join and Rejoin cvars
 * 0.1 = Initial build. CVar and Token testing
*/

#include <sourcemod>

new ConVar:g_S_Enabled;
new ConVar:g_S_Base_Points;
new ConVar:g_S_Rejoin;
new ConVar:g_S_Join;
new Handle:g_S_KV_Players;

public Plugin myinfo =
{
	name = "[INS] Supply Point Manager",
	author = "GiZZoR",
	description = "Set player supply points",
	version = "0.2",
	url = "https://github.com/GiZZoR/ins-sm-plugins"
};

public void OnPluginStart()
{
	// Hook to start of round, for storing players Supply
	HookEvent("round_start", S_RoundStarted);

	// Hook (& Command) to explicitly set a player's supply points. Applies _before_ player spawns in world.
	HookEvent("player_team", Event_PlayerTeam, EventHookMode_Post);
	RegAdminCmd("sm_supply", Command_Supply, ADMFLAG_CUSTOM4,"Sets the supply points of a target");

	// "Boolean": sm_supply_enabled; Enable/disable plugin. Default: 1 (Enabled)
	g_S_Enabled = CreateConVar("sm_supply_enabled" , "1", "Sets whether the plugin is enabled", FCVAR_NONE, true, 0.0, true, 1.0);

	// "Int": sm_supply_base; Number of supply points to give players. Default: 12
	g_S_Base_Points = CreateConVar("sm_supply_base" , "12", "Base / Starting supply points", FCVAR_NONE);

	// "Boolean": sm_supply_restore; Enable/disable restoring player's gained supply points. Default: 1 (Enabled)
	g_S_Rejoin = CreateConVar("sm_supply_restore", "1", "Restore points gained by player on reconnect", FCVAR_NONE, true, 0.0, true, 1.0);

	// "Int": sm_supply_join; Enable/disable setting supply points for new players. Default: 0 (Disabled)
	// Options:
	// 0 - Disabled (Default)
	// 1 - Give new player base supply as set in sm_supply_base. Note: You may want to set this per game mode in server_<mode>.cfg
	// 2 - Give new player the same supply as lowest member in team (Useful for multiple rounds of coop play)
	// 3 - Give new player the team average of supply points (sum all players supply points divided by players)
	g_S_Join = CreateConVar("sm_supply_join", "0", "0 - Disabled; 1 - sm_supply_base; 2 - Team Lowest; 3 - Team Average", FCVAR_NONE, true, 0.0, true, 3.0);
}

// Reset stored supply values on map change
public void OnMapStart()
{
	char MapName[64];
	GetCurrentMap(MapName, sizeof(MapName));
	g_S_KV_Players = new KeyValues(MapName);
}

public Action:Command_Supply(client, args)
{
	// No arguments supplied to "sm_supply" command
	if (args < 1)
	{
		ReplyToCommand(client, "[SM] Usage: sm_supply <#userid|name>");
		return Plugin_Handled;
	}

	decl String:arg[65];
	GetCmdArg(1, arg, sizeof(arg));

	decl String:target_name[MAX_TARGET_LENGTH];
	decl target_list[MAXPLAYERS], bool:tn_is_ml;
	decl String:arg2[11];
	char Name[128];

	new target_count = ProcessTargetString(
		arg,
		client,
		target_list,
		MAXPLAYERS,
		COMMAND_FILTER_NO_MULTI,
		target_name,
		sizeof(target_name),
		tn_is_ml);

	if (target_count <= 0)
	{
		ReplyToTargetError(client, target_count);
		return Plugin_Handled;
	}

	if (args == 1)
	{
		for (new i = 0; i < target_count; i++)
		{
			new Tokens = GetEntProp(target_list[i], Prop_Send, "m_nRecievedTokens");
			GetClientName(target_list[i], Name, sizeof(Name));
			ReplyToCommand(client,"%s has %i supply points",Name, Tokens);
		}
		return Plugin_Handled;
	}

	GetCmdArg(2, arg2, sizeof(arg2));
	new supply = StringToInt(arg2);
	for (new i=0; i<target_count; ++i) {
		GetClientName(target_list[i], Name, sizeof(Name));
		SetEntProp(target_list[i], Prop_Send, "m_nRecievedTokens", supply)
		ReplyToCommand(client,"Setting supply for %s to %i",Name, supply);
	}
	return Plugin_Handled;
}

public Action:Event_PlayerTeam(Handle:event, const String:name[], bool:dontBroadcast)
{
	// If plugin is disabled, skip (sm_supply_enabled = 0)
	if(g_S_Enabled.IntValue == 0) return Plugin_Handled;

	// Get id for (re-)connecting player
	new client = GetClientOfUserId(GetEventInt(event, "userid"));

	// Get the supply points assigned by the server
	new currentTokens = GetEntProp(client, Prop_Send, "m_nRecievedTokens");
	int newTokens = 0;

	// Get player's SteamID
	char SteamID[64];
	GetClientAuthId(client, AuthId_Steam2, SteamID, sizeof(SteamID));

	// Get team player is joining
	new team = GetEventInt(event, "team");

	// Restore points on rejoin, Enabled?
	if(g_S_Rejoin.IntValue == 1)
	{
		// Is player "re-joining"?
		if(KvJumpToKey(g_S_KV_Players,SteamID,false) == true)
		{
			// Fetch player's previous supply count from KV
			newTokens = KvGetNum(g_S_KV_Players,"supply",10);
		}
	}

	// Set points for new players?
	if (g_S_Join.IntValue > 0)
	{
		if (g_S_Join.IntValue == 1) newTokens = g_S_Base_Points.IntValue;
		if (g_S_Join.IntValue == 2) newTokens = TeamLowestSupply(team,client);
		if (g_S_Join.IntValue == 3) newTokens = TeamAverageSupply(team,client);
	}
	if (newTokens > currentTokens)
	{
		SetEntProp(client, Prop_Send, "m_nRecievedTokens",newTokens);
	}
	return Plugin_Handled;
}

public Action:S_RoundStarted(Handle:event, const String:name[], bool:dontBroadcast)
{
	// Loop through all players
	for (new S_Client_Loop = 1; S_Client_Loop <= MaxClients; S_Client_Loop++) {
		if (IsClientConnected(S_Client_Loop)) {
			// Get player's Steam ID
			decl String:S_Round_SteamID[64];
			GetClientAuthId(S_Client_Loop, AuthId_Steam2, S_Round_SteamID, sizeof(S_Round_SteamID));

			// Don't track supply points of bots.
			if (StrEqual(S_Round_SteamID,"BOT",false) == false)
			{
				// Get player's team
				new team = GetClientTeam(S_Client_Loop);
				// Get player's supply points
				new supply = GetEntProp(S_Client_Loop, Prop_Send, "m_nRecievedTokens");
				// Store values in Key Value pair
				if(KvJumpToKey(g_S_KV_Players,S_Round_SteamID,true) == true)
				{
					KvSetNum(g_S_KV_Players,"team",team);
					KvSetNum(g_S_KV_Players,"supply",supply);
				}
				KvRewind(g_S_KV_Players);
			}
		}
	}
}

int TeamAverageSupply(int team, int player)
{
	new Float:TeamSupplyTotal = 0.0;
	int PlayerSupply = GetEntProp(player, Prop_Send, "m_nRecievedTokens");
	int PlayerCount = 0;
	for (new i = 1; i <= MaxClients; i++)
	{
		if(IsClientInGame(i)) {
			new S_Client_Loop_Team = GetClientTeam(i);
			if (S_Client_Loop_Team == team)
			{
				if(player != i)
				{
					int supply = GetEntProp(i, Prop_Send, "m_nRecievedTokens");
					TeamSupplyTotal = TeamSupplyTotal + float(supply);
					PlayerCount++;
				}
			}
		}
	}

	// If no players in team, return player's base supply. Avoid potential divide by 0.
	if (PlayerCount == 0) return PlayerSupply;

	new Float:TeamAverage = TeamSupplyTotal / PlayerCount;
	return RoundToFloor(TeamAverage);
}

int TeamLowestSupply(int team, int player)
{
	int TeamLowest = 0;
	for (new i = 1; i <= MaxClients; i++)
	{
		if(IsClientInGame(i)) {
			new loop_team = GetClientTeam(i);
			if (loop_team == team)
			{
				if(player != i)
				{
					int supply = GetEntProp(i, Prop_Send, "m_nRecievedTokens");
					if (TeamLowest == 0)
					{
						TeamLowest = supply;
					} else if (supply < TeamLowest) {
						TeamLowest = supply;
					}
				}
			}
		}
	}
	return TeamLowest;
}

error: pathspec 'ins_supply.sp' did not match any file(s) known to git


Fix a case where flags would be disabled mid-round


Added core downloadprefs plugin.

Added core downloadprefs plugin.

Initial commit -- fleshing out the API.

/**
 * Download Preferences
 * Author(s): nosoop
 * File:  downloadprefs.sp
 * Description:  Allows clients to select categories of files to download.
 * License:  MIT License
 */

#pragma semicolon 1

#include <sourcemod>

#define PLUGIN_VERSION          "0.1.0"

public Plugin:myinfo = {
    name = "Download Preferences",
    author = "nosoop",
    description = "Client download preferences",
    version = PLUGIN_VERSION,
    url = "http://github.com/nosoop/SM-DownloadPrefs"
}

new Handle:g_hDatabase = INVALID_HANDLE;

public OnPluginStart() {
    // TODO get database handle
    g_hDatabase = INVALID_HANDLE;
}

/**
 * Stores the SteamID (to keep track of the client) plus the IP address to track the browser.
 * Also stores the current time in the event a database pruning is desirable.
 */
public OnClientAuthorized(client, const String:auth[]) {
    if (!IsFakeClient(client)) {
        decl String:sIPAddr[20];

        new iSteamID3 = GetSteamAccountID(client);
        GetClientIP(client, sIPAddr, sizeof(sIPAddr));

        // TODO Perform fast query to store the IP address.
    }
}

/**
 * Registers a group of files to download.
 * Store the category plus description into the database if nonexistent,
 * returning an ID to the corresponding category.
 *
 * @param category          The category name to register.
 * @param description       The description associated with the category.
 * @param default           The file group is downloaded by default; clients must choose to opt-out.
 *
 * @return categoryid       The ID of the category.
 */
// _:RegClientDownloadCategory(const String:category[], const String:description[], bool:default = true);

/**
 * Registers a file to a category.
 *
 * @param categoryid        The ID of the category to register.
 * @param filepath          The full path of the file to download.
 */
// RegClientDownloadFile(id, const String:filepath[]);

/**
 * Stores the client's download preference.
 *
 * @param client            The client to set preferences for.
 * @param categoryid        The category of files to set a download preference for.
 * @param download          Whether or not the client downloads this file.
 */
// SetClientDownloadPreference(client, categoryid, bool:download);

/**
 * Retrieves a client's download preference.
 * A client will keep their existing download preference until a map change or reconnect.
 *
 * @param client            The client to get preferences for.
 * @param categoryid        The category of files to get a download preference for.
 *
 * @return                  Boolean determining if a client allows downloads from this category,
 *                          or the default allow value if the client has not set their own.
 */
// bool:GetClientDownloadPreference(client, categoryid);

/**
 * Tables to create:
 *
 * CREATE TABLE 'categories' ('categoryid' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 'categoryname' TEXT NOT NULL, 'categorydesc' INTEGER, 'enabled' BOOLEAN NOT NULL);
 * CREATE TABLE 'clients' ('sid3' INTEGER PRIMARY KEY NOT NULL, 'ipaddr' TEXT NOT NULL, 'lastconnect' INTEGER NOT NULL);
 * CREATE TABLE 'downloadprefs' ('sid3' INTEGER NOT NULL, 'categoryid' INTEGER NOT NULL, 'enabled' BOOLEAN NOT NULL);
 * CREATE TABLE 'files' ('categoryid' INTEGER, 'filepath' TEXT PRIMARY KEY NOT NULL);
 */

 /**
  * Flow to check if a download is allowed.
  * When a client is authorized: -> Update IP, SteamID3, lastconnect in table clients
  * When a client downloads a file: ->
  *   - Get SteamID3 from the associated IP address in table clients,   (redirect / 404 if not found)
  *   - Get 'categoryid' by 'filepath' in table files (filepath obtained in query string),
  *   - Get 'enabled' by 'sid3' and 'category' in downloadprefs,
  *   - (If not found, get 'enabled' by 'categoryid' in table categories),
  *   - If enabled, allow the download, otherwise redirect / 404.
  */

error: pathspec 'scripting/downloadprefs.sp' did not match any file(s) known to git


Added files via upload

Added files via upload

For tracking projectile speeds. Still need to implement RA5.

#include <sdktools>
#include <sdkhooks>

public Plugin:myinfo =
{
  name = "Entity speed tracker",
  author = "darkid",
  description = "Calculates the speed of a moving entity. Primarily used for http://wiki.tf/Projectiles",
  version = "1.3",
}

// XYZ position for each entity.
new Float:lastPosition[2048][3];
// Prevent
new bool:doubleHookCall[2048];

public OnEntityCreated(entity, const String:classname[]) {
  if (
  // Mad Milk
   	StrEqual(classname, "tf_projectile_jar_milk") ||
  // Sandman
   	StrEqual(classname, "tf_projectile_stun_ball") ||
  // Wrap Assassin
  	StrEqual(classname, "tf_projectile_ball_ornament") ||
  // All rocket launchers, Monoculus
  	StrEqual(classname, "tf_projectile_rocket") ||
  // All flame throwers
  	StrEqual(classname, "tf_flame") ||
  // Flare Gun and Detonator
  	StrEqual(classname, "tf_projectile_flare") ||
  // All grenade launchers
  	StrEqual(classname, "tf_projectile_pipe") ||
  // All stickybomb launchers
  	StrEqual(classname, "tf_projectile_pipe_remote") ||
  // Sandvich, Buffalo Steak Sandvich
  	StrEqual(classname, "item_healthkit_medium") ||
  // Dalokohs Bar, Fishcake
  	StrEqual(classname, "item_healthkit_small") ||
  // Rescue Ranger
  	StrEqual(classname, "tf_projectile_arrow") ||
  // Sentry Gun rockets
  	StrEqual(classname, "tf_projectile_sentryrocket") ||
  // Crusader's Crossbow
  	StrEqual(classname, "tf_projectile_syringe") ||
  // Any syringe gun
  	StrEqual(classname, "tf_projectile_healing_bolt") ||
  // Huntsman
  	StrEqual(classname, "tf_projectile_arrow") ||
  // Jarate
  	StrEqual(classname, "tf_projectile_jar")
  ) {
    // Wait for the projectile to finish spawning
    SDKHook(entity, SDKHook_Spawn, ProjectileSpawned);
  }
}

public ProjectileSpawned(entity) {
  if (doubleHookCall[entity]) return;
  doubleHookCall[entity] = true;
  GetEntPropVector(entity, Prop_Send, "m_vecOrigin", lastPosition[entity]);
  // Two game frames
  CreateTimer(0.3, GetSpeed, entity, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
}

public Action:GetSpeed(Handle:timer, any:entity) {
  doubleHookCall[entity] = false;
  if (!IsValidEntity(entity)) return Plugin_Stop;
  decl Float:position[3];
  GetEntPropVector(entity, Prop_Send, "m_vecOrigin", position);
  // Ignore Z axis movement to avoid the influence of gravity
  new Float:norm = Pow(position[0]-lastPosition[entity][0], 2.0)+Pow(position[1]-lastPosition[entity][1], 2.0);
  lastPosition[entity] = position;
  for (new client = 1; client <= MaxClients; client++) {
    if (!IsClientInGame(client)) continue;
    if (IsFakeClient(client)) continue;
    PrintToChat(client, "%d: %f hu/s", entity, SquareRoot(norm) / 0.3);
  }
  return Plugin_Continue;
}

error: pathspec 'projectile_speed.sp' did not match any file(s) known to git


rebuilded update plugin

rebuilded update plugin

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/vem882/s7.git/'


Update ConVar definitions

Update ConVar definitions


理想的なダイオードのあれ

理想的なダイオードのあれ

* ex3_diode.sp
.options post temp=27
.MODEL Default D

v1 in 0 dc 10v
d1 in out Default
r1 out 0 27

.control
dc v1 -10 10 0.2m
.endc

.tran 1n 400n
.end

error: pathspec 'ex3_diode.sp' did not match any file(s) known to git


Fix invalid reference to reactor cores on map change


Bugfix: Do not send Enable inputs to carried flags


Prevent players from being stunned immediately after spawning


It says new syntax but isnt

It says new syntax but isnt

Push of weapon sounds

#pragma semicolon 1

#include <sourcemod>
#include <sdktools>
//#undef REQUIRE_PLUGIN
#include <multicolors>
#include <clientprefs>

#define PLUGIN_NAME 	"Toggle Weapon Sounds clientprefs"
#define PLUGIN_VERSION 	"1.0.3 fix m_iWeaponID + new syntax"

//#define UPDATE_URL	"http://godtony.mooo.com/stopsound/stopsound.txt"

bool g_bStopSound[MAXPLAYERS+1]; bool g_bHooked;

Handle g_hClientCookie = INVALID_HANDLE;

public Plugin myinfo =
{
	name = PLUGIN_NAME,
	author = "GoD-Tony",
	description = "Allows clients to stop hearing weapon sounds",
	version = PLUGIN_VERSION,
	url = "http://www.sourcemod.net/"
};

public OnPluginStart()
{
	LoadTranslations("common.phrases");

	g_hClientCookie = RegClientCookie("sm_weaponsound", "Toggle hearing weapon sounds", CookieAccess_Private);
	//SetCookiePrefabMenu(g_hClientCookie, CookieMenu_OnOff_Int, "Toggle Weapon Sounds", StopSoundCookieHandler);
	SetCookieMenuItem(StopSoundCookieHandler, g_hClientCookie, "Toggle Weapon Sounds");

	// Detect game and hook appropriate tempent.
	char sGame[32];
	GetGameFolderName(sGame, sizeof(sGame));

	if (StrEqual(sGame, "cstrike") || StrEqual(sGame, "csgo"))
		AddTempEntHook("Shotgun Shot", CSS_Hook_ShotgunShot);
	else if (StrEqual(sGame, "dod"))
		AddTempEntHook("FireBullets", DODS_Hook_FireBullets);

	// TF2/HL2:DM and misc weapon sounds will be caught here.
	AddNormalSoundHook(Hook_NormalSound);

	CreateConVar("sm_stopsound_version", PLUGIN_VERSION, "Toggle Weapon Sounds", FCVAR_NOTIFY|FCVAR_DONTRECORD);
	RegConsoleCmd("sm_stopsound", Command_StopSound, "Toggle hearing weapon sounds");

	// Updater.
	//if (LibraryExists("updater"))
	//{
	//	Updater_AddPlugin(UPDATE_URL);
	//}

	for (new i = 1; i <= MaxClients; ++i)
	{
		if (!AreClientCookiesCached(i))
		{
			continue;
		}

		OnClientCookiesCached(i);
	}
}

/*
public OnLibraryAdded(const String:name[])
{
	if (StrEqual(name, "updater"))
	{
		Updater_AddPlugin(UPDATE_URL);
	}
}
*/

public StopSoundCookieHandler(client, CookieMenuAction:action, any:info, char []buffer, maxlen)
{
	switch (action)
	{
		case CookieMenuAction_DisplayOption:
		{
		}

		case CookieMenuAction_SelectOption:
		{
			if(CheckCommandAccess(client, "sm_stopsound", 0))
			{
				PrepareMenu(client);
			}
			else
			{
				ReplyToCommand(client, "[SM] You have no access!");
			}
		}
	}
}

PrepareMenu(client)
{
	Menu menu = new Menu(YesNoMenu, MENU_ACTIONS_DEFAULT|MenuAction_DrawItem|MenuAction_DisplayItem|MenuAction_Display);
	menu.SetTitle("Weapon Sounds -> ");
	menu.AddItem("0", "On");
	menu.AddItem("1", "Off");
	menu.ExitButton = true;
	menu.Display(client, 20);
}

public int YesNoMenu(Menu menu, MenuAction action, int param1, int param2)
{
	switch(action)
	{
		case MenuAction_DrawItem:
		{
			//PrintToServer("MenuAction_DrawItem");
			if(_:g_bStopSound[param1] == param2)
			{
				//return ITEMDRAW_DISABLED;
				return ITEMDRAW_SPACER;
			}
		}
		case MenuAction_DisplayItem:
		{
			//PrintToServer("MenuAction_DisplayItem");
			// Translate
			char dispBuf[50];
			GetMenuItem(menu, param2, "", 0, _, dispBuf, sizeof(dispBuf));
			Format(dispBuf, sizeof(dispBuf), "%T", dispBuf, param1);
			return RedrawMenuItem(dispBuf);
		}
		case MenuAction_Display:
		{
			//PrintToServer("MenuAction_Display");
			char buffer[100];
			GetMenuTitle(menu, buffer, sizeof(buffer));
			Format(buffer, sizeof(buffer), "%s : %T", buffer, g_bStopSound[param1] ? "Off":"On", param1);
			SetMenuTitle(menu, buffer);
		}
		case MenuAction_Select:
		{
			// Can still choose menu option using console cmd "menuselect" "1", lets recheck
			// Or cvar change in this moment before player choose option

			//PrintToServer("MenuAction_Select");
			char info[50];
			if( GetMenuItem(menu, param2, info, sizeof(info)) )
			{
				SetClientCookie(param1, g_hClientCookie, info);
				g_bStopSound[param1] = StringToInt(info) != 0;
				CPrintToChat(param1, "{GREEN}[{BLUE}Weapons{GREEN}] {OLIVE}Sound from other players guns is now {RED}%s.", g_bStopSound[param1] ? "Off" : "On");
				CheckHooks();
				PrepareMenu(param1);
			}
		}
		case MenuAction_Cancel:
		{
			//PrintToServer("MenuAction_Cancel");
			if( param2 == MenuCancel_Exit ) // Exit go back !settings
			{
				ShowCookieMenu(param1);
			}
		}
		case MenuAction_End:
		{
			//PrintToServer("MenuAction_End");
			CloseHandle(menu);
		}
	}

	return 0;
}

public OnClientCookiesCached(client)
{
	char sValue[8];
	GetClientCookie(client, g_hClientCookie, sValue, sizeof(sValue));

	g_bStopSound[client] = (sValue[0] != '\0' && StringToInt(sValue));
	CheckHooks();
}

public Action Command_StopSound(client, args)
{
	if(AreClientCookiesCached(client))
	{
		PrepareMenu(client);
	}
	else
	{
		ReplyToCommand(client, "[SM] Your Cookies are not yet cached. Please try again later...");
	}
	//g_bStopSound[client] = !g_bStopSound[client];
	//ReplyToCommand(client, "[SM] Weapon sounds %s.", g_bStopSound[client] ? "disabled" : "enabled");
	//CheckHooks();

	return Plugin_Handled;
}

public OnClientDisconnect_Post(client)
{
	g_bStopSound[client] = false;
	CheckHooks();
}

CheckHooks()
{
	bool bShouldHook = false;

	for (new i = 1; i <= MaxClients; i++)
	{
		if (g_bStopSound[i])
		{
			bShouldHook = true;
			break;
		}
	}

	// Fake (un)hook because toggling actual hooks will cause server instability.
	g_bHooked = bShouldHook;
}

public Action Hook_NormalSound(clients[64], &numClients, char sample[PLATFORM_MAX_PATH], &entity, &channel, &Float:volume, &level, &pitch, &flags)
{
	// Ignore non-weapon sounds.
	//if (!g_bHooked || !(strncmp(sample, "weapons", 7) == 0 || strncmp(sample[1], "weapons", 7) == 0))
	// PrintToServer("[Weapon] playing sample %s.", sample);
	if (!g_bHooked || StrContains(sample, "weapon", false) == -1)
		return Plugin_Continue;

	int i, j;

	for (i = 0; i < numClients; i++)
	{
		if (g_bStopSound[clients[i]])
		{
			// Remove the client from the array.
			for (j = i; j < numClients-1; j++)
			{
				clients[j] = clients[j+1];
			}

			numClients--;
			i--;
		}
	}

	return (numClients > 0) ? Plugin_Changed : Plugin_Stop;
}

public Action CSS_Hook_ShotgunShot(const char []te_name, const Players[], numClients, float delay)
{
	if (!g_bHooked)
		return Plugin_Continue;

	// Check which clients need to be excluded.
	decl newClients[MaxClients], client, i;
	int newTotal = 0;

	for (i = 0; i < numClients; i++)
	{
		client = Players[i];

		if (!g_bStopSound[client])
		{
			newClients[newTotal++] = client;
		}
	}

	// No clients were excluded.
	if (newTotal == numClients)
		return Plugin_Continue;

	// All clients were excluded and there is no need to broadcast.
	else if (newTotal == 0)
		return Plugin_Stop;

	// Re-broadcast to clients that still need it.
	float vTemp[3];
	TE_Start("Shotgun Shot");
	TE_ReadVector("m_vecOrigin", vTemp);
	TE_WriteVector("m_vecOrigin", vTemp);
	TE_WriteFloat("m_vecAngles[0]", TE_ReadFloat("m_vecAngles[0]"));
	TE_WriteFloat("m_vecAngles[1]", TE_ReadFloat("m_vecAngles[1]"));
	TE_WriteNum("m_weapon", TE_ReadNum("m_weapon"));
	TE_WriteNum("m_iMode", TE_ReadNum("m_iMode"));
	TE_WriteNum("m_iSeed", TE_ReadNum("m_iSeed"));
	TE_WriteNum("m_iPlayer", TE_ReadNum("m_iPlayer"));
	TE_WriteFloat("m_fInaccuracy", TE_ReadFloat("m_fInaccuracy"));
	TE_WriteFloat("m_fSpread", TE_ReadFloat("m_fSpread"));
	TE_Send(newClients, newTotal, delay);

	return Plugin_Stop;
}

public Action DODS_Hook_FireBullets(const char []te_name, const Players[], numClients, float delay)
{
	if (!g_bHooked)
		return Plugin_Continue;

	// Check which clients need to be excluded.
	decl newClients[MaxClients], client, i;
	int newTotal = 0;

	for (i = 0; i < numClients; i++)
	{
		client = Players[i];

		if (!g_bStopSound[client])
		{
			newClients[newTotal++] = client;
		}
	}

	// No clients were excluded.
	if (newTotal == numClients)
		return Plugin_Continue;

	// All clients were excluded and there is no need to broadcast.
	else if (newTotal == 0)
		return Plugin_Stop;

	// Re-broadcast to clients that still need it.
	float vTemp[3];
	TE_Start("FireBullets");
	TE_ReadVector("m_vecOrigin", vTemp);
	TE_WriteVector("m_vecOrigin", vTemp);
	TE_WriteFloat("m_vecAngles[0]", TE_ReadFloat("m_vecAngles[0]"));
	TE_WriteFloat("m_vecAngles[1]", TE_ReadFloat("m_vecAngles[1]"));
	TE_WriteNum("m_weapon", TE_ReadNum("m_weapon"));
	TE_WriteNum("m_iMode", TE_ReadNum("m_iMode"));
	TE_WriteNum("m_iSeed", TE_ReadNum("m_iSeed"));
	TE_WriteNum("m_iPlayer", TE_ReadNum("m_iPlayer"));
	TE_WriteFloat("m_flSpread", TE_ReadFloat("m_flSpread"));
	TE_Send(newClients, newTotal, delay);

	return Plugin_Stop;
}

error: pathspec 'scripting/toggle_weapon_sounds_clientprefs.sp' did not match any file(s) known to git


added posc3

added posc3

_s 1024 gen_sine

440 0.5 _s posc3

# compared to the default oscillator, the aliasing is way lower!
# 440 0.5 0 _s osc

error: pathspec 'examples/posc3.sp' did not match any file(s) known to git


Timertest is cool test

Timertest is cool test

How to learn: do

/*
* What we learn from this: delete may not be used in a timer's callback. instead, just set the timer to null there.
* Make sure to null timers at the end if they are saved in a global variable. Some say you should null it at the
*	beginning of your "closing" statements within the timer callback, and I would agree as it saves us from
*	accidentally tripping in case our code glitches (do timer = null; PrintToServer("finish"); instead of the reverse.
* return Plugin_Stop to end a repeating timer, dont try and close its handle or randomly delete it or something.
* Our SMTimer methodmap is equivalent to an actual timer in every way.
*/

#include <sourcemod>
#include <ngsutils>

SMTimer timer3, timer4, timer6, timer8;
Handle nontimer, timer1, timer2, timer5, timer7;
int timer7iter = 0, timer8iter = 0;

public void OnPluginStart() {
    nontimer = new ArrayList();
    timer1 = CreateTimer(0.1, timer1func);
    timer2 = CreateTimer(0.1, timer2func);
    timer3 = new SMTimer(0.1, timer3func);
    timer4 = new SMTimer(0.1, timer4func);
    timer5 = CreateTimer(0.1, timer5func);
    timer6 = new SMTimer(0.1, timer6func);
    timer7 = CreateTimer(0.1, timer7func, _, TIMER_REPEAT);
    timer8 = new SMTimer(0.1, timer8func, _, TIMER_REPEAT);
    PrintToServer("%i, %i, %i, %i, %i, %i, %i, %i, %i", nontimer, timer1, timer2, timer3, timer4, timer5, timer6, timer7, timer8);
    delete nontimer;
    delete timer1;
    //delete timer2;
    delete timer3;
    //delete timer4;
    // timer5 and timer6 are nulled within the callback.
    delete timer7;
    //delete timer8;
    PrintToServer("%i, %i, %i, %i, %i, %i, %i, %i, %i", nontimer, timer1, timer2, timer3, timer4, timer5, timer6, timer7, timer8);
    SMTimer checktimer = new SMTimer(1.0, checktimerfunc);
}

public Action timer1func(Handle timer) {
    PrintToServer("Deleted Handle timer1 shows up!");
}

public Action timer2func(Handle timer) {
    PrintToServer("Non-Deleted Handle timer2 shows up!");
}

public Action timer3func(Handle timer) {
    PrintToServer("Deleted SMTimer timer3 shows up!");
}

public Action timer4func(Handle timer) {
    PrintToServer("Non-Deleted SMTimer timer4 shows up!");
}

public Action timer5func(Handle timer) {
    PrintToServer("In Non-delete Handle timer5. Nulling!");
    timer5 = null;
}

public Action timer6func(Handle timer) {
    PrintToServer("In Non-delete SMTimer timer6. Nulling!");
    timer6 = null;
}

public Action timer7func(Handle timer) {
    PrintToServer("In Deleted repeating Handle timer7. Iteration %d!", timer7iter);
    if (timer7iter > 5)
    {
        PrintToServer("In Deleted repeating Handle timer7. Nulling!");
        timer7 = null;
        return Plugin_Stop;
    }
    timer7iter++;
    return Plugin_Continue;
}

public Action timer8func(Handle timer) {
    PrintToServer("In Non-delete repeating SMTimer timer8. Iteration %d!", timer8iter);
    if (timer8iter > 5)
    {
        PrintToServer("In Non-delete repeating SMTimer timer8. Nulling!");
        timer8 = null;
        return Plugin_Stop;
    }
    timer8iter++;
    return Plugin_Continue;
}

public Action checktimerfunc(Handle timer) {
    PrintToServer("After all types of timers are dead:");
    PrintToServer("%i, %i, %i, %i, %i, %i, %i, %i, %i", nontimer, timer1, timer2, timer3, timer4, timer5, timer6, timer7, timer8);
}

error: pathspec 'scripting/TESTPLUGINSPLEASEIGNORE/TIMERTEST.sp' did not match any file(s) known to git


more stuff for diode

more stuff for diode

(
_seq "0 3 -7 -2" gen_vals
_seq2 "0 2 3 7 9 10 12" gen_vals
_clk var
_dry var
_ping var
_bpm 135 varset
0 _bpm get 4 clock _clk set

_clk get 0 _seq tseq 40 + _clk get 0.3 maygate 12 * +
_clk get 0.6 maygate 0.002 0.01 branch port mtof 0.7 saw
30 inv 1 sine 300 3000 biscale 0.75 0.96 (0.1 1 1 randh) randi diode
2 0.3 0.2 0.01 dist
_clk get 0.005 10 inv 1 sine 0.01 0.1 biscale 0.1 tenvx *

# Square leads
_clk get 4 0 tdiv 0.2 maytrig _clk get dup 3 0 tdiv switch
1 _seq2 tseq 62 + dup
mtof 0.015 (0.005 0.5 2 jitter) + port 0.2 0.1 square
swap 12.1 - mtof 0.02 port 0.2 0.2 square + 35 inv 1 sine 500 1000 biscale butlp
_clk get 16 0 tdiv 0.8 maygate 0.1 port * 200 buthp -8 ampdb *
+

# ping

_clk get 0.02 maytrig 0.001 0.005 0.01 tenvx 74 mtof 0.1 1
_clk get 0 7 trand floor 1 fm *
dup _ping set +

_dry set

_dry get 500 buthp dup 0.91 8000 revsc drop -10 ampdb *
_dry get 1000 buthp _ping get +  0.7 _bpm get bpm2dur 0.75 *  delay 1000 butlp +

_dry get +
dup
)

(
_seq "0 3 -7 -2" gen_vals
_clk var
_dry var
_bpm 135 varset
0 _bpm get 4 clock _clk set

_clk get 0 _seq tseq 40 + _clk get 0.3 maygate 12 * +
_clk get 0.6 maygate 0.002 0.01 branch port mtof 0.8 saw
30 inv 1 sine 300 3000 biscale 0.75 0.96 (0.1 1 1 randh) randi diode
2 0.3 0.1 0.0 dist
_clk get 0.001 0.1 0.1 tenvx *

_dry set

_dry get 500 buthp dup 0.91 8000 revsc drop -10 ampdb *
_dry get 1000 buthp 0.7 _bpm get bpm2dur 0.75 *  delay 1000 butlp +

_dry get +
)


Upload RegenerateHealth source file

Upload RegenerateHealth source file

#include <sourcemod>
#include <sdkhooks>
#include <sdktools>

#pragma semicolon 1
#pragma newdecls required

public Plugin myinfo = {
		name			= "[INS] Regenerate health",
		author		  = "rrrfffrrr",
		description	 = "Regenerate player health",
		version		 = "1.0.0",
		url			 = ""
};

Handle hPlayerRegenerationTimer[MAXPLAYERS + 1];

#define MAX_LIMIT 10
int iLimits[MAX_LIMIT];
int iNumOfLimit;

int iPlayerLimit[MAXPLAYERS + 1];

ConVar ConVarRegenerationDelay;
ConVar ConVarRegenerationInterval;
ConVar ConVarRegenerationHeal;
ConVar ConVarRegenerationLimit;

public void OnPluginStart() {
	InitConVar();
	HookConVar();

	OnChangeLimit(ConVarRegenerationLimit, "", "80 20");
	HookEvent("player_death", Event_PlayerDeath);
}

public void OnClientPutInServer(int client) {
	if (IsValidPlayer(client))
		SDKHook(client, SDKHook_OnTakeDamagePost, Event_OnTakeDamagePost);
}

public void OnClientDisconnect_Post(int client) {
	StopRegenerate(client);
}

void Event_OnTakeDamagePost(int victim, int attacker, int inflictor, float damage, int damagetype) {
	if (IsValidPlayer(victim)) {
		StartRegenerate(victim);
	}
}

void InitConVar() {
	ConVarRegenerationDelay = CreateConVar("sm_rhealth_delay", "5", "Delay before start to regenerate.", FCVAR_NOTIFY, true, 0.0);
	ConVarRegenerationInterval = CreateConVar("sm_rhealth_interval", "0.2", "Interval on each heal.", FCVAR_NOTIFY, true, 0.05);
	ConVarRegenerationHeal = CreateConVar("sm_rhealth_heal", "1", "Heal num on each interval.", FCVAR_NOTIFY, true, 0.01);
	ConVarRegenerationLimit = CreateConVar("sm_rhealth_limit", "80 20", "Maximum of regeneration.", FCVAR_NOTIFY);
}

void HookConVar() {
	HookConVarChange(ConVarRegenerationLimit, OnChangeLimit);
}

void OnChangeLimit(ConVar convar, const char[] oldValue, const char[] newValue) {
	char explode[MAX_LIMIT][4];
	iNumOfLimit = ExplodeString(newValue, " ", explode, MAX_LIMIT, sizeof(explode[]));
	for(int i = 0; i < MAX_LIMIT; ++i) {
		if (i < iNumOfLimit)
			iLimits[i] = StringToInt(explode[i]);
		else
			iLimits[i] = 0;
	}
	SortIntegers(iLimits, iNumOfLimit, Sort_Ascending);
}

Action Event_PlayerDeath(Event event, const char[] name, bool dontBroadcast) {
	int client = GetClientOfUserId(event.GetInt("userid"));
	StopRegenerate(client);
	return Plugin_Continue;
}

void StartRegenerate(int client) {
	if (!IsValidPlayer(client) || !IsPlayerAlive(client))
		return;

	if (hPlayerRegenerationTimer[client] != INVALID_HANDLE)
		KillTimer(hPlayerRegenerationTimer[client]);
	hPlayerRegenerationTimer[client] = CreateTimer(ConVarRegenerationDelay.FloatValue, Timer_Delay, client, TIMER_FLAG_NO_MAPCHANGE);

	int health = GetEntProp(client, Prop_Send, "m_iHealth", 4);
	int limit = MAX_LIMIT;
	for(int i = 0; i < iNumOfLimit; ++i) {
		if (health <= iLimits[i])
			limit = i;
		else
			break;
	}
	iPlayerLimit[client] = limit + 1;
}

void StopRegenerate(int client) {
	if (hPlayerRegenerationTimer[client] != INVALID_HANDLE)
		KillTimer(hPlayerRegenerationTimer[client]);
	hPlayerRegenerationTimer[client] = INVALID_HANDLE;
}

Action Timer_Delay(Handle timer, int client) {
	hPlayerRegenerationTimer[client] = INVALID_HANDLE;
	if (!IsValidPlayer(client) || !IsPlayerAlive(client))
		return Plugin_Stop;

	HealPlayer(client, ConVarRegenerationHeal.FloatValue);
	hPlayerRegenerationTimer[client] = CreateTimer(ConVarRegenerationInterval.FloatValue, Timer_Heal, client, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
	return Plugin_Stop;
}

Action Timer_Heal(Handle timer, int client) {
	if (!IsValidPlayer(client) || !IsPlayerAlive(client)) {
		StopRegenerate(client);
		return Plugin_Stop;
	}

	HealPlayer(client, ConVarRegenerationHeal.FloatValue);
	return Plugin_Continue;
}

void HealPlayer(int client, float heal) {
	int max = GetEntProp(client, Prop_Send, "m_iMaxHealth", 4);
	if (iPlayerLimit[client] < MAX_LIMIT) {
		int limit = iLimits[iPlayerLimit[client]];
		max = (max > limit) ? limit : max;
	}
	float health = view_as<float>(GetEntProp(client, Prop_Send, "m_iHealth", 4));
	health += heal;
	if (health > max) {
		health = view_as<float>(max);
		StopRegenerate(client);
	}
	SetEntProp(client, Prop_Send, "m_iHealth", RoundToCeil(health), 4);
}

bool IsValidPlayer(int client) {
	if (client < 1 || client > MaxClients)
		return false;

	if (!IsClientInGame(client))
		return false;

	return true;
}

error: pathspec 'scripting/RegenerateHealth.sp' did not match any file(s) known to git


Version bump (2.0.0-alpha → 2.0.0-beta)

Version bump (2.0.0-alpha → 2.0.0-beta)


added simple sequencer example

added simple sequencer example

# A trivial sequencer
# Create a table of values,
# These do not get pushed to the stack
"seq" "60 62 64 67" gen_vals
# create a metronome at 3Hz, and
# duplicate its signal
3 metro
# stack: metro
# duplicate the last (only) item on stack
dup
# stack: metro metro
# A simple trigger based envelope generator
# This pops off the metro value from
# the stack.
0.01 0.1 0.1 tenv
# stack: metro tenv
# swap last two values pushed on the stack
swap
# stack: tenv metro
# reads a value from the table "seq"
# This pops off the metro value
# from the stack.
0 "seq" tseq
# stack: tenv tseq
# pops last value from the stack, and applies
# a MIDI to frequency conversion
mtof
# stack: tenv mtof
# pops last value from the stack, and uses
# it as the frequency for the sine wave
0.5 sine
# stack: tenv sine
# pops two values from the stack, and
# multiplies them together
mul
# stack: (nothing, as it should be)
# If this were non-zero, we would run
# into stack-overflow issues.

error: pathspec 'examples/seq.sp' did not match any file(s) known to git


Readd mckayupdater, sorry McKay :)

Readd mckayupdater, sorry McKay :)


Extend the RSpec resources of Puppetshow::execute

It adds a resource file in order to test that the runtime errors are
handled.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/ludokng/puppetshow.git/'


Create xmldata.sp

Create xmldata.sp

/**
 * 0.1 = Initial build
*/

#include <sourcemod>
#include <sdktools>

public Plugin myinfo =
{
        name = "[INS] XML Data",
        author = "GiZZoR",
        description = "XML Server Data",
        version = "0.1",
        url = "http://www.sourcemod.net/"
};

public void OnPluginStart()
{
        RegServerCmd("xml_write", Write_XML);
        RegServerCmd("ent_debug", Ent_Loop_Find);
}

public Action Ent_Loop_Find(int args)
{
        decl String:className[35];
        for (new i = 1; i <= MaxClients; i++) {
                if (IsClientConnected(i)) {
                        GetEntityClassname(i, className, sizeof(className));
                        PrintToServer("%s",className);
                }
        }
}

public Action Write_XML(int args)
{
        // Prep variables
        new String:path[PLATFORM_MAX_PATH];
        char SteamID[64];
        char Name[128];
        char MapName[64];
        char ServerName[256];
        new String:sGameMode[32];

        // Open file handle
        BuildPath(Path_SM,path,PLATFORM_MAX_PATH,"server-data.xml");
        new Handle:FileHandle = OpenFile(path,"w");

        new Handle:hHostName = FindConVar("hostname");
        GetConVarString(hHostName, ServerName, sizeof(ServerName));
//ins_bot_difficulty
        GetCurrentMap(MapName, sizeof(MapName));

        GetConVarString(FindConVar("mp_gamemode"), sGameMode, sizeof(sGameMode));

        WriteFileLine(FileHandle,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        WriteFileLine(FileHandle,"<root>");
        WriteFileLine(FileHandle,"\t<servername>%s</servername>",ServerName);
        WriteFileLine(FileHandle,"\t<map>\n\t\t<name>%s</name>\n\t\t<mode>%s</mode>\n\t</map>",MapName,sGameMode);
        WriteFileLine(FileHandle,"\t<players>");
        for (new i = 1; i <= MaxClients; i++) {
                if (IsClientConnected(i)) {
                        GetClientName(i, Name, sizeof(Name));
                        GetClientAuthId(i, AuthId_Steam2, SteamID, sizeof(SteamID));
                        WriteFileLine(FileHandle,"\t\t<player>\n\t\t\t<name>%s</name>\n\t\t\t<steamid>%s</steamid>\n\t\t</player>",Name,SteamID);
                }
        }
        WriteFileLine(FileHandle,"\t</players>");
        WriteFileLine(FileHandle,"</root>");
        CloseHandle(FileHandle);
}

error: pathspec 'xmldata.sp' did not match any file(s) known to git


added timer example

added timer example

# a simple clock divider example

# subdivisions
_s '2 3 4 6 8 16' gen_vals

# master clock
135 bpm2dur dmetro

# randomized frequency
dup 300 1000 trand

# FM synth
0.4 1 1 1 fm

# bring back the clock
swap

# send a copy of the signal into the timer
dup timer
# swap, and send into tseq, then to dmetro
swap 1 _s tseq /
dmetro

# send new dmetro clock into exponential envelope
0.001 0.01 0.1  tenvx *

error: pathspec 'examples/timer.sp' did not match any file(s) known to git


Override win panel "reset" behavior when playing to a winlimit


Add while.sp

Add while.sp

int foo;
int bar;

foo = 0;
bar = 10;

while (foo < bar) {
	print(foo);
	foo = foo + 1;
};

while (foo < bar) {
	print(foo);
};

while (foo < bar)
	print(foo);

print(bar);

error: pathspec 'test/data/while.sp' did not match any file(s) known to git


fist command

fist command

#include <sdktools>
#include <sourcemod>
#define VERSION "1.0"

//-------------------------------------------------------------------------------------------------
public Plugin myinfo = {
	name = "spy crab event",
	author = "caty",
	description = "Use this command to start a spycrab event.",
	version = VERSION,
	url = "matespastdates.servegame.com"
};

public void OnPluginStart()
{
	RegConsoleCmd("sm_spycrab_red", cmd_spycrab_blu, "starts and ends a spycrab");
	RegConsoleCmd("sm_spycrab_blu", cmd_spycrab_red, "starts and end a spycrab" )
}

public Action cmd_spycrab_red(client, args)
{
	if(client == 0 || !IsClientInGame(client) || GetClientTeam(client) <= 1 || !IsPlayerAlive(client))
	{
		ReplyToCommand(client, "[SM] Event: You must be alive to start this event.");
		return Plugin_Handled;
	}

	if(GetClientTeam(client) <= 2)
	{

	float spy_redorigin[3];
	spy_redorigin[0] = 3096.031250;
	spy_redorigin[1] = 1970.062744;
	spy_redorigin[2] = 651.031311;

	TeleportEntity(client, spy_redorigin, NULL_VECTOR, NULL_VECTOR);

	return Plugin_Handled;
	}
}

public Action cmd_spycrab_blu(client, args)
{
	if(client == 0 || !IsClientInGame(client) || GetClientTeam(client) <= 1 || !IsPlayerAlive(client))
	{
		ReplyToCommand(client, "[SM] Event: You must be alive to start this event.");
		return Plugin_Handled;
	}
	if(GetClientTeam(client) <= 0)
	{

	float spyorigin[3];
	spyorigin[0] = 3099.921143;
	spyorigin[1] = 1179.364258;
	spyorigin[2] = 651.031311;

	TeleportEntity(client, spyorigin, NULL_VECTOR, NULL_VECTOR);

	return Plugin_Handled;
	}
}

error: pathspec 'mpd_spycrab.sp' did not match any file(s) known to git


Add a new resource for Cucumber

Add a new resource for Cucumber

This new resource is used to test that an error is raised when the value
of the name clause does not match the name of the file.


added demo.sp

added demo.sp

# Create buffer with length 80000 samples
'buf' 80000 zeros

# Create a sequence
'seq' '0 2 7 11 14 4 2' gen_vals

# our maygate clock with a guaranteed start
tick 1 metro 0.7 maytrig +
# duplicate the clock signal for tseq and pluck
dup

# sequence through the table
0 'seq' tseq
# bias 61 (Db major) and convert to frequency for pluck
61 + mtof
0.5 400 pluck 1000 butlp

# delayz for dayz
dup 0.6 0.75 delay 1000 buthp 0.7 * +

# reverb
dup dup 10 10 8000 zrev 0.5 * drop +

# duplicate our entire signal and record it in buffer
dup 3 p * swap tick 'buf' tblrec

# mincer object shuffles through recording buffer
0 'buf' tbldur
1 p randi 1
0 p 'buf' mincer 2 p *

# Sum mincer with everything else
+

error: pathspec 'pd/demo.sp' did not match any file(s) known to git


New plugin: Bot Respawn

New plugin: Bot Respawn

#include <sourcemod>
#include <sdktools>
#include <insurgency>

#define PLUGIN_VERSION "0.1"

new Handle:gH_Enabled = INVALID_HANDLE;
new Handle:gH_Time = INVALID_HANDLE;
new Handle:gH_Timer = INVALID_HANDLE;
new Handle:gH_GameConfig = INVALID_HANDLE;
new Handle:gH_PlayerRespawn;
new bool:gB_Enabled;
new Float:gF_Time;

public Plugin:myinfo =
{
	name = "[INS] Bot Respawn",
	author = "GiZZoR",
	description = "Timed respawn of bots",
	version = PLUGIN_VERSION
}

public OnPluginStart()
{
	CreateConVar("sm_bot_respawn_version", PLUGIN_VERSION, "[INS] Bot Respawn version", FCVAR_NOTIFY|FCVAR_PLUGIN|FCVAR_DONTRECORD);

	gH_Enabled = CreateConVar("sm_bot_respawn_enabled", "1", "Bot Respawn enabled?", FCVAR_PLUGIN, true, 0.0, true, 1.0);
	gH_Time = CreateConVar("sm_bot_respawn_time", "60.0", "Time to wait before respawning bots.", FCVAR_PLUGIN, true, 0.0, true, 240.0);

	gB_Enabled = GetConVarBool(gH_Enabled);
	gF_Time = GetConVarFloat(gH_Time);

	HookConVarChange(gH_Enabled, ConVarChanged);
	HookConVarChange(gH_Time, ConVarChanged);

	HookEvent("round_start", HookStart);
	HookEvent("round_end", HookEnd);
	HookEvent("object_destroyed", HookObjectDestroyed, EventHookMode_Post);
	HookEvent("controlpoint_captured", HookControlPointCaptured, EventHookMode_Post);

	gH_GameConfig = LoadGameConfigFile("plugin.respawn");
	if (gH_GameConfig == INVALID_HANDLE) {
		SetFailState("Fatal Error: Missing File \"plugin.respawn\"!");
	}
	StartPrepSDKCall(SDKCall_Player);
	PrepSDKCall_SetFromConf(gH_GameConfig, SDKConf_Signature, "ForceRespawn");

	gH_PlayerRespawn = EndPrepSDKCall();
	if (gH_PlayerRespawn == INVALID_HANDLE)
	{
		SetFailState("Fatal Error: Unable to find signature for \"Respawn\"!");
	}
}

public Action:HookStart(Handle:event, const String:name[], bool:dontBroadcast)
{
	if(gB_Enabled)
	{
		gH_Timer = CreateTimer(gF_Time, Respawn, _,TIMER_REPEAT);
	}
}

public Action:HookObjectDestroyed(Handle:event, const String:name[], bool:dontBroadcast)
{
	if(gB_Enabled)
	{
		KillTimer(gH_Timer);
		RespawnAll(true);
		gH_Timer = CreateTimer(gF_Time, Respawn, _,TIMER_REPEAT);
	}
}

public Action:HookControlPointCaptured(Handle:event, const String:name[], bool:dontBroadcast)
{
	if(gB_Enabled)
	{
		KillTimer(gH_Timer);
		RespawnAll(true);
		gH_Timer = CreateTimer(gF_Time, Respawn, _,TIMER_REPEAT);
	}
}

public Action:HookEnd(Handle:event, const String:name[], bool:dontBroadcast)
{
	if(gB_Enabled)
	{
		KillTimer(gH_Timer);
	}
}

public Action:Respawn(Handle:Timer)
{
	RespawnAll(false);
	return Plugin_Continue;
}

public ConVarChanged(Handle:cvar, const String:oldVal[], const String:newVal[])
{
	if(cvar == gH_Enabled)
	{
		gB_Enabled = StringToInt(newVal)? true:false;
	}
	else if(cvar == gH_Time)
	{
		gF_Time = StringToFloat(newVal);
	}
}

RespawnAll(bool:All = false)
{
	for (new i = 1; i <= MaxClients; i++)
	{
		if(IsClientInGame(i)) {
			{
				if(IsFakeClient(i))
				{
					if(All)
					{
						SDKCall(gH_PlayerRespawn, i);
					}
					else if(!IsPlayerAlive(i)) SDKCall(gH_PlayerRespawn, i);
				}
			}
		}
	}
}

error: pathspec 'addons/sourcemod/scripting/ins_botrespawn.sp' did not match any file(s) known to git


A thing to get a player's bp value

A thing to get a player's bp value

#include <sourcemod>
#include <async>

#pragma newdecls required
#pragma semicolon 1

#define PLUGIN_VERSION "1.0.0"
#define BPVALUEURL "https://ngsnetwork.000webhostapp.com/?profile="

ConVar cvarKickEnabled;
ConVar cvarScoreboardEnabled;
ConVar cvarKickAmount;

int playerBpValue[MAXPLAYERS + 1];

public Plugin myinfo =
{
	name = "[NGS] BackpackValue - Async",
	author = "TheXeon",
	description = "Plugin to get bp value using Async.",
	version = PLUGIN_VERSION,
	url = "https://neogenesisnetwork.net/"
}

public void OnPluginStart()
{
	ConVar cvarVer = CreateConVar("sm_bpa_version", PLUGIN_VERSION, "Filter by backpack using Async - version cvar", FCVAR_NOTIFY|FCVAR_DONTRECORD);
	cvarKickEnabled = CreateConVar("sm_bpa_kick_enabled", "1", "Enable kicking people if their bp doesn\'t meet the required amount.", FCVAR_NONE, true, 1.0, true, 3.0);
	cvarScoreboardEnabled = CreateConVar("sm_bpa_scoreboard_enabled", "1", "Enable changing of scoreboard points to bp money value.", FCVAR_NONE);
	cvarKickAmount = CreateConVar("sm_bpa_kick_amount", "25", "Amount in USD that a player\'s bp should be to connect.", FCVAR_NONE);

	cvarVer.SetString(PLUGIN_VERSION);
	AutoExecConfig(true, "ngs-connect-backpackvalue");
}

public void OnClientConnected(int client)
{
	char url[MAX_BUFFER_LENGTH], auth[24];
	GetClientAuthId(client, AuthId_SteamID64, auth, sizeof(auth));
	Format(url, sizeof(url), "%s%s", BPVALUEURL, auth);
	CurlHandle h = Async_CurlNew(client);
	Async_CurlGet(h, url, OnRequestDone);
}

public void OnRequestDone(CurlHandle request, int curlcode, int httpcode, int size, any client)
{
	char buffer = new char[size+1];
	if(curlcode == 0 && httpcode == 200)
	{
		Async_CurlGetData(request, buffer, size + 1);
		if (StrContains(buffer, "invalid", false) != -1)
		{
			playerBpValue[client] = StringToInt(buffer);
			if (cvarKickEnabled.BoolValue && playerBpValue < cvarKickAmount.IntValue)
			{
				KickClient(client, "Kicked for not meeting bp value requirements.");
			}
			if (cvarScoreboardEnabled.BoolValue)
			{
				Se
			}
		}
	}
	Async_Close(request);
}

error: pathspec 'scripting/ngs_connect_backpackvalue.sp' did not match any file(s) known to git


Extend victory time if this is a full round win

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/cjlesiw/arena-respawn.git/'


updated zitarev example

updated zitarev example

"oneart.wav" diskin dup
15  # delay
200 # lf_x
7.0 # rtlo
8.0 # rthi
10000 # hfdamp
315 # eq1 fre1
0 # eq1 level
1500 # eq2 freq
0 # eq2 level
1 # all wet mix
0 # 0 dB level
zitarev
drop

"examples/oneart.wav" diskin dup
15  # delay
200 # lf_x
7.0 # rtlo
8.0 # rthi
10000 # hfdamp
315 # eq1 fre1
0 # eq1 level
1500 # eq2 freq
0 # eq2 level
1 # all wet mix
0 # 0 dB level
zitarev
drop


Fix the wrong LMS being announced

Fix the wrong LMS being announced


Created Repo

Created Repo


Pregame: Don't try to spawn players that aren't on a playable team


Bump plugin version to 2018.09.05

Bump plugin version to 2018.09.05


Add a new resource for RSpec

Add a new resource for RSpec

This new resource is used to test that an error is raised when the value
of the name clause does not match the name of the file.


added lsys example

added lsys example

# L-Systems Test
# Paul Batchleor
# August 2016

_tick var
0.1 dmetro _tick set

_tick get dup
8 "a|a:ab|b:a" lsys 10 eq *
0.01 0.01 0.01 tenvx 1000 0.4 sine *

_tick get dup
4 "a|a:ab|b:a" lsys 10 eq *
0.01 0.01 0.01 tenvx 500 0.4 sine *

_tick get dup
3 "a|a:ab|b:a" lsys 10 eq *
0.01 0.01 0.01 tenvx 1500 0.4 sine *

mix

error: pathspec 'examples/lsys.sp' did not match any file(s) known to git


Added example template plugin.

Added example template plugin.

/**
 * Download Preferences Template
 */

#pragma semicolon 1
#include <sourcemod>
#include <downloadprefs>

// Holds a number to set the preferences for "Some Sounds"
new g_iDownloadPref;

public OnPluginStart() {
	// Create a download category "Some Sounds", describing "A couple of sounds.", and by default downloads are disabled.
	// This value will someday not be consistent across loads of the downloadprefs library.
	g_iDownloadPref = RegClientDownloadCategory("Some Sounds", "A couple of sounds.", false);

	// Register a few files to the "Some Sounds" category.
	// Existing files will be recategorized to the specified category.
	RegClientDownloadFile(g_iDownloadPref, "sound/dprefs_sample/fart.wav");
	RegClientDownloadFile(g_iDownloadPref, "sound/dprefs_sample/pootis.wav");
}

/**
 * Call this function to enable / disable the "Some Sounds" category for a client.
 * The next time the client requests the file, the download will be allowed.
 */
SetSomeSoundsPreference(client, bool:enabled) {
	SetClientDownloadPreference(client, g_iDownloadPref, enabled);
}

error: pathspec 'scripting/empty_downloadprefs.sp' did not match any file(s) known to git