PDA

View Full Version : Need help fixing issues with "Gachls Candy Credit Mod"


404UserNotFound
02-14-2012, 16:27
So I decided to try out Gachls Candy Credit Mod (http://forums.alliedmods.net/showpost.php?p=1130589&postcount=45).

I ended up running through the source code of Candyscript.sp, and after adding "#pragma semicolon 1", and compiling the plugin, I received a lot of errors due to various things missing a semicolon.

But I also received an error about this bit of code:
public bool:AskPluginLoad(Handle:myself, bool:late, String:error[], err_max)
{
CreateNative("RegisterCandy", RegisterCandy);
CreateNative("DeregisterCandy", DeregisterCandy);
return true;
}

The error is as follows:
warning 234: symbol "AskPluginLoad" is marked as deprecated: Use AskPluginLoad2() instead

So I changed AskPluginLoad to AskPluginLoad2 like so:
public bool:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
{
CreateNative("RegisterCandy", RegisterCandy);
CreateNative("DeregisterCandy", DeregisterCandy);
return true;
}

And I recompiled it. Now the compiler is giving me two errors, both of which are the same:

error 025: function heading differs from prototypeThe first of the two errors points to AskPluginLoad2. Apparently, just adding a 2 isn't the way to fix the issue.

But the second "function heading differs" error points to this bit of code:
public ePlayerConnect(Handle:event, const String:name[], bool:dontBroadcast)
{
InitializeDatabase();
if (dbConnection == INVALID_HANDLE)
return;
new String:sSteamId[128], iUserId, hUserHimself;
GetEventString(event, "networkid", sSteamId, sizeof(sSteamId));
iUserId = GetEventInt(event, "userid");
hUserHimself = GetClientOfUserId(iUserId);
iKills[hUserHimself] = 0;
Client_iCurrentMoney[hUserHimself] = 0;

PrintDebug("Prechecking connecting user");
PrecheckUser(AddToConnecters(sSteamId));
}

More specifically, it points to:
PrecheckUser(AddToConnecters(sSteamId));

This is the PrecheckUser code:

public PrecheckUser(position)
{
InitializeDatabase();
if (dbConnection == INVALID_HANDLE)
return;
new String:sSteamId[32];
strcopy(sSteamId, sizeof(sSteamId), sConnectingClients[position]);
new String:qCheckForUser[255];
Format(qCheckForUser, sizeof(qCheckForUser), "SELECT * FROM %scandydata WHERE steamid = '%s';", sTablePrefix, sSteamId);
SQL_TQuery(dbConnection, cPrecheckUser, qCheckForUser, position);
}

I'm stumped. How do I fix both these errors?

404UserNotFound
02-14-2012, 16:41
Oh, I should mention that I also ran through the coding and changed any instances of "candy" to "money"/"Candy" to "Money".

So in the effort of supplying proper information, here's my modified version of the candyscript.sp file:

// ********************************************* ************************************
// TABLE OF CONTENTS
// ********************************************* ************************************
// 1. DEFINE INCLUDES, SET STRICT SEMICOLON MODE
// 2. DEFINES
// 3. PLUGIN INFORMATION
// 4. EVENTS
// 5. COMMANDS
// 6. INITIALIZATIONS
// 7. FUNCTIONS
// ********************************************* ************************************



// ********************************************* ************************************
// SECTION 1 - DEFINE INCLUDES, SET STRICT SEMICOLON MODE
// ********************************************* ************************************
// GLOBAL INCLUDES
#include <sourcemod>

// DEFINE STRICT SEMICOLON MODE
#pragma semicolon 1

// ********************************************* ************************************
// SECTION 2 - DEFINES
// ********************************************* ************************************
// DEFINES
#define NULLNAME "$$NULL##"
#define SHOP_MENU_MAX 6
#define SHOPMENU_OTHER_INDEX 512
//#define DEBUG "1"

// HANDLES
new Handle:cvCreditPerTick;
new Handle:cvCreditPerKill;
new Handle:cvCreditLossPerSuicide;
new Handle:cvCfgTickSpeed;
new Handle:cvCfgDatabaseToUse;
new Handle:cvCfgTablePrefix;
new Handle:cvCfgChatTag;
new Handle:cvCfgTickOnlyAlive;
new Handle:cvCfgNoiseLevel;
new Handle:cvCreditLossPerDeath;
new Handle:cvKillsForCredit;
new Handle:cvCreditForAssist;
new Handle:cvCustomChatTriggerBuyMenu1;
new Handle:cvCustomChatTriggerBuyMenu2;
new Handle:cvCustomChatTriggerPlayerStats1;
new Handle:cvCustomChatTriggerPlayerStats2;
new Handle:cvMoneyAdmin;
new Handle:dbConnection = INVALID_HANDLE;

// STRINGS
new String:sChatTag[32];
new String:sTablePrefix[32];
new String:sCurrentDB[64];
new String:sConnectingClients[34][128];
new String:sNames[512][128];
new String:ShopMenuName[SHOP_MENU_MAX][] = { "Player Buffs","Team Buffs","Hats","Weapons","Evil","Others" };

// BOOLEANS
new bool:bRunning = false;

// FLOATS
new Float:iStopTimes[512];

// FUNCTIONS
new Function:fCallbacks[512][2];

// NEW
new iKills[MAXPLAYERS];
new iPushArray[34];
new iBuyCount = 0;
new iCosts[512];
new iGroups[512];
new Client_iCurrentMoney[MAXPLAYERS+1] = 0;



// ********************************************* ************************************
// SECTION 3 - PLUGIN INFORMATION
// ********************************************* ************************************
// CREATE PLUGIN INFORMATION
public Plugin:myinfo =
{
name = "money money money, moooooney!",
author = "abrandnewday",
description = "everybody loves money!",
version = "1.0",
url = "http://forums.alliedmods.net",
}



// ********************************************* ************************************
// SECTION 4 - EVENTS
// ********************************************* ************************************
// EVENT: PLUGIN STARTED
public OnPluginStart()
{
PrintDebug("Creating convars");

InitializeConvars();

HookEvent("player_connect", Event_PlayerConnect);
HookEvent("player_death", Event_PlayerDeath);
HookEvent("teamplay_round_win", Event_RoundWin);


for (new i = 0; i < sizeof(sNames); i++)
{
sNames[i] = NULLNAME;
}

LoadTranslations("common.phrases");
// LoadTranslations("money.phrases")
}

// EVENT: PLAYER CONNECT
public Event_PlayerConnect(Handle:event, const String:name[], bool:dontBroadcast)
{
InitializeDatabase();
if (dbConnection == INVALID_HANDLE)
{
return;
}
new String:sSteamId[128], iUserId, hUserHimself;
GetEventString(event, "networkid", sSteamId, sizeof(sSteamId));
iUserId = GetEventInt(event, "userid");
hUserHimself = GetClientOfUserId(iUserId);
iKills[hUserHimself] = 0;
Client_iCurrentMoney[hUserHimself] = 0;

PrintDebug("Prechecking connecting user");
PrecheckUser(AddToConnecters(sSteamId));
}

// EVENT: PLAYER DEATH
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
PrintDebug("Eew, blood! player_death called!");
InitializeDatabase();
new attackerId = GetEventInt(event, "attacker");
new victimId = GetEventInt(event, "userid");
new assisterId = GetEventInt(event, "assister");
new attacker = GetClientOfUserId(attackerId);
new victim = GetClientOfUserId(victimId);
new assister = GetClientOfUserId(assisterId);

if (!FullCheckClient(attacker) || !FullCheckClient(victim))
{
PrintDebug("The target or the attacker are invalid clients!");
return;
}

if (attacker == victim)
{
PrintDebug("Someone killed himself (suicide)");
new iLosePoints = GetConVarInt(cvCreditLossPerSuicide);
if (iLosePoints == 0)
{
return;
}
new String:sNoise[128];
Format(sNoise, sizeof(sNoise), "[%s] You lost %i credits.", sChatTag, iLosePoints);
PrintNoise(sNoise, 3, victim);
RemoveMoney(victim, iLosePoints);
return;
}

PrintDebug("Someone got killed");
new iCreditGain = GetConVarInt(cvCreditPerKill);
new iCreditLoss = GetConVarInt(cvCreditLossPerDeath);
new iKillsForCredit = GetConVarInt(cvKillsForCredit);
new iCreditForAssist = GetConVarInt(cvCreditForAssist);

new bool:bUserGetsCredits = iKillsForCredit < 2;

if (!bUserGetsCredits)
{
if (iKills[attacker] >= iKillsForCredit)
{
bUserGetsCredits = true;
iKills[attacker] = 0;
}
else
{
iKills[attacker]++;
}
}

if (bUserGetsCredits)
{
PrintDebug("User gets credits!");
if (iCreditGain != 0)
{
AddMoney(attacker, iCreditGain);
}

new String:sNoiseAttacker[128];
Format(sNoiseAttacker, sizeof(sNoiseAttacker), "[%s] You got %i credits.", sChatTag, iCreditGain);
if (iCreditGain != 0)
{
PrintNoise(sNoiseAttacker, 2, attacker);
}
}

if (iCreditLoss != 0)
{
RemoveMoney(victim, iCreditLoss);
}
new String:sNoiseVictim[128];
Format(sNoiseVictim, sizeof(sNoiseVictim), "[%s] You lost %i credits.", sChatTag, iCreditLoss);
if (iCreditLoss != 0)
{
RemoveMoney(victim, iCreditLoss);
}

if (!FullCheckClient(assister))
{
return;
}

bUserGetsCredits = iKillsForCredit < 2;

if (!bUserGetsCredits)
{
if (iKills[assister] >= iKillsForCredit)
{
bUserGetsCredits = true;
iKills[assister] = 0;
}
else
{
iKills[assister]++;
}
}

if (bUserGetsCredits)
{
PrintDebug("Assister gets credits!");
if (iCreditForAssist != 0)
{
AddMoney(assister, iCreditForAssist);
}

new String:sNoiseAssister[128];
Format(sNoiseAssister, sizeof(sNoiseAssister), "[%s] You got %i credits.", sChatTag, iCreditForAssist);
if (iCreditForAssist != 0)
{
PrintNoise(sNoiseAssister, 2, assister);
}
}
}

// EVENT: ROUND WIN
public Event_RoundWin(Handle:event, const String:name[], bool:dontBroadcast)
{
new winteam = GetEventInt(event,"team");
if(winteam < 2)
{
return;
}

new maxClients = GetMaxClients();
new amount = GetConVarInt(cvMoneyAdmin);
new String:display[128];
Format(display,sizeof(display),"CONGRATULATIONS! YOUR TEAM WON %d CREDITS!",amount);
for (new i = 1; i <= maxClients; i++)
{
if (IsClientInGame(i) && GetClientTeam(i) == winteam)
{
new adminflags = GetUserFlagBits(i);
if(adminflags != 0 && adminflags & ADMFLAG_GENERIC)
{
AddMoney(i,amount);
PrintCenterText(i,display);
}
}
}
}

// EVENT: ON CONFIGS EXECUTED
public OnConfigsExecuted()
{
InitializeTimersAndCValues();
InitializeDatabase();
}



// ********************************************* ************************************
// SECTION 5 - COMMANDS
// ********************************************* ************************************
// ADMIN COMMAND: ADD MONEY
public Action:cAddMoney(client, args)
{
InitializeDatabase();
if (dbConnection == INVALID_HANDLE)
{
return Plugin_Handled;
}
new String:sTarget[32], String:sAmount[32];
new iAmount;

if (!GetCmdArg(1, sTarget, sizeof(sTarget)))
{
if (FullCheckClient(client))
{
PrintToChat(client, "[%s] Usage: sm_money_add userid amount", sChatTag);
}
else
{
PrintToServer("[%s] Usage: sm_money_add userid amount", sChatTag);
}
return Plugin_Handled;
}

if (!GetCmdArg(2, sAmount, sizeof(sAmount)))
{
if (FullCheckClient(client))
{
PrintToChat(client, "[%s] Usage: sm_money_add userid amount", sChatTag);
}
else
{
PrintToServer("[%s] Usage: sm_money_add userid amount", sChatTag);
}
return Plugin_Handled;
}

new String:sTargetName[MAX_TARGET_LENGTH];
new iTargetList[MAXPLAYERS], iTargetCount, bool:tn_is_ml;

iTargetCount = ProcessTargetString(sTarget, client, iTargetList, MAXPLAYERS, COMMAND_FILTER_CONNECTED, sTargetName, sizeof(sTargetName), tn_is_ml);

iAmount = StringToInt(sAmount);

for (new i = 0; i < iTargetCount; i++)
{
new iTarget = iTargetList[i];

if (!FullCheckClient(iTarget))
{
if (FullCheckClient(client))
{
PrintToChat(client, "[%s] No such user (%s)", sChatTag, sTarget);
}
else
{
PrintToServer("[%s] No such user (%s)", sChatTag, sTarget);
}
return Plugin_Handled;
}

if (iAmount != 0)
{
AddMoney(iTarget, iAmount);
}

new String:sMoneyNoise[255];
Format(sMoneyNoise, sizeof(sMoneyNoise), "[%s] A nice admin gave you %i credits.", sChatTag, iAmount);
PrintNoise(sMoneyNoise, 2, iTarget);
}

return Plugin_Handled;
}

// ADMIN COMMAND: REMOVE MONEY
public Action:cRemoveMoney(client, args)
{
InitializeDatabase();
if (dbConnection == INVALID_HANDLE)
{
return Plugin_Handled;
}
new String:sTarget[32], String:sAmount[32];
new iAmount;

if (!GetCmdArg(1, sTarget, sizeof(sTarget)))
{
if (FullCheckClient(client))
{
PrintToChat(client, "[%s] Usage: sm_money_remove userid amount", sChatTag);
}
else
{
PrintToServer("[%s] Usage: sm_money_remove userid amount", sChatTag);
}
return Plugin_Handled;
}

if (!GetCmdArg(2, sAmount, sizeof(sAmount)))
{
if (FullCheckClient(client))
{
PrintToChat(client, "[%s] Usage: sm_money_remove userid amount", sChatTag);
}
else
{
PrintToServer("[%s] Usage: sm_money_remove userid amount", sChatTag);
}
return Plugin_Handled;
}

new String:sTargetName[MAX_TARGET_LENGTH];
new iTargetList[MAXPLAYERS], iTargetCount, bool:tn_is_ml;

iTargetCount = ProcessTargetString(sTarget, client, iTargetList, MAXPLAYERS, COMMAND_FILTER_CONNECTED, sTargetName, sizeof(sTargetName), tn_is_ml);

iAmount = StringToInt(sAmount);

for (new i = 0; i < iTargetCount; i++)
{
new iTarget = iTargetList[i];

if (!FullCheckClient(iTarget))
{
if (FullCheckClient(client))
{
PrintToChat(client, "[%s] No such user (%s)", sChatTag, sTarget);
}
else
{
PrintToServer("[%s] No such user (%s)", sChatTag, sTarget);
}
return Plugin_Handled;
}

if (iAmount != 0)
{
RemoveMoney(iTarget, iAmount);
}

new String:sMoneyNoise[255];
Format(sMoneyNoise, sizeof(sMoneyNoise), "[%s] An evil admin stole %i credits from you.", sChatTag, iAmount);
PrintNoise(sMoneyNoise, 2, iTarget);
}

return Plugin_Handled;
}

// ADMIN COMMAND: RESET MONEY
public Action:cResetMoney(client, args)
{
InitializeDatabase();
if (dbConnection == INVALID_HANDLE)
{
return Plugin_Handled;
}
new String:sAmount[32];

if (!GetCmdArg(1, sAmount, sizeof(sAmount)))
{
if (FullCheckClient(client))
{
PrintToChat(client, "[%s] Usage: sm_money_reset amount", sChatTag);
}
else
{
PrintToServer("[%s] Usage: sm_money_reset amount", sChatTag);
}
return Plugin_Handled;
}

new iAmount = StringToInt(sAmount);
if (iAmount < 0)
{
return Plugin_Handled;
}

if (!FullCheckClient(client))
{
new String:qReset[255];
Format(qReset, sizeof(qReset), "UPDATE %smoneydata SET money = %s;", sTablePrefix, sAmount);
SQL_TQuery(dbConnection, cIgnoreQueryCallback, qReset);
PrintToServer("Reset all clients money to %s", sAmount);
return Plugin_Handled;
}

new Handle:mAskForSure = CreateMenu(cResetMoneyMenuCallback);
SetMenuTitle(mAskForSure, "Reset money to %s?", sAmount);
AddMenuItem(mAskForSure, "no", "No");
AddMenuItem(mAskForSure, sAmount, "Yes");
DisplayMenu(mAskForSure, client, 20);
return Plugin_Handled;
}

// ADMIN COMMAND: RESET DATABASE
public Action:cResetDB(client, args)
{
InitializeDatabase();
if (dbConnection == INVALID_HANDLE)
{
return Plugin_Handled;
}

if (!FullCheckClient(client))
{
new String:qReset[255];
Format(qReset, sizeof(qReset), "DROP TABLE %smoneydata;", sTablePrefix);
SQL_TQuery(dbConnection, cIgnoreQueryCallback, qReset);
PrintToServer("Reset db, dropping EVERYTHING!");
CloseHandle(dbConnection);
dbConnection = INVALID_HANDLE;
sCurrentDB = "INVALID_DATABASE";
InitializeDatabase();
return Plugin_Handled;
}

new Handle:mAskForSure = CreateMenu(cResetDBMenuCallback);
SetMenuTitle(mAskForSure, "Reset database?");
AddMenuItem(mAskForSure, "no", "No");
AddMenuItem(mAskForSure, "yes", "Yes");
DisplayMenu(mAskForSure, client, 20);
return Plugin_Handled;
}

// ADMIN COMMAND: GET MONEY
public Action:cGetMoney(client, args)
{
InitializeDatabase();
if (dbConnection == INVALID_HANDLE)
{
return Plugin_Handled;
}
new String:sTarget[32];

if (!GetCmdArg(1, sTarget, sizeof(sTarget)))
{
if (FullCheckClient(client))
{
PrintToChat(client, "[%s] Usage: sm_money_get userid", sChatTag);
}
else
{
PrintToServer("[%s] Usage: sm_money_get userid", sChatTag);
}
return Plugin_Handled;
}

new String:sTargetName[MAX_TARGET_LENGTH];
new iTargetList[MAXPLAYERS], iTargetCount, bool:tn_is_ml;

iTargetCount = ProcessTargetString(sTarget, client, iTargetList, MAXPLAYERS, COMMAND_FILTER_CONNECTED, sTargetName, sizeof(sTargetName), tn_is_ml);

for (new i = 0; i < iTargetCount; i++)
{
new iTarget = iTargetList[i];

if (!FullCheckClient(iTarget))
{
if (FullCheckClient(client))
{
PrintToChat(client, "[%s] No such user (%s)", sChatTag, sTarget);
}
else
{
PrintToServer("[%s] No such user (%s)", sChatTag, sTarget);
}
return Plugin_Handled;
}

new String:qGetUsersMoney[255], String:sSteamId[32];
GetClientAuthString(iTarget, sSteamId, sizeof(sSteamId));
Format(qGetUsersMoney, sizeof(qGetUsersMoney), "SELECT money FROM %smoneydata WHERE steamid = '%s';", sTablePrefix, sSteamId);
SQL_TQuery(dbConnection, cGetUsersMoney, qGetUsersMoney, client);
PrintDebug(qGetUsersMoney);
}

return Plugin_Handled;
}

// ADMIN COMMAND: PRINT MONEY MESSAGE
public Action:cMsg(client, args)
{
InitializeDatabase();
if (dbConnection == INVALID_HANDLE)
{
return Plugin_Handled;
}
new String:sTarget[32], String:sItem[256];

if (!GetCmdArg(1, sTarget, sizeof(sTarget)))
{
if (FullCheckClient(client))
{
PrintToChat(client, "[%s] Usage: sm_money_msg user item", sChatTag);
}
else
{
PrintToServer("[%s] Usage: sm_money_msg user item", sChatTag);
}
return Plugin_Handled;
}

if (!GetCmdArg(2, sItem, sizeof(sItem)))
{
if (FullCheckClient(client))
{
PrintToChat(client, "[%s] Usage: sm_money_msg user item", sChatTag);
}
else
{
PrintToServer("[%s] Usage: sm_money_msg user item", sChatTag);
}
return Plugin_Handled;
}

new String:sTargetName[MAX_TARGET_LENGTH];
new iTargetList[MAXPLAYERS], iTargetCount, bool:tn_is_ml;

iTargetCount = ProcessTargetString(sTarget, client, iTargetList, MAXPLAYERS, COMMAND_FILTER_CONNECTED, sTargetName, sizeof(sTargetName), tn_is_ml);

for (new i = 0; i < iTargetCount; i++)
{
new iTarget = iTargetList[i];

if (!FullCheckClient(iTarget))
{
if (FullCheckClient(client))
{
PrintToChat(client, "[%s] No such user (%s)", sChatTag, sTarget);
}
else
{
PrintToServer("[%s] No such user (%s)", sChatTag, sTarget);
}
return Plugin_Handled;
}

new String:sName[256];
GetClientName(iTarget, sName, sizeof(sName));

for (new j = 1; j <= MaxClients; j++)
{
if (!FullCheckClient(j))
{
continue;
}

PrintToChat(j, "\x01\x03%s \x01has bought: \x04%s", sName, sItem);
}
}

return Plugin_Handled;
}

// COMMAND: BUY
public Action:cBuy(client, args)
{
PrintDebug("Buy event has been fired!");
PrintDebug("Reinitializing DB (if needed)");
InitializeDatabase();
PrintDebug("Checking DB connection");
if (dbConnection == INVALID_HANDLE)
{
PrintDebug("Nope, no DB connection. Aborting say command");
return Plugin_Continue;
}
PrintDebug("Validating client");
if (!FullCheckClient(client))
{
PrintDebug("Nope, client invalid. Aborting say command");
return Plugin_Continue;
}
PrintDebug("Seems to be a health client/db. Checking for commands");
PrintDebug("Someone wants to buy something");
new String:qGetUsersMoney[255], String:sSteamId[32];
GetClientAuthString(client, sSteamId, sizeof(sSteamId));
Format(qGetUsersMoney, sizeof(qGetUsersMoney), "SELECT money FROM %smoneydata WHERE steamid = '%s';", sTablePrefix, sSteamId);
SQL_TQuery(dbConnection, cBuyMenuSQLCallback, qGetUsersMoney, client);

return Plugin_Handled;
}

// COMMAND: STATS
public Action:cStats(client, args)
{
PrintDebug("Buy event has been fired!");
PrintDebug("Reinitializing DB (if needed)");
InitializeDatabase();
PrintDebug("Checking DB connection");
if (dbConnection == INVALID_HANDLE)
{
PrintDebug("Nope, no DB connection. Aborting say command");
return Plugin_Continue;
}
PrintDebug("Validating client");
if (!FullCheckClient(client))
{
PrintDebug("Nope, client invalid. Aborting say command");
return Plugin_Continue;
}
PrintDebug("Seems to be a health client/db. Checking for commands");
PrintDebug("Someone wants his stats");
new String:qGetUsersMoney[255], String:sSteamId[32];
GetClientAuthString(client, sSteamId, sizeof(sSteamId));
Format(qGetUsersMoney, sizeof(qGetUsersMoney), "SELECT money, lifetimemoney FROM %smoneydata WHERE steamid = '%s';", sTablePrefix, sSteamId);
SQL_TQuery(dbConnection, cStatsSQLCallback, qGetUsersMoney, client);

return Plugin_Handled;
}

// COMMAND: SAY
public Action:cSay(client, args)
{
PrintDebug("Say event has been fired!");
PrintDebug("Reinitializing DB (if needed)");
InitializeDatabase();
PrintDebug("Checking DB connection");
if (dbConnection == INVALID_HANDLE)
{
PrintDebug("Nope, no DB connection. Aborting say command");
return Plugin_Continue;
}
PrintDebug("Validating client");
if (!FullCheckClient(client))
{
PrintDebug("Nope, client invalid. Aborting say command");
return Plugin_Continue;
}
PrintDebug("Seems to be a health client/db. Checking for commands");
new String:text[512], String:sCustChatTriggerBuy1[128], String:sCustChatTriggerBuy2[128], String:sCustChatTriggerStats1[128], String:sCustChatTriggerStats2[128];
GetConVarString(cvCustomChatTriggerBuyMenu1, sCustChatTriggerBuy1, sizeof(sCustChatTriggerBuy1));
GetConVarString(cvCustomChatTriggerBuyMenu2, sCustChatTriggerBuy2, sizeof(sCustChatTriggerBuy2));
GetConVarString(cvCustomChatTriggerPlayerStat s1, sCustChatTriggerStats1, sizeof(sCustChatTriggerStats1));
GetConVarString(cvCustomChatTriggerPlayerStat s2, sCustChatTriggerStats2, sizeof(sCustChatTriggerStats2));
GetCmdArg(1, text, sizeof(text));
if (((strcmp(sCustChatTriggerBuy1, "", false) != 0) && (strcmp(text, sCustChatTriggerBuy1, false) == 0))
|| ((strcmp(sCustChatTriggerBuy2, "", false) != 0) && (strcmp(text, sCustChatTriggerBuy2, false) == 0)))
{
PrintDebug("Someone wants to buy something");
new String:qGetUsersMoney[255], String:sSteamId[32];
GetClientAuthString(client, sSteamId, sizeof(sSteamId));
Format(qGetUsersMoney, sizeof(qGetUsersMoney), "SELECT money FROM %smoneydata WHERE steamid = '%s';", sTablePrefix, sSteamId);
SQL_TQuery(dbConnection, cBuyMenuSQLCallback, qGetUsersMoney, client);

return Plugin_Handled;
}
else if (((strcmp(sCustChatTriggerStats1, "", false) == 0) && (strcmp(text, sCustChatTriggerStats1, false) == 0))
|| ((strcmp(sCustChatTriggerStats2, "", false) == 0) && (strcmp(text, sCustChatTriggerStats2, false) == 0)))
{
PrintDebug("Someone wants his stats");
new String:qGetUsersMoney[255], String:sSteamId[32];
GetClientAuthString(client, sSteamId, sizeof(sSteamId));
Format(qGetUsersMoney, sizeof(qGetUsersMoney), "SELECT money, lifetimemoney FROM %smoneydata WHERE steamid = '%s';", sTablePrefix, sSteamId);
SQL_TQuery(dbConnection, cStatsSQLCallback, qGetUsersMoney, client);

return Plugin_Handled;
}
PrintDebug("Nope, no command found. Aborting say command");
return Plugin_Continue;
}


// ********************************************* ************************************
// SECTION 6 - INITIALIZATIONS
// ********************************************* ************************************
// INITIALIZE CONVARS
public InitializeConvars()
{
cvCreditPerKill = CreateConVar("sm_money_per_kill", "1", "Credits a user gets for killing someone", FCVAR_PLUGIN);
cvCreditPerTick = CreateConVar("sm_money_per_tick", "1", "Credits a user gets each tick", FCVAR_PLUGIN);
cvCreditLossPerSuicide = CreateConVar("sm_money_loss_per_suicide", "0", "Credits a user loses if he kills himself", FCVAR_PLUGIN);
cvCfgTickSpeed = CreateConVar("sm_money_tick_speed", "60", "Time between two ticks in seconds", FCVAR_PLUGIN);
cvCfgDatabaseToUse = CreateConVar("sm_money_database", "default", "Database to use (from databases.cfg)", FCVAR_PLUGIN);
cvCfgTablePrefix = CreateConVar("sm_money_table_prefix", "cndy_", "Prefix for the table to store data in", FCVAR_PLUGIN);
cvCfgChatTag = CreateConVar("sm_money_chat_tag", "money", "Tag for messages printed to the chat ([value] text)", FCVAR_PLUGIN);
cvCfgTickOnlyAlive = CreateConVar("sm_money_tick_only_alive", "0", "Give only alive players credit on tick", FCVAR_PLUGIN, true, 0.0, true, 1.0);
cvCfgNoiseLevel = CreateConVar("sm_money_noise_level", "2", "Set the noise level 1-3", FCVAR_PLUGIN, true, 1.0, true, 3.0);
cvCreditLossPerDeath = CreateConVar("sm_money_loss_per_death", "1", "Credits a user loses if he gets killed", FCVAR_PLUGIN);
cvKillsForCredit = CreateConVar("sm_money_kills_for_money", "1", "Kills required to receive sm_money_per_kill", FCVAR_PLUGIN);
cvCustomChatTriggerBuyMenu1 = CreateConVar("sm_money_chat_buy1", "", "Custom chat trigger for the buy menu", FCVAR_PLUGIN);
cvCustomChatTriggerBuyMenu2 = CreateConVar("sm_money_chat_buy2", "", "Custom chat trigger for the buy menu", FCVAR_PLUGIN);
cvCustomChatTriggerPlayerStats1 = CreateConVar("sm_money_chat_stats1", "", "Custom chat trigger for the player stats", FCVAR_PLUGIN);
cvCustomChatTriggerPlayerStats2 = CreateConVar("sm_money_chat_stats2", "", "Custom chat trigger for the player stats", FCVAR_PLUGIN);
cvCreditForAssist = CreateConVar("sm_money_per_assist", "1", "Receive credits for an assist", FCVAR_PLUGIN);
cvMoneyAdmin = CreateConVar("sm_money_admin","1000","How many credits give to admin", FCVAR_PLUGIN);

PrintDebug("AutoExecConfig");
AutoExecConfig();

PrintDebug("Getting new chat tag");
GetConVarString(cvCfgChatTag, sChatTag, sizeof(sChatTag));
}

// INITIALIZE ADMIN COMMANDS
public InitializeAdminCommands()
{
RegAdminCmd("sm_money_add", cAddMoney, ADMFLAG_RCON, "Give a user some credits (sm_money_add user amount)");
RegAdminCmd("sm_money_remove", cRemoveMoney, ADMFLAG_RCON, "Remove some credits (sm_money_remove user amount)");
RegAdminCmd("sm_money_get", cGetMoney, ADMFLAG_RCON, "Get the amount of money (sm_money_get userid)");
RegAdminCmd("sm_money_reset", cResetMoney, ADMFLAG_RCON, "Reset the amount of money of every player to a certain amount (sm_money_reset amount)");
RegAdminCmd("sm_money_resetdb", cResetDB, ADMFLAG_RCON, "Reset the database (sm_money_resetdb)");
RegAdminCmd("sm_money_msg", cMsg, ADMFLAG_KICK, "Prints a money buy message (sm_money_msg user item)");
}

// INITIALIZE DATABASE
public InitializeDatabase()
{
new String:sDBHndlName[128];
GetConVarString(cvCfgDatabaseToUse, sDBHndlName, sizeof(sDBHndlName));
if (strcmp(sCurrentDB, sDBHndlName) == 0)
{
PrintDebug("No change in db connection detected.");
return;
}

if (dbConnection != INVALID_HANDLE)
{
PrintDebug("Closing existing DB handle!");
CloseHandle(dbConnection);
}

if (!SQL_CheckConfig(sDBHndlName))
{
PrintToServer("[%s] I wasn't able to find your database configuration %s", sChatTag, sDBHndlName);
return;
}
SQL_TConnect(cDatabaseEstablished, sDBHndlName);
}

// INITIALIZE TIMERS AND CONVAR VALUES
public InitializeTimersAndCValues()
{
if (bRunning)
{
return;
}
PrintDebug("Creating admin commands");
InitializeAdminCommands();
PrintToServer("Money plugin is now loaded and running!");
RegConsoleCmd("say", cSay);
RegConsoleCmd("sm_buy", cBuy, "Open Buymenu");
RegConsoleCmd("sm_buymenu", cBuy, "Open Buymenu");
RegConsoleCmd("sm_cstats", cStats, "Show money stats");
RegConsoleCmd("sm_money", cStats, "Show money stats");

GetConVarString(cvCfgChatTag, sChatTag, sizeof(sChatTag));
GetConVarString(cvCfgTablePrefix, sTablePrefix, sizeof(sTablePrefix));

PrintDebug("Updating tick speed");
new iTickSpeed = GetConVarInt(cvCfgTickSpeed);
new iCreditEarn = GetConVarInt(cvCreditPerTick);
if ((iTickSpeed > 0) && (iCreditEarn > 0))
{
CreateTimer(float(iTickSpeed), tTick, _, TIMER_REPEAT);
}

for (new i = 0; i < sizeof(sConnectingClients); i++)
{
sConnectingClients[i] = "";
}
bRunning = true;
}



// ********************************************* ************************************
// SECTION 7 - FUNCTIONS
// ********************************************* ************************************
// FUNCTION: ASK PLUGIN LOAD
public bool:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
{
CreateNative("RegisterMoney", RegisterMoney);
CreateNative("DeregisterMoney", DeregisterMoney);
return true;
}

// FUNCTION: PRINT DEBUG
public PrintDebug(String:sMessage[])
{
#if defined DEBUG
PrintToServer("[CDBG] %s", sMessage);
#endif
}

// FUNCTION: PRINT NOISE
public PrintNoise(String:sMessage[], level, target)
{
PrintDebug("Printing noise");
new iNoiseLevel = GetConVarInt(cvCfgNoiseLevel);
if (level <= iNoiseLevel)
{
if (target == 0)
{
PrintDebug("Print noise to all");
PrintToChatAll(sMessage);
}
else
{
PrintDebug("Print noise to [target]");
if (!FullCheckClient(target))
{
PrintDebug("Invalid target!");
return;
}
PrintToChat(target, sMessage);
}
}
}

// FUNCTION: PRECHECK ALL USERS
public PrecheckAllUsers()
{
InitializeDatabase();
for (new i = 1; i <= MaxClients; i++)
{
if (!FullCheckClient(i))
{
continue;
}
new String:sSteamId[128];
GetClientAuthString(i, sSteamId, sizeof(sSteamId));
PrecheckUser(AddToConnecters(sSteamId));
}
}

// FUNCTION: ADD TO CONNECTERS
public AddToConnecters(String:sSteamId[128])
{
for (new i = 0; i < sizeof(sConnectingClients); i++)
{
if (strcmp(sConnectingClients[i], sSteamId) == 0)
{
return i;
}
}

new iNext = 0;
for (new i = 0; i < sizeof(sConnectingClients); i++)
{
iNext = i;
if (strcmp(sConnectingClients[i], "") == 0)
{
break;
}
}
sConnectingClients[iNext] = sSteamId;
PrintDebug("Adding a value to the connectors");
return iNext;
}

// FUNCTION: REMOVE FROM CONNECTERS
public RemoveFromConnecters(position)
{
sConnectingClients[position] = "";
PrintDebug("Removing a value from the connectors");
}

// FUNCTION: PRECHECK USER (POSITION)
public PrecheckUser(position)
{
InitializeDatabase();
if (dbConnection == INVALID_HANDLE)
{
return;
}
new String:sSteamId[32];
strcopy(sSteamId, sizeof(sSteamId), sConnectingClients[position]);
new String:qCheckForUser[255];
Format(qCheckForUser, sizeof(qCheckForUser), "SELECT * FROM %smoneydata WHERE steamid = '%s';", sTablePrefix, sSteamId);
SQL_TQuery(dbConnection, cPrecheckUser, qCheckForUser, position);
}

// FUNCTION: PRECHECK USER
public cPrecheckUser(Handle:owner, Handle:hndl, String:error[], any:data)
{
new String:sSteamId[32];
strcopy(sSteamId, sizeof(sSteamId), sConnectingClients[data]);

if (hndl == INVALID_HANDLE)
{
PrintToServer("[%s] Error while executing PrecheckUser query: %s", sChatTag, error);
return;
}

if (SQL_GetRowCount(hndl) != 1)
{
new String:qCreateNewUser[255];
Format(qCreateNewUser, sizeof(qCreateNewUser), "INSERT INTO %smoneydata (steamid, money, lifetimemoney) VALUES ('%s', 0, 0);", sTablePrefix, sSteamId);
SQL_TQuery(dbConnection, cIgnoreQueryCallback, qCreateNewUser);
}

RemoveFromConnecters(data);
}

// FUNCTION: ADD MONEY
public AddMoney(client, amount)
{
InitializeDatabase();
if (dbConnection == INVALID_HANDLE)
{
return;
}
if (!FullCheckClient(client))
{
return;
}
new String:sSteamId[32];
GetClientAuthString(client, sSteamId, sizeof(sSteamId));
new String:qAddMoney[255];
Format(qAddMoney, sizeof(qAddMoney), "UPDATE %smoneydata SET money = money + %i, lifetimemoney = lifetimemoney + %i WHERE steamid = '%s';", sTablePrefix, amount, amount, sSteamId);
PrintDebug(qAddMoney);
SQL_TQuery(dbConnection, cIgnoreQueryCallback, qAddMoney);
}

// FUNCTION: REMOVE MONEY
public RemoveMoney(client, amount)
{
InitializeDatabase();
if (dbConnection == INVALID_HANDLE)
{
return;
}
if (!FullCheckClient(client))
{
return;
}
new String:sSteamId[32];
GetClientAuthString(client, sSteamId, sizeof(sSteamId));
new String:qAddMoney[255];
Format(qAddMoney, sizeof(qAddMoney), "SELECT money, '%s' FROM %smoneydata WHERE steamid = '%s';", sSteamId, sTablePrefix, sSteamId);
SQL_TQuery(dbConnection, cCheckForNegativeAmount, qAddMoney, amount);
}

// FUNCTION: CHECK FOR NEGATIVE AMOUNT
public cCheckForNegativeAmount(Handle:owner, Handle:hndl, String:error[], any:data)
{
if (hndl == INVALID_HANDLE)
{
PrintToServer("[%s] Error in remove money query: %s", sChatTag, error);
return;
}

SQL_FetchRow(hndl);
if (SQL_FetchInt(hndl, 0) - data < 0)
{
return;
}
new String:sSteamId[32];
SQL_FetchString(hndl, 1, sSteamId, sizeof(sSteamId));

new String:qAddMoney[255];
Format(qAddMoney, sizeof(qAddMoney), "UPDATE %smoneydata SET money = money - %i WHERE steamid = '%s';", sTablePrefix, data, sSteamId);
SQL_TQuery(dbConnection, cIgnoreQueryCallback, qAddMoney);
}

// FUNCTION: SET MONEY
public SetMoney(client, amount)
{
InitializeDatabase();
if (dbConnection == INVALID_HANDLE)
{
return;
}
if (!FullCheckClient(client))
{
return;
}
new String:sSteamId[32];
GetClientAuthString(client, sSteamId, sizeof(sSteamId));
new String:qAddMoney[255];
Format(qAddMoney, sizeof(qAddMoney), "UPDATE %smoneydata SET money = %i WHERE steamid = '%s';", sTablePrefix, amount, sSteamId);
SQL_TQuery(dbConnection, cIgnoreQueryCallback, qAddMoney);
}

// FUNCTION: GET USERS MONEY CALLBACK
public cGetUsersMoney(Handle:owner, Handle:hndl, String:error[], any:data)
{
if (hndl == INVALID_HANDLE)
{
PrintToServer("[%s] Error while executing cGetMoney query: %s", sChatTag, error);
return;
}

if (SQL_GetRowCount(hndl) == 1)
{
SQL_FetchRow(hndl);
new iHisMoney = SQL_FetchInt(hndl, 0);
if (FullCheckClient(data))
{
PrintToChat(data, "[%s] This user has got \x03%i\x01 credits.", sChatTag, iHisMoney);
}
else
{
PrintToServer("[%s] This user has got \x03%i\x01 credits.", sChatTag, iHisMoney);
}
}
else
{
if (FullCheckClient(data))
{
PrintToChat(data, "[%s] This user does not exist in the database.", sChatTag);
}
else
{
PrintToServer("[%s] This user does not exist in the database.", sChatTag);
}
}
}

// FUNCTION: DATABASE ESTABLISHED CALLBACK
public cDatabaseEstablished(Handle:owner, Handle:db, String:error[], any:data)
{
PrintDebug("Database connection established");
if (db == INVALID_HANDLE)
{
PrintToServer("[%s] Failed to connect: %s", sChatTag, error);
dbConnection = INVALID_HANDLE;
return;
}
else
{
PrintDebug("Success! Create tables if not exist!");
new String:sDBHndlName[128];
GetConVarString(cvCfgDatabaseToUse, sDBHndlName, sizeof(sDBHndlName));
strcopy(sCurrentDB, sizeof(sCurrentDB), sDBHndlName);
dbConnection = db;
new String:qCreateTable[255];
Format(qCreateTable, sizeof(qCreateTable), "DESCRIBE %smoneydata;", sTablePrefix);
new Handle:qCheckTableVersion = SQL_Query(dbConnection, qCreateTable);
if (qCheckTableVersion != INVALID_HANDLE)
{
if (SQL_GetRowCount(qCheckTableVersion) == 2)
{
Format(qCreateTable, sizeof(qCreateTable), "ALTER TABLE %smoneydata ADD lifetimemoney INT UNSIGNED;", sTablePrefix);
SQL_FastQuery(dbConnection, qCreateTable);
PrintDebug("Update database!");
}
else if (SQL_GetRowCount(qCheckTableVersion) == 3)
{
SQL_FetchRow(qCheckTableVersion);
SQL_FetchRow(qCheckTableVersion);
SQL_FetchRow(qCheckTableVersion); // lifetime money
new String:sLifeTimeMoney[255];
SQL_FetchString(qCheckTableVersion, 4, sLifeTimeMoney, sizeof(sLifeTimeMoney));
Format(qCreateTable, sizeof(qCreateTable), "ltc: '%s'", sLifeTimeMoney);
PrintDebug(qCreateTable);
if (strcmp(sLifeTimeMoney, "", false) == 0)
{
Format(qCreateTable, sizeof(qCreateTable), "ALTER TABLE %smoneydata CHANGE money money INT NOT NULL DEFAULT '0', CHANGE lifetimemoney lifetimemoney INT UNSIGNED NOT NULL DEFAULT '0';", sTablePrefix);
SQL_FastQuery(dbConnection, qCreateTable);
PrintDebug("Updating database!");
}
else
{
PrintDebug("Latest db version!");
}
}
CloseHandle(qCheckTableVersion);
}
else
{
Format(qCreateTable, sizeof(qCreateTable), "CREATE TABLE IF NOT EXISTS %smoneydata (steamid VARCHAR(32) NOT NULL PRIMARY KEY, money INT, lifetimemoney INT UNSIGNED);", sTablePrefix);
SQL_FastQuery(dbConnection, qCreateTable);
}
PrintDebug("Prechecking all users");
PrecheckAllUsers();
}
}

// FUNCTION: IGNORE QUERY CALLBACK
public cIgnoreQueryCallback(Handle:owner, Handle:hndl, String:error[], any:data)
{
return;
}

// FUNCTION: FULL CHECK CLIENT
public bool:FullCheckClient(client)
{
if (client < 1)
{
PrintDebug("Client < 0");
return false;
}

if (!IsClientConnected(client))
{
PrintDebug("Client not connected");
return false;
}

if (!IsClientInGame(client))
{
PrintDebug("Client not ingame");
return false;
}

if (IsFakeClient(client))
{
PrintDebug("Client is fake");
return false;
}

return true;
}

// FUNCTION: STATS SQL CALLBACK
public cStatsSQLCallback(Handle:owner, Handle:hndl, String:error[], any:data)
{
if (hndl == INVALID_HANDLE)
{
PrintToServer("[%s] Error in buy menu query: %s", sChatTag, error);
return;
}

SQL_FetchRow(hndl);
new iCurrentMoney = SQL_FetchInt(hndl, 0);
new iLifetimeMoney = SQL_FetchInt(hndl, 1);

PrintToChat(data, "[%s] You currently own \x04%i\x01 credits. You totally earned \x04%i\x01!", sChatTag, iCurrentMoney, iLifetimeMoney);
}

// FUNCTION: BUY MENU SQL CALLBACK
public cBuyMenuSQLCallback(Handle:owner, Handle:hndl, String:error[], any:data)
{
if (hndl == INVALID_HANDLE)
{
PrintToServer("[%s] Error in buy menu query: %s", sChatTag, error);
return;
}

SQL_FetchRow(hndl);
new iCurrentMoney = SQL_FetchInt(hndl, 0);

Client_iCurrentMoney[data] = iCurrentMoney;
new Handle:mBuyMenu = CreateMenu(hShopMenuHandler);
SetMenuTitle(mBuyMenu, "Your credits: %i", iCurrentMoney);

for(new i=0;i<SHOP_MENU_MAX;i++)
{
AddMenuItem(mBuyMenu,"",ShopMenuName[i]);
}

DisplayMenu(mBuyMenu, data, 20);
}

// FUNCTION: BUY MENU
public cBuyMenu(Handle:menu, MenuAction:action, param1, param2)
{
if (action == MenuAction_Select)
{
new String:info[32];
GetMenuItem(menu, param2, info, sizeof(info));

new String:qGetUsersMoney[255], String:sSteamId[32];
GetClientAuthString(param1, sSteamId, sizeof(sSteamId));
Format(qGetUsersMoney, sizeof(qGetUsersMoney), "SELECT money, '%s' FROM %smoneydata WHERE steamid = '%s';", info, sTablePrefix, sSteamId);
SQL_TQuery(dbConnection, cBuyMenuCallbackSQLCallback, qGetUsersMoney, param1);
}
else if (action == MenuAction_End)
{
CloseHandle(menu);
}
}

// FUNCTION: BUY MENU CALLBACK SQL CALLBACK
public cBuyMenuCallbackSQLCallback(Handle:owner, Handle:hndl, String:error[], any:data)
{
PrintDebug("MenuCallback!");
if (hndl == INVALID_HANDLE)
{
PrintToServer("[%s] Error in buy menu query: %s", sChatTag, error);
return;
}

PrintDebug("Get all data");
SQL_FetchRow(hndl);
new iCurrentMoney = SQL_FetchInt(hndl, 0);
new String:sBuyEntry[32];
SQL_FetchString(hndl, 1, sBuyEntry, sizeof(sBuyEntry));
new iBuyEntry = StringToInt(sBuyEntry);

if (iBuyEntry < 1024)
{
new String:sTitle[32], String:sPrice[32], String:sOnCmd[256], String:sOffCmd[256], String:sTime[32];
new String:sFilePath[PLATFORM_MAX_PATH];
BuildPath(Path_SM, sFilePath, sizeof(sFilePath),"configs/buymenu.txt");

if (!FileExists(sFilePath))
{
PrintToServer("[%s] buymenu.txt not found in configs folder!", sChatTag);
return;
}
new Handle:kv = CreateKeyValues("Buymenu");
FileToKeyValues(kv, sFilePath);
if (!KvJumpToKey(kv, sBuyEntry))
{
return;
}

KvGetString(kv, "title", sTitle, sizeof(sTitle));
KvGetString(kv, "price", sPrice, sizeof(sPrice));
KvGetString(kv, "oncmd", sOnCmd, sizeof(sOnCmd));
KvGetString(kv, "offcmd", sOffCmd, sizeof(sOffCmd));
KvGetString(kv, "time", sTime, sizeof(sTime));
new iPrice, Float:iTime;
iPrice = StringToInt(sPrice);
iTime = StringToFloat(sTime);
CloseHandle(kv);
if (iCurrentMoney < iPrice)
{
PrintDebug("Insufficient funds!");
PrintToChat(data, "[%s] You don't have enough credits to buy that! (Required: %i)", sChatTag, iPrice);
return;
}

PrintDebug("Parsing ?$#~|");
new String:sUserId[8], String:sName[128], String:sIndex[4], String:sSteamId[32], String:sQuotedName[128];
IntToString(GetClientUserId(data), sUserId, sizeof(sUserId));
GetClientName(data, sName, sizeof(sName));
GetClientAuthString(data, sSteamId, sizeof(sSteamId));
IntToString(data, sIndex, sizeof(sIndex));
Format(sQuotedName, sizeof(sQuotedName), "\"%s\"", sName);
ReplaceChar("=", "\"", sOnCmd);
ReplaceChar("?", sUserId, sOnCmd);
ReplaceChar("$", sName, sOnCmd);
ReplaceChar("#", sIndex, sOnCmd);
ReplaceChar("~", sSteamId, sOnCmd);
ReplaceChar("|", sQuotedName, sOnCmd);

RemoveMoney(data, iPrice);
PrintDebug("Running OnCmd");
ServerCommand(sOnCmd);

if (iTime > 0)
{
PrintDebug("Command has off time");
ReplaceChar("=", "\"", sOnCmd);
ReplaceChar("?", sUserId, sOffCmd);
ReplaceChar("$", sName, sOffCmd);
ReplaceChar("#", sIndex, sOffCmd);
ReplaceChar("~", sSteamId, sOffCmd);
ReplaceChar("|", sQuotedName, sOffCmd);

PrintDebug("Creating off timer");
new String:sSmallOffCmd[128];
strcopy(sSmallOffCmd, sizeof(sSmallOffCmd), sOffCmd);
new iDataStore = AddToConnecters(sSmallOffCmd); // abuse of the AddToConnecters, but who cares?
CreateTimer(iTime, tStopCommand, iDataStore);
}
}
else
{
iBuyEntry -= 1024;
if (strcmp(sNames[iBuyEntry], NULLNAME) == 0)
{
return;
}
if (iCurrentMoney < iCosts[iBuyEntry])
{
PrintDebug("Insufficient funds!");
PrintToChat(data, "[%s] You don't have enough credits to buy that! (Required: %i)", sChatTag, iCosts[iBuyEntry]);
return;
}
Call_StartFunction(INVALID_HANDLE, fCallbacks[iBuyEntry][0]);
Call_PushCell(data);
Call_PushCell(iCurrentMoney);
new Float:iResult;
if (Call_Finish(iResult) == SP_ERROR_NONE)
{
if (iResult > 0)
{
new iRemoveMoney = RoundToNearest(iCosts[iBuyEntry]*iResult);
if (iRemoveMoney > iCurrentMoney)
{
return;
}
RemoveMoney(data, iRemoveMoney);
}
}

if ((iStopTimes[iBuyEntry] > 0) && (fCallbacks[iBuyEntry][1] != INVALID_FUNCTION))
{
new String:sFitBuyEntry[128];
strcopy(sFitBuyEntry, sizeof(sFitBuyEntry), sBuyEntry);
new iStore = AddToConnecters(sFitBuyEntry);
iPushArray[iStore] = data;
CreateTimer(iStopTimes[iBuyEntry], tStopCommand, iStore);
}
}
}

// FUNCTION: REPLACE CHARACTER
public ReplaceChar(String:sSplitChar[], String:sReplace[], String:sString[256])
{
StrCat(sString, sizeof(sString), " ");
new String:sBuffer[16][256];
ExplodeString(sString, sSplitChar, sBuffer, sizeof(sBuffer), sizeof(sBuffer[]));
strcopy(sString, sizeof(sString), "");
for (new i = 0; i < sizeof(sBuffer); i++)
{
if (strcmp(sBuffer[i], "") == 0)
{
continue;
}
if (i != 0)
{
new String:sTmpStr[256];
Format(sTmpStr, sizeof(sTmpStr), "%s%s", sReplace, sBuffer[i]);
StrCat(sString, sizeof(sString), sTmpStr);
}
else
{
StrCat(sString, sizeof(sString), sBuffer[i]);
}
}
}

// FUNCTION: RESET MONEY MENU CALLBACK
public cResetMoneyMenuCallback(Handle:menu, MenuAction:action, client, item)
{
if (action == MenuAction_Select)
{
new String:info[32];
GetMenuItem(menu, item, info, sizeof(info));

if (strcmp(info, "no", false) == 0)
{
return;
}

new String:qResetMoney[255];
Format(qResetMoney, sizeof(qResetMoney), "UPDATE %smoneydata SET money = '%s';", sTablePrefix, info);
SQL_TQuery(dbConnection, cIgnoreQueryCallback, qResetMoney);
}
else if (action == MenuAction_End)
{
CloseHandle(menu);
}
}

// FUNCTION: RESET DATABASE MENU CALLBACK
public cResetDBMenuCallback(Handle:menu, MenuAction:action, client, item)
{
if (action == MenuAction_Select)
{
new String:info[32];
GetMenuItem(menu, item, info, sizeof(info));

if (strcmp(info, "no", false) == 0)
{
return;
}

new String:qReset[255];
Format(qReset, sizeof(qReset), "DROP TABLE %smoneydata;", sTablePrefix);
SQL_TQuery(dbConnection, cIgnoreQueryCallback, qReset);
PrintToServer("Reset db, dropping EVERYTHING!");
CloseHandle(dbConnection);
dbConnection = INVALID_HANDLE;
sCurrentDB = "INVALID_DATABASE";
InitializeDatabase();
}
else if (action == MenuAction_End)
{
CloseHandle(menu);
}
}

// FUNCTION: REGISTER MONEY
public RegisterMoney(Handle:hPlugin, iNumParams)
{
new String:sName[256], iBuyCosts, Float:iStopTime, Function:fStart, Function:fStop,iGroup;
GetNativeString(1, sName, sizeof(sName));
iBuyCosts = GetNativeCell(2);
iStopTime = GetNativeCell(3);
fStart = GetNativeCell(4);
fStop = GetNativeCell(5);
iGroup = GetNativeCell(6);

if (strlen(sName) == 0)
{
LogError("Error: Money name not given!");
return -1;
}
if (iBuyCosts <= 0)
{
LogError("Error: Buy costs <= 0!");
return -1;
}
new iClicks = 0;
new bool:run = true;
while (run)
{
if (strcmp(sNames[iBuyCount], NULLNAME) == 0)
{
break;
}
iBuyCount++;
if (iBuyCount >= sizeof(sNames))
{
iBuyCount = 0;
iClicks++;
}
if (iClicks >= 2)
{
LogError("Error: Too much money (max. %i)", sizeof(sNames));
return -1;
}
}
strcopy(sNames[iBuyCount], sizeof(sNames[]), sName);
iCosts[iBuyCount] = iBuyCosts;
fCallbacks[iBuyCount][0] = fStart;
fCallbacks[iBuyCount][1] = fStop;
if (iStopTime > 0)
{
iStopTimes[iBuyCount] = iStopTime;
}

iGroups[iBuyCount] = iGroup;
return iBuyCount;
}

// FUNCTION: DE-REGISTER MONEY
public DeregisterMoney(Handle:hPlugin, iNumParams)
{
new iMoneyId = GetNativeCell(1);
fCallbacks[iMoneyId][0] = INVALID_FUNCTION;
fCallbacks[iMoneyId][1] = INVALID_FUNCTION;
iCosts[iMoneyId] = 0;
sNames[iMoneyId] = NULLNAME;
iStopTimes[iMoneyId] = 0.0;
iGroups[iMoneyId] = SHOPMENU_OTHER_INDEX;
}

// FUNCTION: SHOP MENU HANDLER
public hShopMenuHandler(Handle:menu, MenuAction:action, param1, param2)
{
if (action == MenuAction_Select)
{
if(param2 < SHOP_MENU_MAX)
{
new String:sFilePath[PLATFORM_MAX_PATH];
BuildPath(Path_SM, sFilePath, sizeof(sFilePath),"configs/buymenu.txt");
if (!FileExists(sFilePath))
{
PrintToServer("[%s] buymenu.txt not found in configs folder!", sChatTag);
return;
}
new Handle:kv = CreateKeyValues("Buymenu");
FileToKeyValues(kv, sFilePath);

if (!KvGotoFirstSubKey(kv))
{
PrintToServer("[%s] Failed to read the buymenu.txt", sChatTag);
return;
}

new Handle:mBuyMenu = CreateMenu(cBuyMenu);
SetMenuTitle(mBuyMenu, "Your credits: %i", Client_iCurrentMoney[param1]);

for(new i = 0; i < sizeof(sNames); i++)
{
if (strcmp(sNames[i], NULLNAME) == 0 || iGroups[i] != param2)
{
continue;
}
new String:sInfo[128];
IntToString(i+1024, sInfo, sizeof(sInfo));
AddMenuItem(mBuyMenu, sInfo, sNames[i], (Client_iCurrentMoney[param1] >= iCosts[i] ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED));
}

decl String:buffer[255];
do
{
KvGetSectionName(kv, buffer, sizeof(buffer));
new group = KvGetNum(kv, "group",SHOPMENU_OTHER_INDEX);
if(group == param2)
{
new String:sTitle[32], String:sCosts[32], String:sText[64];
KvGetString(kv, "title", sTitle, sizeof(sTitle));
KvGetString(kv, "price", sCosts, sizeof(sCosts));
Format(sText, sizeof(sText), "%s (%s)", sTitle, sCosts);

AddMenuItem(mBuyMenu, buffer, sText, (Client_iCurrentMoney[param1] >= StringToInt(sCosts) ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED));
}
}
while (KvGotoNextKey(kv));
CloseHandle(kv);
DisplayMenu(mBuyMenu, param1, 20);
}
}
else if (action == MenuAction_End)
{
CloseHandle(menu);
}
}


// ********************************************* ************************************
// SECTION 8 - TIMERS
// ********************************************* ************************************
// TIMER: TICK!
public Action:tTick(Handle:timer)
{
InitializeDatabase();
if (dbConnection == INVALID_HANDLE)
{
return;
}

new String:err[255];
SQL_GetError(dbConnection, err, sizeof(err));
PrintDebug(err);

PrintDebug("Tick!");

new iCreditEarn = GetConVarInt(cvCreditPerTick);
for (new i = 1; i <= MaxClients; i++)
{
if (!FullCheckClient(i))
{
continue;
}

PrintDebug("Processing a client in tick!");

new iOnlyAlive = GetConVarInt(cvCfgTickOnlyAlive);
if ((iOnlyAlive == 1) && !IsPlayerAlive(i))
{
PrintDebug("Client is dead and dead clients don't get points!");
continue;
}

PrintDebug("He's got money!");
AddMoney(i, iCreditEarn);
new String:sTickNoise[128];
if (iCreditEarn == 1)
{
Format(sTickNoise, sizeof(sTickNoise), "[%s] You received 1 credit!", sChatTag);
}
else if (iCreditEarn > 1)
{
Format(sTickNoise, sizeof(sTickNoise), "[%s] You received %i credits!", sChatTag, iCreditEarn);
}
PrintNoise(sTickNoise, 3, i);
}
}

// TIMER: STOP COMMAND
public Action:tStopCommand(Handle:timer, any:data)
{
new iEntry = StringToInt(sConnectingClients[data]);
if (iEntry >= 1024)
{
iEntry -= 1024;
if (fCallbacks[iEntry][1] == INVALID_FUNCTION)
{
return;
}
new client = iPushArray[data];
Call_StartFunction(INVALID_HANDLE, fCallbacks[iEntry][1]);
Call_PushCell(client);
Call_Finish(_);
iPushArray[data] = 0;
}
else
{
PrintDebug("Off timer called with this command:");
PrintDebug(sConnectingClients[data]);
ServerCommand(sConnectingClients[data]);
}
RemoveFromConnecters(data);
}

Dr. McKay
02-14-2012, 22:40
public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
{
CreateNative("RegisterCandy", RegisterCandy);
CreateNative("DeregisterCandy", DeregisterCandy);
return APLRes_Success;
}

404UserNotFound
02-14-2012, 23:27
public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
{
CreateNative("RegisterCandy", RegisterCandy);
CreateNative("DeregisterCandy", DeregisterCandy);
return APLRes_Success;
}

Well I'll be damned. That fixed all the errors! Plugin's compiling with 0 errors, 0 warnings.

Thanks Dr. Mackay, you are awesome :D