Thread: [INC] Bank
View Single Post
eyal282
Veteran Member
Join Date: Aug 2011
Old 04-08-2018 , 13:37   Re: [INC] Bank
Reply With Quote #39

Quote:
Originally Posted by Arkarr View Post
Oh. So it works.
That's what I thought. Another plugin is using Bank, but it doesn't check if the database is yet connected or not ! So, it crash. You want to fix your other plugin. Mine is fine.
How do I check if the database is connected or not? Can you create a nativefor that in the include?

Should I use the forward you removed "Bank_DatabaseReady" and treat it as "OnPluginStart"?

Just tell me if I'm doing it right.

Bank.sp:

Code:
#include <sourcemod>
#include <sdktools>
#include <bank>

#pragma newdecls required

//Plugin Info
#define PLUGIN_TAG			"[Bank]"
#define PLUGIN_NAME			"[ANY] Bank"
#define PLUGIN_AUTHOR 		"Arkarr"
#define PLUGIN_VERSION 		"1.0"
#define PLUGIN_DESCRIPTION 	"A simple bank system where you can store money."
//Database
#define QUERY_INIT_DB_TCLIENTS		"CREATE TABLE IF NOT EXISTS `clients` (`clientID` int NOT NULL AUTO_INCREMENT, `steamid` varchar(45) NOT NULL, `credits` int NOT NULL, `bankID` int NOT NULL, PRIMARY KEY (`clientID`))"
#define QUERY_INIT_DB_TBANKS		"CREATE TABLE IF NOT EXISTS `banks` (`bankID` int NOT NULL AUTO_INCREMENT,  `name` varchar(50) NOT NULL, PRIMARY KEY (`bankID`))"
#define QUERY_CREATE_BANK			"INSERT INTO `banks` (name) VALUES ('%s')"
#define QUERY_SELECT_BANKS			"SELECT * FROM `banks`"
#define QUERY_SELECT_CLIENT_BANK	"SELECT * FROM `clients` WHERE steamid='%s' AND bankID=%i"
#define QUERY_ADD_CLIENT_TO_BANK	"INSERT INTO `clients` (steamid, credits, bankID) VALUES ('%s', '0', %i)"
#define QUERY_UPDATE_CLIENT_CREDITS	"UPDATE `clients` SET credits='%i' WHERE steamid='%s' AND bankID=%i"

Handle DATABASE_Banks;
//Handle FORWARD_DatabaseReady;

public Plugin myinfo = 
{
	name = PLUGIN_NAME,
	author = PLUGIN_AUTHOR,
	description = PLUGIN_DESCRIPTION,
	version = PLUGIN_VERSION,
	url = "http://www.sourcemod.net"
};

 
public void OnPluginStart()
{
   //FORWARD_DatabaseReady = CreateGlobalForward("Bank_DatabaseReady", ET_Event)
}

public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
{   
   	CreateNative("Bank_Create", Native_BankCreate);
	CreateNative("Bank_GetBalance", Native_BankGetBalance);
	CreateNative("Bank_SetBalance", Native_BankSetBalance);
	CreateNative("Bank_SetBalanceSteam", Native_BankSetBalanceSteam);
	CreateNative("Bank_EditBalance", Native_BankEditBalance);
	
	RegPluginLibrary("Bank");
   
	SQL_TConnect(DBConResult, "Bank");
   
	return APLRes_Success;
}

//Database init

public void DBConResult(Handle owner, Handle hndl, const char[] error, any data)
{
	if (hndl == INVALID_HANDLE)
	{
		SetFailState(error);
	}
	else
	{
		DATABASE_Banks = hndl;
		
		char buffer[300];
		if (!SQL_FastQuery(DATABASE_Banks, QUERY_INIT_DB_TCLIENTS) || !SQL_FastQuery(DATABASE_Banks, QUERY_INIT_DB_TBANKS))
		{
			SQL_GetError(DATABASE_Banks, buffer, sizeof(buffer));
			SetFailState(buffer);
		}
		/*else
		{
			Call_StartForward(FORWARD_DatabaseReady);
	  	}*/
	}
}

//Natives

public int Native_BankCreate(Handle plugin, int numParams)
{
	char buffer[300];
	char strBankName[128];
	GetNativeString(1, strBankName, sizeof(strBankName));
		
	if(BankExist(strBankName))
	{
		Format(buffer, sizeof(buffer), "Bank %s already exist !", strBankName);
		PrintErrorMessage(buffer);
		
		return false;
	}
	
	Format(buffer, sizeof(buffer), QUERY_CREATE_BANK, strBankName);
	if (!SQL_FastQuery(DATABASE_Banks, buffer))
	{
		SQL_GetError(DATABASE_Banks, buffer, sizeof(buffer));
		PrintErrorMessage(buffer);
		
		return false;
	}
	
	return true;
}

public int Native_BankEditBalance(Handle plugin, int numParams)
{
	char steamID[50];
	char buffer[200];
	char strBankName[128];
	
	GetNativeString(1, strBankName, sizeof(strBankName));
	int client = GetNativeCell(2);
	int ammount = GetNativeCell(3);
	bool create = GetNativeCell(4);
	
	int bankID = GetBankID(strBankName)
	if(bankID == -1)
	{
		Format(buffer, sizeof(buffer), "Bank %s doesn't exist !", strBankName);
		PrintErrorMessage(buffer);
		return false;
	}
	
	GetClientAuthId(client, AuthId_SteamID64, steamID, sizeof(steamID));
	Handle TRIE_Client = ClientFromBank(client, strBankName);
	
	int clientID;
	GetTrieValue(TRIE_Client, "ID", clientID);
	if(clientID == -1 || clientID == 0)
	{
		if(!create)
		{
			Format(buffer, sizeof(buffer), "User not in bank %s !", strBankName);
			PrintErrorMessage(buffer);
			return false;
		}
		else
		{
			Format(buffer, sizeof(buffer), QUERY_ADD_CLIENT_TO_BANK, steamID, bankID);
			if (!SQL_FastQuery(DATABASE_Banks, buffer))
			{
				SQL_GetError(DATABASE_Banks, buffer, sizeof(buffer));
				PrintErrorMessage(buffer);
				
				return false;
			}
		}
	}
	
	int credits;
	GetTrieValue(TRIE_Client, "credits", credits);
	credits += ammount;
	delete TRIE_Client;
	
	Format(buffer, sizeof(buffer), QUERY_UPDATE_CLIENT_CREDITS, credits, steamID, bankID);
	if (!SQL_FastQuery(DATABASE_Banks, buffer))
	{
		SQL_GetError(DATABASE_Banks, buffer, sizeof(buffer));
		PrintErrorMessage(buffer);
		
		return false;
	}
	
	return true;
}

public int Native_BankGetBalance(Handle plugin, int numParams)
{
	char strBankName[128];
	
	GetNativeString(1, strBankName, sizeof(strBankName));
	int client = GetNativeCell(2);
	
	Handle clientInfos = ClientFromBank(client, strBankName);
	
	if(clientInfos == INVALID_HANDLE)
	{
		return -1;
	}
	else
	{
		int credits;
		GetTrieValue(clientInfos, "credits", credits);
		delete clientInfos;
		return credits;
	}
}

public int Native_BankSetBalance(Handle plugin, int numParams)
{
	char steamID[50];
	char buffer[200];
	char strBankName[128];
	
	GetNativeString(1, strBankName, sizeof(strBankName));
	int client = GetNativeCell(2);
	int ammount = GetNativeCell(3);
	bool create = GetNativeCell(4);
	
	int bankID = GetBankID(strBankName)
	if(bankID == -1)
	{
		Format(buffer, sizeof(buffer), "Bank %s doesn't exist !", strBankName);
		PrintErrorMessage(buffer);
		return false;
	}
	
	GetClientAuthId(client, AuthId_SteamID64, steamID, sizeof(steamID));
	Handle TRIE_Client = ClientFromBank(client, strBankName);
	
	int clientID;
	GetTrieValue(TRIE_Client, "ID", clientID);
	delete TRIE_Client;
	if(clientID == -1 || clientID == 0)
	{
		if(!create)
		{
			Format(buffer, sizeof(buffer), "User not in bank %s !", strBankName);
			PrintErrorMessage(buffer);
			return false;
		}
		else
		{
			Format(buffer, sizeof(buffer), QUERY_ADD_CLIENT_TO_BANK, steamID, bankID);
			if (!SQL_FastQuery(DATABASE_Banks, buffer))
			{
				SQL_GetError(DATABASE_Banks, buffer, sizeof(buffer));
				PrintErrorMessage(buffer);
				
				return false;
			}
		}
	}
	
	Format(buffer, sizeof(buffer), QUERY_UPDATE_CLIENT_CREDITS, ammount, steamID, bankID);
	if (!SQL_FastQuery(DATABASE_Banks, buffer))
	{
		SQL_GetError(DATABASE_Banks, buffer, sizeof(buffer));
		PrintErrorMessage(buffer);
		
		return false;
	}
	
	return true;
}

public int Native_BankSetBalanceSteam(Handle plugin, int numParams)
{
	char steamID[50];
	char buffer[200];
	char strBankName[128];
	
	GetNativeString(1, strBankName, sizeof(strBankName));
	GetNativeString(2, steamID, sizeof(steamID));
	int ammount = GetNativeCell(3);
	
	int bankID = GetBankID(strBankName)
	if(bankID == -1)
	{
		Format(buffer, sizeof(buffer), "Bank %s doesn't exist !", strBankName);
		PrintErrorMessage(buffer);
		return false;
	}
	
	Format(buffer, sizeof(buffer), QUERY_UPDATE_CLIENT_CREDITS, ammount, steamID, bankID);
	if (!SQL_FastQuery(DATABASE_Banks, buffer))
	{
		SQL_GetError(DATABASE_Banks, buffer, sizeof(buffer));
		PrintErrorMessage(buffer);
		
		return false;
	}
	
	return true;
}

//Helper function

stock Handle ClientFromBank(int client, const char[] strBankName)
{
	char dbquery[100];
	char steamID[50];
	
	Handle TRIE_Client = CreateTrie();
	
	GetClientAuthId(client, AuthId_SteamID64, steamID, sizeof(steamID));
	Format(dbquery, sizeof(dbquery), QUERY_SELECT_CLIENT_BANK, steamID, GetBankID(strBankName));

	DBResultSet query = SQL_Query(DATABASE_Banks, dbquery);
	if (query == null)
	{
		char error[255];
		SQL_GetError(DATABASE_Banks, error, sizeof(error));
		SetFailState(error);
		
		return INVALID_HANDLE;
	} 
	else 
	{
		SetTrieValue(TRIE_Client, "credits", -1);
		while (SQL_FetchRow(query))
		{
			SetTrieValue(TRIE_Client, "ID", SQL_FetchInt(query, 0));
			SetTrieString(TRIE_Client, "steamid", steamID);
			SetTrieValue(TRIE_Client, "credits", SQL_FetchInt(query, 2), true);
			SetTrieValue(TRIE_Client, "bankID", SQL_FetchInt(query, 3));
		}
		
		delete query;
	}
	
	return TRIE_Client;
}

stock int GetBankID(const char[] strBankName)
{
	int bankID = -1;
	DBResultSet query = SQL_Query(DATABASE_Banks, QUERY_SELECT_BANKS);
	if (query == null)
	{
		char error[255];
		SQL_GetError(DATABASE_Banks, error, sizeof(error));
		SetFailState(error);
		
		return false;
	} 
	else 
	{
		char bankName[45];
		while (SQL_FetchRow(query))
		{
			SQL_FetchString(query, 1, bankName, sizeof(bankName));
			if(StrEqual(strBankName, bankName))
				bankID = SQL_FetchInt(query, 0);
		}
		
		delete query;
	}
	
	return bankID;
}

stock bool BankExist(const char[] strBankName)
{
	return GetBankID(strBankName) > 0 ? true : false;
}

stock void PrintErrorMessage(const char[] msg)
{
	PrintToServer("%s - ERROR - %s", PLUGIN_TAG, msg);
}
The plugin:

Code:
#include <sourcemod>
#include <sdkhooks>

///////////////////////////////////////////////////////////
////////////////////////NATIVES////////////////////////////
///////////////////////////////////////////////////////////

/* 
    Include file for Bank.sp 
    Provide simple functions to manage a player's bank. 
     
    Created by Arkarr (Alliedmodders) EDITED/FIXED BY ShawnCZek 
*/ 

/** 
 * Create a new bank. Can't create bank with same name at once. 
 * 
 * @param bankName  The name of the bank 
 * @return            True on sucess, false otherwise. 
 */ 
native bool Bank_Create(const char[] bankName) 

/** 
 * Add or substract a certain ammount of credits of a player's balance. 
 * 
 * @param bank             The name of the bank 
 * @param client        The client to add/substract to. 
 * @param ammount       The ammount to add/substract. 
 * @param forcecreate   Create the user if not found in the bank. 
 * @return            True on sucess, false otherwise. 
 */ 
native bool Bank_EditBalance(const char[] bank, int client, int ammount, bool forcecreate = true) 

/** 
 * Get the balance of a client in a specific bank. 
 * 
 * @param bank             The name of the bank 
 * @param client    The client to get the balance of. 
 * @return            The ammount of credits. -1 if no account found. 
 */ 
native int Bank_GetBalance(const char[] bank, int client) 

/** 
 * Set the balance of a client in a specific bank. 
 * 
 * @param bank             The name of the bank 
 * @param client        The client to set the balance of. 
 * @param ammount       The ammount to set the balance of the player. That wasn't english. 
 * @param forcecreate   Create the user if not found in the bank. 
 * @return            True on sucess, false otherwise. 
 */ 
native bool Bank_SetBalance(const char[] bank, int client, int ammount, bool forcecreate = true) 

/** 
 * Set the balance of a client in a specific bank. 
 * 
 * @param bank             The name of the bank 
 * @param steamID        The client to set the balance of. 
 * @param ammount       The ammount to set the balance of the player. That wasn't english. 
 * @param forcecreate   Create the user if not found in the bank. 
 * @return            True on sucess, false otherwise. 
 */ 
native bool Bank_SetBalanceSteam(const char[] bank, const char[] steamID, int ammount, bool forcecreate = true) 

native bool Bank_IsConnected();

///////////////////////////////////////////////////////////
////////////////////////END NATIVES////////////////////////
///////////////////////////////////////////////////////////

public Plugin:myinfo = {
	name = "Credits",
	author = "Eyal282 ( FuckTheSchool )",
	description = "Credits",
	version = "1.0",
	url = "https://forums.alliedmods.net/showthread.php?t=304043"
};

new bool:Hooked[MAXPLAYERS+1];

new const String:cBankName[] = "Credits";
new const String:hpBankName[] = "Health";
new const String:regenBankName[] = "Regen";
new const String:damageBankName[] = "Damage";

new HealthMaxLevel = 10;
new RegenMaxLevel = 10;
new DamageMaxLevel = 10;

new HealthPerLevel = 10;
new RegenPerLevel = 2;
new Float:DamagePerLevel = 1.1;

new HealthCost = 500;
new RegenCost = 500;
new DamageCost = 500;


new Handle:hcv_CreditsKill = INVALID_HANDLE;
new Handle:hcv_CreditsHS = INVALID_HANDLE;

new Handle:hRegenTimer[MAXPLAYERS+1] = INVALID_HANDLE;
public Bank_DatabaseReady()
{
	Bank_Create("Credits");
	RegConsoleCmd("sm_credits", Command_Credits);
	HookEvent("player_death", Event_PlayerDeath);
	HookEvent("player_spawn", Event_PlayerSpawn, EventHookMode_Post);
	
	hcv_CreditsKill = CreateConVar("surf_credits_kill", "1", "Amount of credits you get per kill");
	hcv_CreditsHS = CreateConVar("surf_credits_hs", "2", "Amount of credits you get per headshot kill");
	
	RegConsoleCmd("sm_shop", Command_Shop);
	RegAdminCmd("sm_getcredits", Command_LOL, ADMFLAG_ROOT);
	
	PrintToChatAll("Bank database is ready, skills are available and killing will now give credits");
}

public OnMapStart()
{
	for(new i=0;i < MAXPLAYERS+1;i++)
	{
		hRegenTimer[i] = INVALID_HANDLE;
	}
}

public Action:Event_PlayerSpawn(Handle:hEvent, String:Name[], bool:dontBroadcast)
{
	new UserId = GetEventInt(hEvent, "userid");
	new client = GetClientOfUserId(UserId);
	
	if(!IsValidPlayer(client))
		return;
	
	if(hRegenTimer[client] != INVALID_HANDLE)
	{
		CloseHandle(hRegenTimer[client]);
		hRegenTimer[client] = INVALID_HANDLE;
	}
	hRegenTimer[client] = CreateTimer(5.0, Regenerate, client, TIMER_FLAG_NO_MAPCHANGE|TIMER_REPEAT);
}


public OnClientConnected(client)
{
	Hooked[client] = false;
}
public OnClientPostAdminCheck(client)
{
	if(IsClientInGame(client) && !IsFakeClient(client))
	{
		SDKHook(client, SDKHook_OnTakeDamage, Event_Hurt);
		Hooked[client] = true;
	}
}

public OnClientDisconnect(client)
{
	if(Hooked[client])
		SDKUnhook(client, SDKHook_OnTakeDamage, Event_Hurt);
}

public Action:Event_Hurt(victim, &attacker, &inflictor, &Float:damage, &damagetype, &weapon, Float:damageForce[3], Float:damagePosition[3], damagecustom)
{
	if(victim > MaxClients || victim < 1)
		return Plugin_Continue;
		
	else if(attacker > MaxClients || attacker < 1)
		return Plugin_Continue;
		
	else if(damage == 0.0)
		return Plugin_Continue;
	
	damage *= Pow(DamagePerLevel, float(GetClientDamageSkill(attacker)));
	return Plugin_Changed;
}
public Action:Regenerate(Handle:hTimer, client)
{
	if(!IsValidPlayer(client))
	{
		hRegenTimer[client] = INVALID_HANDLE;
		return Plugin_Stop;
	}
	
	new CurHealth = GetEntProp(client, Prop_Send, "m_iHealth");
	new HealthToAdd = (HealthPerLevel * GetClientRegenSkill(client));
	new HPSkill = GetClientHPSkill(client);
	new TotalHealth;
	
	if(CurHealth + HealthToAdd >= 100 + ( HealthPerLevel * HPSkill ))
		TotalHealth = ( HealthPerLevel * HPSkill );
	
	else
		TotalHealth = CurHealth + HealthToAdd;
	SetEntityHealth(client, TotalHealth);
	return Plugin_Continue;
}	
public Action:Command_LOL(client, args)
{
	AddClientCredits(client, 100);
	return Plugin_Handled;
}

public Action:Command_Shop(client, args)
{
	new String:TempFormat[200];
	new Handle:hMenu = CreateMenu(Shop_MenuHandler);
	
	new HPSkill = GetClientHPSkill(client);
	new RegenSkill = GetClientRegenSkill(client);
	new DamageSkill = GetClientDamageSkill(client);
	Format(TempFormat, sizeof(TempFormat), "Health: [%i/%i] [%i HP] [%ic]", HPSkill, HealthMaxLevel, HPSkill * HealthPerLevel, HPSkill * HealthCost);
	AddMenuItem(hMenu, "", TempFormat);
	
	Format(TempFormat, sizeof(TempFormat), "HP Regen: [%i/%i] [%i/5sec] [%ic]", RegenSkill, RegenMaxLevel, RegenSkill * RegenPerLevel, RegenSkill * RegenCost);
	AddMenuItem(hMenu, "", TempFormat);
	
	Format(TempFormat, sizeof(TempFormat), "Damage: [%i/%i] [%.2fx] [%ic]", DamageSkill, DamageMaxLevel, DamageSkill * DamagePerLevel, DamageSkill * DamageCost);
	AddMenuItem(hMenu, "", TempFormat);
	
	SetMenuTitle(hMenu, "Choose your power:");
	DisplayMenu(hMenu, client, MENU_TIME_FOREVER);
	
	return Plugin_Handled;
}

public Shop_MenuHandler(Handle:hMenu, MenuAction:action, client, item)
{
	if(action == MenuAction_End)
		CloseHandle(hMenu);
	
	else if(action == MenuAction_Select)
	{
		switch(item)
		{
			case 0:
			{
				new HPSkill = GetClientHPSkill(client);
				new cost = HPSkill * HealthCost;
				new credits = GetClientCredits(client);
				
				if(HPSkill == HealthMaxLevel)
				{
					PrintToChat(client, "\x04Error:\x01 You reached the\x03 max level\x01 for this skill!");
				}
				else if(credits < cost)
				{
					PrintToChat(client, "\x04Error:\x01 You need\x03 %i\x01 more credits to buy this skill!", cost - credits);
				}
				AddClientHPSkill(client, 1);
				AddClientCredits(client, (-1 * cost));
			}
			case 1:
			{
				new RegenSkill = GetClientRegenSkill(client);
				new cost = RegenSkill * RegenCost;
				new credits = GetClientCredits(client);
				
				if(RegenSkill == RegenMaxLevel)
				{
					PrintToChat(client, "\x04Error:\x01 You reached the\x03 max level\x01 for this skill!");
				}
				else if(credits < cost)
				{
					PrintToChat(client, "\x04Error:\x01 You need\x03 %i\x01 more credits to buy this skill!", cost - credits);
				}
				AddClientRegenSkill(client, 1);
				AddClientCredits(client, (-1 * cost));
			}
			case 2:
			{
				new DamageSkill = GetClientDamageSkill(client);
				new cost = DamageSkill * DamageCost;
				new credits = GetClientCredits(client);
				
				if(DamageSkill == DamageMaxLevel)
				{
					PrintToChat(client, "\x04Error:\x01 You reached the\x03 max level\x01 for this skill!");
				}
				else if(credits < cost)
				{
					PrintToChat(client, "\x04Error:\x01 You need\x03 %i\x01 more credits to buy this skill!", cost - credits);
				}
				AddClientDamageSkill(client, 1);
				AddClientCredits(client, (-1 * cost));
			}
		}
	}	
	
	hMenu = INVALID_HANDLE;
}

public Action:Event_PlayerDeath(Handle:hEvent, String:Name[], bool:dontBroadcast)
{
	new victim = GetClientOfUserId(GetEventInt(hEvent, "userid"));
	
	if(!IsValidPlayer(victim))
		return;
	
	new attacker = GetClientOfUserId(GetEventInt(hEvent, "attacker"));
	
	new bool:headshot = GetEventBool(hEvent, "headshot");
	
	if(headshot)
		AddClientCredits(attacker, GetConVarInt(hcv_CreditsHS));
		
	else
		AddClientCredits(attacker, GetConVarInt(hcv_CreditsKill));
	
	
}

public Action:Command_Credits(client, args)
{
	PrintToChat(client, "\x01You have\x03 %i\x01 credits.", GetClientCredits(client));
	return Plugin_Handled;
}

stock AddClientCredits(client, amount)
{
	Bank_EditBalance(cBankName, client, amount);
}

stock SetClientCredits(client, amount)
{
	Bank_SetBalance(cBankName, client, amount);
}

stock GetClientCredits(client)
{
	new amount = Bank_GetBalance(cBankName, client);
	
	if(amount == -1)
		amount = 0;
	
	return amount;
}

stock GetClientHPSkill(client)
{
	new amount = Bank_GetBalance(hpBankName, client);
	
	if(amount == -1)
		amount = 0;
	
	return amount;
}

stock AddClientHPSkill(client, amount)
{
	Bank_EditBalance(hpBankName, client, amount);
}

stock GetClientRegenSkill(client)
{
	new amount = Bank_GetBalance(regenBankName, client);
	
	if(amount == -1)
		amount = 0;
	
	return amount;
}

stock AddClientRegenSkill(client, amount)
{
	Bank_EditBalance(regenBankName, client, amount);
}

stock GetClientDamageSkill(client)
{
	new amount = Bank_GetBalance(damageBankName, client);
	
	if(amount == -1)
		amount = 0;
	
	return amount;
}

stock AddClientDamageSkill(client, amount)
{
	Bank_EditBalance(damageBankName, client, amount);
}


stock bool:IsValidPlayer(client)
{
	if(client <= 0)
		return false;
		
	else if(client > MaxClients)
		return false;
		
	return IsClientInGame(client);
}
__________________
I am available to make plugins for pay.

Discord: Eyal282#1334

Last edited by eyal282; 04-08-2018 at 14:17.
eyal282 is offline