Raised This Month: $32 Target: $400
 8% 

Level System trying to move to SQL Database


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
KerwinSweet2003
Junior Member
Join Date: Nov 2022
Old 05-26-2023 , 04:45   Level System trying to move to SQL Database
Reply With Quote #1

Hello,I have a Level System for Zombie Escape 1.6 (Escapers Zone),I'm trying to make it work with mySQL database because with nVault some players are losing their data randomly.


I tried to fix it but I failed

Code:
#include <zombie_escape>
#include <ze_vip>


// Native witch ze_infections plugin (by Urban)
native ze_get_infections(id);


// Defines
#define MAX_LEVEL 10
#define TASK_SHOWHUD 2020
#define TASK_DOUBLE 1133
#define REPEAT_TIME 60.0
#define ID_SHOWHUD (taskid - TASK_SHOWHUD)
#define LEVELUP "zombie_escape/new_level.wav"



enum
{
Host = 0,
User,
Pass,
DB
}

new const g_iMaxLevelsXP[MAX_LEVEL] =
{
20, // 1
60, // 2
120, // 3
200, // 4
300, // 5
400, // 6
580, // 7
700, // 8
920, // 9
1090, // 10

}

// Constants
new const g_szLevelsVault[] = "Levels"
new const g_szRanksVault[] = "Ranks"
new const g_szLogFile[] = "Levels.log" // MySQL Errors log file
new const g_szTable[] = 
" \
	CREATE TABLE IF NOT EXISTS `zombie_escape_level_system` \
	( \
		`SteamID` varchar(34) NOT NULL, \
		`Levels` int(16) NOT NULL, \
		`Escapes` int(16) NOT NULL \
	); \
"

// Messages
const Float:HUD_SPECT_X = -1.0
const Float:HUD_SPECT_Y = 0.70
const Float:HUD_STATS_X = 0.015
const Float:HUD_STATS_Y = 0.33

const HUD_STATS_ZOMBIE_R = 0
const HUD_STATS_ZOMBIE_G = 255
const HUD_STATS_ZOMBIE_B = 0

const HUD_STATS_HUMAN_R = 0
const HUD_STATS_HUMAN_G = 255
const HUD_STATS_HUMAN_B = 0

const HUD_STATS_SPEC_R = 0
const HUD_STATS_SPEC_G = 255
const HUD_STATS_SPEC_B = 0

// Variables
new g_iLevel[33],
g_iXP[33],
g_iMaxXP[33],
Float:g_fDamage[33],
g_MsgSync,
g_iLevelsVaultHandle,
g_Online,
g_iRanksVaultHandle,
Handle:g_hTuple,
Fw_LevelUP,
ForwardReturn,
bool:g_bIsDoubleHours

// Cvars
new g_pCvarZombieInfect,
g_pCvarEscapeSuccess,
g_pCvarEnableDamage,
g_pCvarRequiredDamage,
g_pCvarDamageAward,
g_pCvarStartXP,
g_pCvarPercentageStyle,
g_pCvarStartFromZero,
g_pCvarAddCommas,
g_pCvarLevelEffects,
g_pCvarSaveType,
g_pCvarDBInfo[4],
g_pCvarDoubleXP

public plugin_natives()
{
register_native("ze_get_user_xp", "native_ze_get_user_xp", 1)
register_native("ze_set_user_xp", "native_ze_set_user_xp", 1)
register_native("ze_get_user_level", "native_ze_get_user_level", 1)
register_native("ze_set_user_level", "native_ze_set_user_level", 1)
register_native("ze_get_user_max_xp", "native_ze_get_user_max_xp", 1)
}

public plugin_precache()
{
	precache_sound(LEVELUP)
}

public plugin_init()
{
	register_plugin("[ZE] Level-XP System", "1.9", "Raheem/JaCk")

// Hook Chains
RegisterHookChain(RG_CBasePlayer_TakeDamage, "Fw_TakeDamage_Post", 1)

Fw_LevelUP = CreateMultiForward("ze_on_levelup", ET_IGNORE, FP_CELL)

// Cvars
g_pCvarZombieInfect = register_cvar("ze_zombie_infect", "0")
g_pCvarEscapeSuccess = register_cvar("ze_escape_success", "1")
g_pCvarEnableDamage = register_cvar("ze_enable_dmg", "0")
g_pCvarRequiredDamage = register_cvar("ze_required_dmg", "50.0")
g_pCvarDamageAward = register_cvar("ze_dmg_award", "3")
g_pCvarStartXP = register_cvar("ze_start_xp", "1")
g_pCvarPercentageStyle = register_cvar("ze_enable_percentage_style", "0")
g_pCvarStartFromZero = register_cvar("ze_new_level_zero_xp", "1")
g_pCvarAddCommas = register_cvar("ze_add_commas_to_xp", "1")
g_pCvarLevelEffects = register_cvar("ze_level_up_effects", "0")
g_pCvarDoubleXP = register_cvar("ze_double_xp", "21-10")

g_pCvarSaveType = register_cvar("ze_levels_save_type", "0")
g_pCvarDBInfo[Host] = register_cvar("ze_levels_host", "127.0.0.1")
g_pCvarDBInfo[User] = register_cvar("ze_levels_user", "root")
g_pCvarDBInfo[Pass] = register_cvar("ze_levels_pass", "password")
g_pCvarDBInfo[DB] = register_cvar("ze_levels_dbname", "levels_db")

// Messages
g_MsgSync = CreateHudSyncObj()

	set_task(0.1, "Delay_MySQL_Init")

DoubleHours()

if (g_bIsDoubleHours)
{
	set_task(REPEAT_TIME, "HappyHours", TASK_DOUBLE, _, _, "b")
}
}

public plugin_end()
{
	if (get_pcvar_num(g_pCvarSaveType))
	{
	if (g_hTuple != Empty_Handle)
	{
		SQL_FreeHandle(g_hTuple)
	}

	}
}

public Delay_MySQL_Init()
{
	MySQL_Init()
}

public MySQL_Init()
{
	if (!get_pcvar_num(g_pCvarSaveType))
	return

new szHost[64], szUser[32], szPass[32], szDB[128]

get_pcvar_string(g_pCvarDBInfo[Host], szHost, charsmax(szHost))
get_pcvar_string(g_pCvarDBInfo[User], szUser, charsmax(szUser))
get_pcvar_string(g_pCvarDBInfo[Pass], szPass, charsmax(szPass))
get_pcvar_string(g_pCvarDBInfo[DB], szDB, charsmax(szDB))

g_hTuple = SQL_MakeDbTuple(szHost, szUser, szPass, szDB)

// Let's ensure that the g_hTuple will be valid, we will access the database to make sure
new iErrorCode, szError[512], Handle:hSQLConnection

hSQLConnection = SQL_Connect(g_hTuple, iErrorCode, szError, charsmax(szError))


if (hSQLConnection != Empty_Handle)
{
	log_amx("[MySQL][LVL] Successfully connected to host: %s (ALL IS OK).", szHost)
	SQL_FreeHandle(hSQLConnection)
}
else
{
	// Disable plugin
	set_fail_state("[LVL] Failed to connect to MySQL database: %s.", szError)
}

SQL_ThreadQuery(g_hTuple, "QueryCreateTable", g_szTable)
}

public QueryCreateTable(iFailState, Handle:hQuery, szError[], iError, szData[], iSize, Float:flQueueTime)
{
SQL_IsFail(iFailState, iError, szError, g_szLogFile)
}

public client_putinserver(id)
{
if(is_user_hltv(id) || is_user_bot(id))
	return
	
	// Just 1 second delay
	set_task(5.0, "DelayLoad", id)
	
	// Other tasks
	set_task(1.0, "Show_Hud", id+TASK_SHOWHUD, _, _, "b")
	
	if (g_bIsDoubleHours)
	{
	    set_task(REPEAT_TIME, "HappyHours", id+TASK_DOUBLE, _, _, "b")
	}

	if(ze_is_user_vip(id) & VIP_B)
	{
		g_Online++
	}
}

public HappyHours(taskid)
{
	DoubleHours()
	
	if (!g_bIsDoubleHours)
		remove_task(taskid)
	
	new szDoubleHours[32]
	
	get_pcvar_string(g_pCvarDoubleXP, szDoubleHours, charsmax(szDoubleHours))
	
	set_hudmessage(0, 255, 0, -0.5, 0.20, 0, 0.0, 10.0)
	show_hudmessage(0, "Double Experience Time")
}

public DelayLoad(id)
{
	// Load his data
	LoadData(id)
}

public client_disconnected(id)
{
	if(is_user_hltv(id) || is_user_bot(id))
		return
	
	remove_task(id+TASK_SHOWHUD)
	remove_task(id)

	if(ze_is_user_vip(id) & VIP_B)
	{
		g_Online--
	}
}

public Show_Hud(taskid)
{  
	new iPlayer = ID_SHOWHUD
	
	if (!is_user_alive(iPlayer))
	{
		iPlayer = pev(iPlayer, pev_iuser2)
		
		if (!is_user_alive(iPlayer))
			return
	}
	
	if (get_pcvar_num(g_pCvarPercentageStyle) != 0)
	{
		if(iPlayer != ID_SHOWHUD)
		{
			set_hudmessage(HUD_STATS_SPEC_R, HUD_STATS_SPEC_G, HUD_STATS_SPEC_B, HUD_SPECT_X, HUD_SPECT_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
			ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40 ^n[Escapes] - %0.2f %", g_iLevel[iPlayer], (float(g_iXP[iPlayer])/float(g_iMaxXP[iPlayer]), g_Online) * 100.0)
		}
		else if (ze_is_user_zombie(iPlayer))
		{
			new zeInfNeed = get_cvar_num("ze_infections_num")
			
			set_hudmessage(HUD_STATS_ZOMBIE_R, HUD_STATS_ZOMBIE_G, HUD_STATS_ZOMBIE_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
			ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40 ^n[Escapes] - %0.2f %^n[Infections] - %d/%d", g_iLevel[ID_SHOWHUD], (float(g_iXP[ID_SHOWHUD])/float(g_iMaxXP[ID_SHOWHUD]), g_Online) * 100.0, ze_get_infections(ID_SHOWHUD), zeInfNeed)
		}
		else
		{
			set_hudmessage(HUD_STATS_HUMAN_R, HUD_STATS_HUMAN_G, HUD_STATS_HUMAN_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
			ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40 ^n[Escapes] - %0.2f %", g_iLevel[ID_SHOWHUD], (float(g_iXP[ID_SHOWHUD])/float(g_iMaxXP[ID_SHOWHUD]), g_Online) * 100.0)
		}
	}
	else
	{
		if(iPlayer != ID_SHOWHUD)
		{
			if (get_pcvar_num(g_pCvarAddCommas) == 1)
			{
				new szSpecXP[15], szSpecMaxXP[15]
				
				AddCommas(g_iXP[iPlayer], szSpecXP, charsmax(szSpecXP))
				AddCommas(g_iMaxXP[iPlayer], szSpecMaxXP, charsmax(szSpecMaxXP))
				
				set_hudmessage(HUD_STATS_SPEC_R, HUD_STATS_SPEC_G, HUD_STATS_SPEC_B, HUD_SPECT_X, HUD_SPECT_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n[Escapes] - %s/%s", g_iLevel[iPlayer], szSpecXP, szSpecMaxXP, g_Online)
			}
			else
			{
				set_hudmessage(HUD_STATS_SPEC_R, HUD_STATS_SPEC_G, HUD_STATS_SPEC_B, HUD_SPECT_X, HUD_SPECT_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n[Escapes] - %d/%d", g_iLevel[iPlayer], g_iXP[iPlayer], g_iMaxXP[iPlayer], g_Online)
			}  
		}
		else if (ze_is_user_zombie(iPlayer))
		{
			if (get_pcvar_num(g_pCvarAddCommas) == 1)
			{
				new zeInfNeed = get_cvar_num("ze_infections_num")
				new szZombieXP[15], szZombieMaxXP[15]
				
				AddCommas(g_iXP[ID_SHOWHUD], szZombieXP, charsmax(szZombieXP))
				AddCommas(g_iMaxXP[ID_SHOWHUD], szZombieMaxXP, charsmax(szZombieMaxXP))
				
				set_hudmessage(HUD_STATS_ZOMBIE_R, HUD_STATS_ZOMBIE_G, HUD_STATS_ZOMBIE_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n[Escapes] - %s/%s^n[Infections] - %d/%d", g_iLevel[ID_SHOWHUD], szZombieXP, szZombieMaxXP, ze_get_infections(ID_SHOWHUD), zeInfNeed, g_Online)
			}
			else
			{
				new zeInfNeed = get_cvar_num("ze_infections_num")
				set_hudmessage(HUD_STATS_ZOMBIE_R, HUD_STATS_ZOMBIE_G, HUD_STATS_ZOMBIE_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n[Escapes] - %d/%d^n[Infections] - %d/%d", g_iLevel[ID_SHOWHUD], g_iXP[ID_SHOWHUD], g_iMaxXP[ID_SHOWHUD], ze_get_infections(ID_SHOWHUD), zeInfNeed, g_Online)
			}
		}
		else
		{
			if (get_pcvar_num(g_pCvarAddCommas) == 1)
			{
				new szHumanXP[15], szHumanMaxXP[15]
				
				AddCommas(g_iXP[ID_SHOWHUD], szHumanXP, charsmax(szHumanXP))
				AddCommas(g_iMaxXP[ID_SHOWHUD], szHumanMaxXP, charsmax(szHumanMaxXP))
				
				set_hudmessage(HUD_STATS_HUMAN_R, HUD_STATS_HUMAN_G, HUD_STATS_HUMAN_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n[Escapes] - %s/%s", g_iLevel[ID_SHOWHUD], szHumanXP, szHumanMaxXP, g_Online)
			}
			else
			{
				set_hudmessage(HUD_STATS_HUMAN_R, HUD_STATS_HUMAN_G, HUD_STATS_HUMAN_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n^n[Infections] - %d/%d", g_iLevel[ID_SHOWHUD], g_iXP[ID_SHOWHUD], g_iMaxXP[ID_SHOWHUD], g_Online)
			}
		}
	}
}

public ze_roundend(WinTeam)
{
	if (WinTeam == ZE_TEAM_HUMAN)
	{
		new iXP = g_bIsDoubleHours ? (get_pcvar_num(g_pCvarEscapeSuccess) * 2) : get_pcvar_num(g_pCvarEscapeSuccess)
		
		for(new id = 1; id <= get_member_game(m_nMaxPlayers); id++)
		{
			if( (ze_get_vip_flags(id) & VIP_B) )
			{
				iXP *= 2
			}

			if (!is_user_alive(id) || ze_is_user_zombie(id))
				continue
			
			Reward(id, (g_iXP[id] + iXP))
			ze_colored_print(id, "Good Job,Humans have escaped the Zombies! +!g%d !yEscape(s)", (iXP))
		}
	}
	
	remove_task(TASK_SHOWHUD)
}

public Check_User_Level(id)
{
	if (!is_user_connected(id))
		return
	
	if (g_iLevel[id] < MAX_LEVEL)
	{
		new szName[32]
		
		if (g_iXP[id] >= g_iMaxXP[id])
		{
			if (get_pcvar_num(g_pCvarStartFromZero) == 1)
			{
				g_iXP[id] = 0
			}
			
			g_iLevel[id]++
			g_iMaxXP[id] = g_iMaxLevelsXP[g_iLevel[id]]
			get_user_name(id, szName, charsmax(szName))
			ze_colored_print(0, "Congratulations to !g%s !yfor archiving (!gLevel!y:!g%i!y) and !y(!g%d escapes!y)!", szName, g_iLevel[id] ,g_iXP[id])
			ExecuteForward(Fw_LevelUP, ForwardReturn, id)
			SaveData(id)
			PlaySound(0, LEVELUP)
			
			if (get_pcvar_num(g_pCvarLevelEffects) != 0)
			{
				// Screen Fade
				message_begin(MSG_ONE, get_user_msgid("ScreenFade"), {0,0,0}, id)
				write_short(4096*2)
				write_short(4096*5)
				write_short(0x0001)
				write_byte(random(256))
				write_byte(random(256))
				write_byte(random(256))
				write_byte(150)
				message_end()
				
				// Screen Shake
				message_begin(MSG_ONE, get_user_msgid("ScreenShake"), {0,0,0}, id)
				write_short(255<<14)
				write_short(10<<14)
				write_short(255<<14)
				message_end()
			}
		}
	}
}

public ze_user_infected(iVictim, iInfector)
{
	if (iInfector == 0)
		return
	
	new iXP = g_bIsDoubleHours ? (get_pcvar_num(g_pCvarZombieInfect) * 2) : get_pcvar_num(g_pCvarZombieInfect)

	if((ze_get_vip_flags(iInfector) & VIP_B))
    {
        iXP *= 2
    }
	Reward(iInfector, (g_iXP[iInfector] + iXP))
}

public Fw_TakeDamage_Post(iVictim, iInflictor, iAttacker, Float:fDamage, bitsDamageType)
{
	// Player Damage Himself
	if (iVictim == iAttacker || !is_user_alive(iVictim) || !is_user_alive(iAttacker) || ze_is_user_zombie(iAttacker) || !get_pcvar_num(g_pCvarEnableDamage))
		return HC_CONTINUE
	
	// Same Team?
	if (get_member(iAttacker, m_iTeam) == get_member(iVictim, m_iTeam))
		return HC_CONTINUE
	
	// Store Damage For every Player
	g_fDamage[iAttacker] += fDamage
	
	// Damage Calculator Equal or Higher than needed damage
	if (g_fDamage[iAttacker] >= get_pcvar_float(g_pCvarRequiredDamage))
	{
		// Player did damage that a multiplication of the cvar? Increase coins by this factor
		new iMultiplier = floatround(g_fDamage[iAttacker] / get_pcvar_float(g_pCvarRequiredDamage))
		new iXP = ((g_bIsDoubleHours ? (get_pcvar_num(g_pCvarDamageAward) * 2) : get_pcvar_num(g_pCvarDamageAward)) * iMultiplier)
		Reward(iAttacker, (g_iXP[iAttacker] + iXP))
		
		// Rest The Damage Calculator
		g_fDamage[iAttacker] = 0.0
	}
	return HC_CONTINUE
}

public Reward(id, XP)
{
	if ((g_iLevel[id] + 1) < MAX_LEVEL)
	{
		g_iXP[id] = XP
		Check_User_Level(id)
	}
	else
	{
		if ((g_iXP[id] + XP) >= g_iMaxLevelsXP[MAX_LEVEL - 1])
		{
			g_iXP[id] = g_iMaxXP[id] = g_iMaxLevelsXP[MAX_LEVEL - 1]
		}
	}
	SaveData(id)
}

public SaveData(id)
{
	new szAuthID[35], szName[64]
	get_user_authid(id, szAuthID, charsmax(szAuthID))
	get_user_name(id, szName, charsmax(szName))
	
	if (!get_pcvar_num(g_pCvarSaveType))
	{
		new szData[256]
		formatex(szData , charsmax(szData), "%i %i", g_iLevel[id], g_iXP[id])
		
		// Open the Vaults
		g_iLevelsVaultHandle = nvault_open(g_szLevelsVault)
		g_iRanksVaultHandle = nvault_open(g_szRanksVault)
		
		// Saves His Data
		nvault_set(g_iLevelsVaultHandle, szAuthID, szData)
		nvault_set(g_iRanksVaultHandle, szAuthID, szName)
		
		// Close Vaults
		nvault_close(g_iLevelsVaultHandle)
		nvault_close(g_iRanksVaultHandle)
		
		new logtext[196], times[25], dest[64]
		get_localinfo("amxx_logs",dest,charsmax(dest))
		format(dest,charsmax(dest),"%s/Levels,Escapes Logs",dest)
		if(!dir_exists(dest))
		{
			mkdir(dest)
		}
		get_time("%Y",times,4)
		format(dest,charsmax(dest),"%s/%s",dest,times)
		if(!dir_exists(dest))
		{
			mkdir(dest)
		}
		get_time("%B",times,charsmax(times))
		format(dest,charsmax(dest),"%s/%s.txt",dest,times)
		if(!file_exists(dest))
		{
			write_file(dest,"")
		}
		get_time( "%d.%m.%Y", times, charsmax(times) );
		formatex(logtext, charsmax(logtext), "[%s] [Name: %s] - [SteamID %s] - [[Level] - %i] - [XP: %i]", times, szName, szAuthID, g_iLevel[id], g_iXP[id]);
		write_file(dest, logtext)
    
		
	}
	else
	{
		new szData[256]
		formatex(szData , charsmax(szData), "%i %i", g_iLevel[id], g_iXP[id])
		
		new szQuery[128]
		formatex(szQuery, charsmax(szQuery), "UPDATE `zombie_escape_level_system` SET `Levels` = '%d', `Escapes` = '%d' WHERE ( 'SteamID' = '%s');", g_iLevel[id],  g_iXP[id], szAuthID)
		SQL_ThreadQuery(g_hTuple, "QuerySelectData", szQuery)
	}
}

public QuerySetData(iFailState, Handle:hQuery, szError[], iError, szData[], iSize, Float:flQueueTime)
{
	SQL_IsFail(iFailState, iError, szError, g_szLogFile)
}

public QuerySetData2(iFailState, Handle:hQuery, szError[], iError, szData[], iSize, Float:flQueueTime)
{
	SQL_IsFail(iFailState, iError, szError, g_szLogFile)
}

public LoadData(id)
{
	new szAuthID[35], szName[64], szIP[35]
	get_user_authid(id, szAuthID, charsmax(szAuthID))
	get_user_name(id, szName, charsmax(szName))
	get_user_ip(id, szIP, charsmax(szIP), 1)
	
	if (!get_pcvar_num(g_pCvarSaveType))
	{
		new szData[256], iTimestamp, iExists
		
		// Open the Vault
		g_iLevelsVaultHandle = nvault_open(g_szLevelsVault)
		
		iExists = nvault_lookup(g_iLevelsVaultHandle, szAuthID, szData, charsmax(szData), iTimestamp)
		
		// Close Vault
		nvault_close(g_iLevelsVaultHandle)
		
		if (!iExists)
		{
			g_iLevel[id] = 0
			g_iXP[id] = get_pcvar_num(g_pCvarStartXP)
			SaveData(id)
			ze_colored_print(id, "Account Created!y: Name!y: (!g%s!y) SteamID !y^"!g%s!y^"", szName, szAuthID)
		}
		else
		{
			new iLevel[32], iXP[32]
			parse(szData, iLevel, 31, iXP, 31)
			
			g_iLevel[id] = str_to_num(iLevel)
			g_iXP[id] = str_to_num(iXP)

			if((ze_get_vip_flags(id) & VIP_B))
			{
				ze_colored_print(id, "!gAccount Loaded!y: (Name!y: !g%s!y) !t/!y (SteamID !y^"!g%s^"!y)", szName, szAuthID)
			}
			else
			{
				ze_colored_print(id, "!gAccount Loaded!y: (Name!y: !g%s!y) !t/!y (SteamID !y^"!g%s^"!y)", szName, szAuthID)
			}
		}
		
		g_iMaxXP[id] = g_iMaxLevelsXP[g_iLevel[id]]
	}
	else
	{
		new szQuery[128], szData[5]
		formatex(szQuery, charsmax(szQuery), "SELECT * FROM `zombie_escape_level_system` WHERE ( 'SteamID' = '%s' );", szAuthID)
		
		num_to_str(id, szData, charsmax(szData))
		SQL_ThreadQuery(g_hTuple, "QuerySelectData", szQuery, szData, charsmax(szData))
	}
}

public QuerySelectData(iFailState, Handle:hQuery, szError[], iError, szData[])
{
	if (SQL_IsFail(iFailState, iError, szError, g_szLogFile))
		return
	
	new id = str_to_num(szData)

	
	// No results for this query means this is new player
	if (!SQL_NumResults(hQuery))
	{
		g_iLevel[id] = 0
		g_iXP[id] = get_pcvar_num(g_pCvarStartXP)

		new szAuthID[35], szName[64], szIP[35]
		get_user_authid(id, szAuthID, charsmax(szAuthID))
		get_user_name(id, szName, charsmax(szName))
		get_user_ip(id, szIP, charsmax(szIP), 1)

		new szQuery[128]

		formatex(szQuery, charsmax(szQuery), "INSERT INTO `zombie_escape_level_system` (`SteamID`, `Levels`, `Escapes`) VALUES ('%s', '%d', '%d');", szAuthID, g_iLevel[id], g_iXP[id])
		SQL_ThreadQuery(g_hTuple, "QueryInsertData", szQuery)

		return
	}
	// Get the "Escape" column number (It's 2, always i don't like to hardcode :p)
	new iXP_Column = SQL_FieldNameToNum(hQuery, "Escapes")
	new iLevels_Column = SQL_FieldNameToNum(hQuery, "Levels")
	
	// Read the coins of this player
	g_iXP[id] = SQL_ReadResult(hQuery, iXP_Column)
	g_iLevel[id] = SQL_ReadResult(hQuery, iLevels_Column)
}

public QueryInsertData(iFailState, Handle:hQuery, szError[], iError, szData[], iSize, Float:flQueueTime)
{
	SQL_IsFail(iFailState, iError, szError, g_szLogFile)
}

public native_ze_get_user_xp(id)
{
	if(!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false;
	}
	
	return g_iXP[id]
}

public native_ze_set_user_xp(id, amount)
{
	if(!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false
	}
	
	DoubleHours()
	new addedXP = (amount - g_iXP[id])
	new iXP = g_bIsDoubleHours ? (addedXP * 2) : addedXP
	Reward(id, g_iXP[id] + iXP)
	return true
}

public native_ze_get_user_level(id)
{
	if(!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false;
	}
	
	return g_iLevel[id]
}

public native_ze_set_user_level(id, amount)
{
	if(!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false
	}
	
	if (amount > MAX_LEVEL)
	{
		log_error(AMX_ERR_NATIVE, "Level must be less than or equal to MAX_LEVEL (%d)", MAX_LEVEL)
		return false
	}
	
	g_iLevel[id] = amount
	
	if (get_pcvar_num(g_pCvarStartFromZero) == 1)
	{
		g_iXP[id] = 0
	}
	SaveData(id)
	
	return true
}

public native_ze_get_user_max_xp(id)
{
	if(!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false
	}
	
	return g_iMaxXP[id]
}

stock DoubleHours()
{
	new szTime[3], szDoubleHours[32], szDoubleHours_Start[32], szDoubleHours_End[32]
	get_time("%H", szTime, charsmax(szTime))
	
	get_pcvar_string(g_pCvarDoubleXP, szDoubleHours, charsmax(szDoubleHours))
	
	for (new ch = 0; ch <= charsmax(szDoubleHours); ch++)
	{
		if (szDoubleHours[ch] == '-')
			szDoubleHours[ch] = ' '
	}
	
	parse(szDoubleHours, szDoubleHours_Start, charsmax(szDoubleHours_Start), szDoubleHours_End, charsmax(szDoubleHours_End))
	
	new iTime, iDoubleHourStart, iDoubleHourEnd
	
	iTime = str_to_num(szTime)
	iDoubleHourStart = str_to_num(szDoubleHours_Start)
	iDoubleHourEnd = str_to_num(szDoubleHours_End)
	
	if (iDoubleHourEnd > iTime >= iDoubleHourStart)
	{
		g_bIsDoubleHours = true
	}
	else
	{
		g_bIsDoubleHours = false
	}
}
I get this error in console when the time comes to get the XP or Level

Code:
L 05/26/2023 - 10:01:20: [MySQL] Query failed: Duplicate entry 'STEAM_0:0:224689198' for key 'zombie_escape_level_system.PRIMARY'

There is a plugin that SQL works and I tried to impliment the code to the Level System,which I got the console error above.

ze_coins_system

Code:
#include <zombie_escape>

// Static (Change it if you need)
new const g_szVaultName[] = "Escape_Coins"
new const g_szLogFile[] = "Escape-Coins.log" // MySQL Errors log file

// MySQL Table
new const g_szTable[] = 
" \
	CREATE TABLE IF NOT EXISTS `zombie_escape` \
	( \
		`Nick` varchar(64) NOT NULL, \
		`IP` varchar(34) NOT NULL, \
		`SteamID` varchar(34) NOT NULL, \
		`EC` int(16) NOT NULL, \
		PRIMARY KEY (`Nick`) \
	); \
"

// Variables
new g_iMaxClients,
	g_iVaultHandle,
	g_iEscapeCoins[33], 
	Float:g_flDamage[33],
	Handle:g_hTuple

// Cvars
new g_pCvarEscapeSuccess, 
	g_pCvarHumanInfected, 
	g_pCvarDamage, 
	g_pCvarDamageCoins, 
	g_pCvarStartCoins, 
	g_pCvarMaxCoins,
	g_pCvarEarnChatNotice,
	g_pCvarSaveType,
	g_pCvarDBInfo[4]

// Database
enum
{
	Host = 0,
	User,
	Pass,
	DB
}

// Natives
public plugin_natives()
{
	register_native("ze_get_escape_coins", "native_ze_get_escape_coins", 1)
	register_native("ze_set_escape_coins", "native_ze_set_escape_coins", 1)
}

public plugin_init()
{
	register_plugin("[ZE] Escape Coins System", ZE_VERSION, AUTHORS)
	
	// Hook Chains
	RegisterHookChain(RG_CBasePlayer_TakeDamage, "Fw_TakeDamage_Post", 1)
	
	// Commands
	//register_clcmd("say /EC", "Coins_Info")
	//register_clcmd("say_team /EC", "Coins_Info")
	
	// Static Values
	g_iMaxClients = get_member_game(m_nMaxPlayers)
	
	// Cvars
	g_pCvarSaveType = register_cvar("ze_coins_save_type", "0")
	g_pCvarEscapeSuccess = register_cvar("ze_escape_success_coins", "15")
	g_pCvarHumanInfected = register_cvar("ze_human_infected_coins", "5")
	g_pCvarDamage = register_cvar("ze_damage_required", "300")
	g_pCvarDamageCoins = register_cvar("ze_damage_coins", "4")
	g_pCvarStartCoins = register_cvar("ze_start_coins", "50")
	g_pCvarMaxCoins = register_cvar("ze_max_coins", "200000")
	g_pCvarEarnChatNotice = register_cvar("ze_earn_chat_notice", "1")
	
	g_pCvarDBInfo[Host] = register_cvar("ze_ec_host", "localhost")
	g_pCvarDBInfo[User] = register_cvar("ze_ec_user", "user")
	g_pCvarDBInfo[Pass] = register_cvar("ze_ec_pass", "pass")
	g_pCvarDBInfo[DB] = register_cvar("ze_ec_dbname", "dbname")
	
	// Initialize MySQL - Delay 0.1 second required so we make sure that our zombie_escape.cfg already executed and cvars values loaded from it
	set_task(0.1, "Delay_MySQL_Init")
}

public Coins_Info(id)
{
	ze_colored_print(id, "%L", LANG_PLAYER, "COINS_INFO", g_iEscapeCoins[id])
}

public Delay_MySQL_Init()
{
	MySQL_Init()
}

public MySQL_Init()
{
	if (!get_pcvar_num(g_pCvarSaveType))
		return
	
	new szHost[64], szUser[32], szPass[32], szDB[128]
	
	get_pcvar_string(g_pCvarDBInfo[Host], szHost, charsmax(szHost))
	get_pcvar_string(g_pCvarDBInfo[User], szUser, charsmax(szUser))
	get_pcvar_string(g_pCvarDBInfo[Pass], szPass, charsmax(szPass))
	get_pcvar_string(g_pCvarDBInfo[DB], szDB, charsmax(szDB))
	
	g_hTuple = SQL_MakeDbTuple(szHost, szUser, szPass, szDB)
	
	// Let's ensure that the g_hTuple will be valid, we will access the database to make sure
	new iErrorCode, szError[512], Handle:hSQLConnection
	
	hSQLConnection = SQL_Connect(g_hTuple, iErrorCode, szError, charsmax(szError))
	
	if(hSQLConnection != Empty_Handle)
	{
		log_amx("[MySQL] Successfully connected to host: %s (ALL IS OK).", szHost)
		SQL_FreeHandle(hSQLConnection)
	}
	else
	{
		// Disable plugin, and display the error
		set_fail_state("Failed to connect to MySQL database: %s", szError)
	}
	
	// Create our table
	SQL_ThreadQuery(g_hTuple, "QueryCreateTable", g_szTable)
}

public QueryCreateTable(iFailState, Handle:hQuery, szError[], iError, szData[], iSize, Float:flQueueTime) 
{
	SQL_IsFail(iFailState, iError, szError, g_szLogFile)
}

public client_putinserver(id)
{
	if (is_user_bot(id) || is_user_hltv(id))
		return
	
	// Just 1 second delay
	set_task(1.0, "DelayLoad", id)
}

public DelayLoad(id)
{
	LoadCoins(id)
}

public plugin_end()
{
	if (get_pcvar_num(g_pCvarSaveType))
	{
		if (g_hTuple != Empty_Handle)
		{
			SQL_FreeHandle(g_hTuple)
		}
	}
}

public ze_roundend(WinTeam)
{
	if (WinTeam == ZE_TEAM_HUMAN)
	{
		for(new id = 1; id <= g_iMaxClients; id++)
		{
			g_flDamage[id] = 0.0
			
			if (!is_user_alive(id) || ze_is_user_zombie(id))
				continue
			
			g_iEscapeCoins[id] += get_pcvar_num(g_pCvarEscapeSuccess)
			
			SaveCoins(id)
			
			if (get_pcvar_num(g_pCvarEarnChatNotice))
			{
				ze_colored_print(id, "%L", LANG_PLAYER, "ESCAPE_SUCCESS_COINS", get_pcvar_num(g_pCvarEscapeSuccess))
			}
		}
	}
}

public ze_user_infected(iVictim, iInfector)
{
	if (iInfector == 0) // Server ID
		return

	g_iEscapeCoins[iInfector] += get_pcvar_num(g_pCvarHumanInfected)
	
	SaveCoins(iInfector)
	
	if (get_pcvar_num(g_pCvarEarnChatNotice))
	{
		ze_colored_print(iInfector, "%L", LANG_PLAYER, "HUMAN_INFECTED_COINS", get_pcvar_num(g_pCvarHumanInfected))
	}
}

public Fw_TakeDamage_Post(iVictim, iInflictor, iAttacker, Float:fDamage, bitsDamageType)
{
	// Player Damage Himself
	if(!is_user_connected(iVictim) || !is_user_connected(iAttacker) || iVictim == iAttacker || rg_is_player_can_takedamage(iVictim,iAttacker))
		return HC_CONTINUE
	
	/* // Two Players From one Team
	if (get_member(iAttacker, m_iTeam) == get_member(iVictim, m_iTeam))
		return HC_CONTINUE */
	
	// iVictim or iAttacker Not Alive
	if (!is_user_alive(iVictim) || !is_user_alive(iAttacker))
		return HC_CONTINUE
	
	// Attacker is Zombie
	if (get_member(iAttacker, m_iTeam) == TEAM_TERRORIST)
		return HC_CONTINUE
	
	// Store Damage For every Player
	g_flDamage[iAttacker] += fDamage
	
	// Damage Calculator Equal or Higher than needed damage
	while (g_flDamage[iAttacker] >= get_pcvar_float(g_pCvarDamage))
	{
		g_iEscapeCoins[iAttacker] += (get_pcvar_num(g_pCvarDamageCoins))
		g_flDamage[iAttacker] -= get_pcvar_float(g_pCvarDamage)
	}
		
	SaveCoins(iAttacker)

	return HC_CONTINUE
}

LoadCoins(id)
{
	new szAuthID[35], szName[64]
	get_user_name(id, szName, charsmax(szName))
	get_user_authid(id, szAuthID, charsmax(szAuthID))
	
	if (!get_pcvar_num(g_pCvarSaveType))
	{
		// Open the Vault
		g_iVaultHandle = nvault_open(g_szVaultName)
		
		// Get coins
		new szCoins[16], iExists, iTimestamp;
		iExists = nvault_lookup(g_iVaultHandle, szName, szCoins, charsmax(szCoins), iTimestamp);
		
		// Close Vault
		nvault_close(g_iVaultHandle)
		
		if (!iExists)
		{
			// Player exist? Load start value then save
			g_iEscapeCoins[id] = get_pcvar_num(g_pCvarStartCoins)
			SaveCoins(id)
		}
		else
		{
			g_iEscapeCoins[id] = str_to_num(szCoins)
		}
	}
	else
	{
		new szQuery[128], szData[5]
		formatex(szQuery, charsmax(szQuery), "SELECT `EC` FROM `zombie_escape` WHERE ( `Nick` = '%s' );", szName)
     
		num_to_str(id, szData, charsmax(szData))
		SQL_ThreadQuery(g_hTuple, "QuerySelectData", szQuery, szData, charsmax(szData))
	}
}

public QuerySelectData(iFailState, Handle:hQuery, szError[], iError, szData[]) 
{
	if(SQL_IsFail(iFailState, iError, szError, g_szLogFile))
		return
	
	new id = str_to_num(szData)
	
	// No results for this query means that player not saved before
	if(!SQL_NumResults(hQuery))
	{
		// This is new player
		g_iEscapeCoins[id] = get_pcvar_num(g_pCvarStartCoins)
		
		// Get user steamid
		new szAuthID[35], szName[64], szIP[35]
		get_user_authid(id, szAuthID, charsmax(szAuthID))
		get_user_name(id, szName, charsmax(szName))
		get_user_ip(id, szIP, charsmax(szIP), 1)
		
		// Insert his data to our database
		new szQuery[128]
		
		formatex(szQuery, charsmax(szQuery), "INSERT INTO `zombie_escape` (`Nick`, `IP`, `SteamID`, `EC`) VALUES ('%s', '%s', '%s', '%d');", szName, szIP, szAuthID, g_iEscapeCoins[id])
		SQL_ThreadQuery(g_hTuple, "QueryInsertData", szQuery)
		
		return
	}
	
	// Get the "EC" column number (It's 2, always i don't like to hardcode :p)
	new iEC_Column = SQL_FieldNameToNum(hQuery, "EC")
	
	// Read the coins of this player
	g_iEscapeCoins[id] = SQL_ReadResult(hQuery, iEC_Column)
}

public QueryInsertData(iFailState, Handle:hQuery, szError[], iError, szData[], iSize, Float:flQueueTime)
{
	SQL_IsFail(iFailState, iError, szError, g_szLogFile)
}

SaveCoins(id)
{
	new szAuthID[35], szName[64], szIP[35], iMaxValue
	iMaxValue = get_pcvar_num(g_pCvarMaxCoins)
	get_user_authid(id, szAuthID, charsmax(szAuthID))
	get_user_name(id, szName, charsmax(szName))
	get_user_ip(id, szIP, charsmax(szIP), 1)
	
	// Set Him to max if he Higher than Max Value
	if (g_iEscapeCoins[id] > iMaxValue)
	{
		g_iEscapeCoins[id] = iMaxValue
	}

	new szData[16]
	num_to_str(g_iEscapeCoins[id], szData, charsmax(szData))

	if (!get_pcvar_num(g_pCvarSaveType))
	{
		// Open the Vault
		g_iVaultHandle = nvault_open(g_szVaultName)

		// Save His SteamID, Escape Coins
		nvault_set(g_iVaultHandle, szName, szData)
		
		// Close Vault
		nvault_close(g_iVaultHandle)
	}
	else
	{
		new szQuery[128]
		formatex(szQuery, charsmax(szQuery), "UPDATE `zombie_escape` SET `EC` = '%d', `SteamID` = '%s', `IP` = '%s' WHERE `Nick` = '%s';", g_iEscapeCoins[id], szAuthID, szIP, szName)
		SQL_ThreadQuery(g_hTuple, "QueryUpdateData", szQuery)
	}
}

public QueryUpdateData(iFailState, Handle:hQuery, szError[], iError, szData[], iSize, Float:flQueueTime) 
{
	SQL_IsFail(iFailState, iError, szError, g_szLogFile)
}

// Natives
public native_ze_get_escape_coins(id)
{
	if (!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false;
	}
	
	return g_iEscapeCoins[id]
}

public native_ze_set_escape_coins(id, iAmount)
{
	if (!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false;
	}
	
	g_iEscapeCoins[id] = iAmount
	
	SaveCoins(id)
	return true;
}

I try to save the following values

STEAMID = szAuthID (from which the data will load)

LEVELS = g_iLevel[id]
XP = g_iXP[id]



If one could help I would be grateful!
KerwinSweet2003 is offline
lexzor
Veteran Member
Join Date: Nov 2020
Old 05-26-2023 , 06:10   Re: Level System trying to move to SQL Database
Reply With Quote #2

hello, i make some code review for saving/loadin data from mysql and nvault

i changed table structure. anyways, it's not so clear what 'EC' means

PHP Code:
#include <zombie_escape>

// Static (Change it if you need)
new const g_szVaultName[] = "Escape_Coins"
new const g_szLogFile[] = "Escape-Coins.log" // MySQL Errors log file

// MySQL Table


//add a auto incremented variable in the tables when you have many entries 
new const g_szTable[] = 
" \
    CREATE TABLE IF NOT EXISTS `zombie_escape` \
    ( \
        `id` int(11) AUTO_INCREMENT NOT NULL, \
        `Nick` varchar(64) NOT NULL, \
        `IP` varchar(34) NOT NULL, \
        `SteamID` varchar(34) NOT NULL, \
        `EC` int(16) NOT NULL, \
        PRIMARY KEY (`id`) \
    ); \
"

// Variables
new g_iMaxClients,
    
g_iVaultHandle,
    
g_iEscapeCoins[33], 
    
Float:g_flDamage[33],
    
Handle:g_hTuple

// Cvars
new g_pCvarEscapeSuccess
    
g_pCvarHumanInfected
    
g_pCvarDamage
    
g_pCvarDamageCoins
    
g_pCvarStartCoins
    
g_pCvarMaxCoins,
    
g_pCvarEarnChatNotice,
    
g_pCvarSaveType,
    
g_pCvarDBInfo[4]

// Database
enum
{
    
Host 0,
    
User,
    
Pass,
    
DB
}

// Natives
public plugin_natives()
{
    
register_native("ze_get_escape_coins""native_ze_get_escape_coins"1)
    
register_native("ze_set_escape_coins""native_ze_set_escape_coins"1)
}

public 
plugin_init()
{
    
register_plugin("[ZE] Escape Coins System"ZE_VERSIONAUTHORS)
    
    
// Hook Chains
    
RegisterHookChain(RG_CBasePlayer_TakeDamage"Fw_TakeDamage_Post"1)
    
    
// Commands
    //register_clcmd("say /EC", "Coins_Info")
    //register_clcmd("say_team /EC", "Coins_Info")
    
    // Static Values
    
g_iMaxClients get_member_game(m_nMaxPlayers)
    
    
// Cvars
    
g_pCvarSaveType register_cvar("ze_coins_save_type""0")
    
g_pCvarEscapeSuccess register_cvar("ze_escape_success_coins""15")
    
g_pCvarHumanInfected register_cvar("ze_human_infected_coins""5")
    
g_pCvarDamage register_cvar("ze_damage_required""300")
    
g_pCvarDamageCoins register_cvar("ze_damage_coins""4")
    
g_pCvarStartCoins register_cvar("ze_start_coins""50")
    
g_pCvarMaxCoins register_cvar("ze_max_coins""200000")
    
g_pCvarEarnChatNotice register_cvar("ze_earn_chat_notice""1")
    
    
g_pCvarDBInfo[Host] = register_cvar("ze_ec_host""localhost")
    
g_pCvarDBInfo[User] = register_cvar("ze_ec_user""user")
    
g_pCvarDBInfo[Pass] = register_cvar("ze_ec_pass""pass")
    
g_pCvarDBInfo[DB] = register_cvar("ze_ec_dbname""dbname")
    
    
// Initialize MySQL - Delay 0.1 second required so we make sure that our zombie_escape.cfg already executed and cvars values loaded from it
    
set_task(0.1"Delay_MySQL_Init")
    
// you can call this in plugin_cfg
}

public 
Coins_Info(id)
{
    
ze_colored_print(id"%L"LANG_PLAYER"COINS_INFO"g_iEscapeCoins[id])
}

public 
Delay_MySQL_Init()
{
    
MySQL_Init()
}

public 
MySQL_Init()
{
    if (!
get_pcvar_num(g_pCvarSaveType))
        return
    
    new 
szHost[64], szUser[32], szPass[32], szDB[128]
    
    
get_pcvar_string(g_pCvarDBInfo[Host], szHostcharsmax(szHost))
    
get_pcvar_string(g_pCvarDBInfo[User], szUsercharsmax(szUser))
    
get_pcvar_string(g_pCvarDBInfo[Pass], szPasscharsmax(szPass))
    
get_pcvar_string(g_pCvarDBInfo[DB], szDBcharsmax(szDB))
    
    
g_hTuple SQL_MakeDbTuple(szHostszUserszPassszDB)
    
    
// Let's ensure that the g_hTuple will be valid, we will access the database to make sure
    
new iErrorCodeszError[512], Handle:hSQLConnection
    
    hSQLConnection 
SQL_Connect(g_hTupleiErrorCodeszErrorcharsmax(szError))
    
    if(
hSQLConnection != Empty_Handle)
    {
        
log_amx("[MySQL] Successfully connected to host: %s (ALL IS OK)."szHost)
        
SQL_FreeHandle(hSQLConnection)
    }
    else
    {
        
// Disable plugin, and display the error
        
SQL_FreeHandle(hSQLConnection// why not? better be safe
        
set_fail_state("Failed to connect to MySQL database: %s"szError)
    }
    
    
// Create our table
    
SQL_ThreadQuery(g_hTuple"QueryCreateTable"g_szTable)
}

public 
QueryCreateTable(iFailStateHandle:hQueryszError[], iErrorszData[], iSizeFloat:flQueueTime
{
    
SQL_IsFail(iFailStateiErrorszErrorg_szLogFile)
}

public 
client_putinserver(id)
{
    if (
is_user_bot(id) || is_user_hltv(id))
        return
    
    
// Just 1 second delay
    
set_task(1.0"DelayLoad"id)
}

public 
DelayLoad(id)
{
    
LoadCoins(id)
}

public 
plugin_end()
{
    if (
get_pcvar_num(g_pCvarSaveType))
    {
        if (
g_hTuple != Empty_Handle)
        {
            
SQL_FreeHandle(g_hTuple)
        }
    }
    else
    {
        
nvault_close(nvault// why don't you close this too?
    
}
}

//this types of saves are nice to use when you know your server can crash,
//don't need to make so many queries every time, you can save their data when disconnecting
//also, it is better to use get_players to parse all players
// you have here some info how to use it https://wiki.alliedmods.net/Optimizing_Plugins_(AMX_Mod_X_Scripting)#Don.27t_Re-index_Arrays
public ze_roundend(WinTeam
{
    if (
WinTeam == ZE_TEAM_HUMAN)
    {
        for(new 
id 1id <= g_iMaxClientsid++)
        {
            
g_flDamage[id] = 0.0
            
            
if (!is_user_alive(id) || ze_is_user_zombie(id))
                continue
            
            
g_iEscapeCoins[id] += get_pcvar_num(g_pCvarEscapeSuccess)
            
            
SaveCoins(id)
            
            if (
get_pcvar_num(g_pCvarEarnChatNotice))
            {
                
ze_colored_print(id"%L"LANG_PLAYER"ESCAPE_SUCCESS_COINS"get_pcvar_num(g_pCvarEscapeSuccess))
            }
        }
    }
}

public 
ze_user_infected(iVictimiInfector)
{
    if (
iInfector == 0// Server ID
        
return

    
g_iEscapeCoins[iInfector] += get_pcvar_num(g_pCvarHumanInfected)
    
    
SaveCoins(iInfector)
    
    if (
get_pcvar_num(g_pCvarEarnChatNotice))
    {
        
ze_colored_print(iInfector"%L"LANG_PLAYER"HUMAN_INFECTED_COINS"get_pcvar_num(g_pCvarHumanInfected))
    }
}

public 
Fw_TakeDamage_Post(iVictimiInflictoriAttackerFloat:fDamagebitsDamageType)
{
    
// Player Damage Himself
    
if(!is_user_connected(iVictim) || !is_user_connected(iAttacker) || iVictim == iAttacker || rg_is_player_can_takedamage(iVictim,iAttacker))
        return 
HC_CONTINUE
    
    
/* // Two Players From one Team
    if (get_member(iAttacker, m_iTeam) == get_member(iVictim, m_iTeam))
        return HC_CONTINUE */
    
    // iVictim or iAttacker Not Alive
    
if (!is_user_alive(iVictim) || !is_user_alive(iAttacker))
        return 
HC_CONTINUE
    
    
// Attacker is Zombie
    
if (get_member(iAttackerm_iTeam) == TEAM_TERRORIST)
        return 
HC_CONTINUE
    
    
// Store Damage For every Player
    
g_flDamage[iAttacker] += fDamage
    
    
// Damage Calculator Equal or Higher than needed damage
    
while (g_flDamage[iAttacker] >= get_pcvar_float(g_pCvarDamage))
    {
        
g_iEscapeCoins[iAttacker] += (get_pcvar_num(g_pCvarDamageCoins))
        
g_flDamage[iAttacker] -= get_pcvar_float(g_pCvarDamage)
    }
        
    
SaveCoins(iAttacker)

    return 
HC_CONTINUE
}

LoadCoins(id)
{
    new 
szAuthID[35], szName[64]
    
get_user_name(idszNamecharsmax(szName))
    
get_user_authid(idszAuthIDcharsmax(szAuthID))
    
    if (!
get_pcvar_num(g_pCvarSaveType))
    {
        
// Open the Vault
        
g_iVaultHandle nvault_open(g_szVaultName)
        
        
// Get coins
        
new szCoins[16], iExistsiTimestamp;
        
iExists nvault_lookup(g_iVaultHandleszNameszCoinscharsmax(szCoins), iTimestamp);
        
/*
            you can do this

            if(iExists = nvault_lookup(g_iVaultHandle, szName, szCoins, charsmax(szCoins), iTimestamp))
            {
                data exists....
            }
            else 
            {
                data does not exists...
            }
    

            NOTE: it's not a good practice to open and close the nvault every time you save/load a record,
            just open it in plugin_init and close it in plugin_end
        */
    



        // Close Vault
        
nvault_close(g_iVaultHandle)
        
        if (!
iExists)
        {
            
// Player exist? Load start value then save
            
g_iEscapeCoins[id] = get_pcvar_num(g_pCvarStartCoins)
            
SaveCoins(id)
        }
        else
        {
            
g_iEscapeCoins[id] = str_to_num(szCoins)
        }
    }
    else
    {
        new 
szQuery[128], szData[5]
        
// formatex(szQuery, charsmax(szQuery), "SELECT `EC` FROM `zombie_escape` WHERE ( `Nick` = '%s' );", szName)
        
formatex(szQuerycharsmax(szQuery), "SELECT `EC` FROM `zombie_escape` WHERE `Nick` = '%s';"szName)
     
        
num_to_str(idszDatacharsmax(szData))
        
SQL_ThreadQuery(g_hTuple"QuerySelectData"szQueryszDatacharsmax(szData))
    }
}

public 
QuerySelectData(iFailStateHandle:hQueryszError[], iErrorszData[]) 
{
    if(
SQL_IsFail(iFailStateiErrorszErrorg_szLogFile))
        return
    
    new 
id str_to_num(szData)
    
    
// No results for this query means that player not saved before
    
if(!SQL_NumResults(hQuery))
    {
        
// This is new player
        
g_iEscapeCoins[id] = get_pcvar_num(g_pCvarStartCoins)
        
        
// Get user steamid
        
new szAuthID[35], szName[64], szIP[35]
        
get_user_authid(idszAuthIDcharsmax(szAuthID))
        
get_user_name(idszNamecharsmax(szName))
        
get_user_ip(idszIPcharsmax(szIP), 1)
        
        
// Insert his data to our database
        
new szQuery[128]
        
        
formatex(szQuerycharsmax(szQuery), "INSERT INTO `zombie_escape` (`Nick`, `IP`, `SteamID`, `EC`) VALUES ('%s', '%s', '%s', '%d');"szNameszIPszAuthIDg_iEscapeCoins[id])
        
SQL_ThreadQuery(g_hTuple"QueryInsertData"szQuery)
    
        
// freehandle query?
        
return
    }
    
    
// Get the "EC" column number (It's 2, always i don't like to hardcode :p)
    
new iEC_Column SQL_FieldNameToNum(hQuery"EC")
    
    
// Read the coins of this player
    
g_iEscapeCoins[id] = SQL_ReadResult(hQueryiEC_Column)

    
// freehandle query?
}

public 
QueryInsertData(iFailStateHandle:hQueryszError[], iErrorszData[], iSizeFloat:flQueueTime)
{
    
SQL_IsFail(iFailStateiErrorszErrorg_szLogFile)

    
// freehandle query?

lexzor is offline
KerwinSweet2003
Junior Member
Join Date: Nov 2022
Old 05-26-2023 , 07:32   Re: Level System trying to move to SQL Database
Reply With Quote #3

Quote:
Originally Posted by lexzor View Post
hello, i make some code review for saving/loadin data from mysql and nvault

i changed table structure. anyways, it's not so clear what 'EC' means

PHP Code:
#include <zombie_escape>

// Static (Change it if you need)
new const g_szVaultName[] = "Escape_Coins"
new const g_szLogFile[] = "Escape-Coins.log" // MySQL Errors log file

// MySQL Table


//add a auto incremented variable in the tables when you have many entries 
new const g_szTable[] = 
" \
    CREATE TABLE IF NOT EXISTS `zombie_escape` \
    ( \
        `id` int(11) AUTO_INCREMENT NOT NULL, \
        `Nick` varchar(64) NOT NULL, \
        `IP` varchar(34) NOT NULL, \
        `SteamID` varchar(34) NOT NULL, \
        `EC` int(16) NOT NULL, \
        PRIMARY KEY (`id`) \
    ); \
"

// Variables
new g_iMaxClients,
    
g_iVaultHandle,
    
g_iEscapeCoins[33], 
    
Float:g_flDamage[33],
    
Handle:g_hTuple

// Cvars
new g_pCvarEscapeSuccess
    
g_pCvarHumanInfected
    
g_pCvarDamage
    
g_pCvarDamageCoins
    
g_pCvarStartCoins
    
g_pCvarMaxCoins,
    
g_pCvarEarnChatNotice,
    
g_pCvarSaveType,
    
g_pCvarDBInfo[4]

// Database
enum
{
    
Host 0,
    
User,
    
Pass,
    
DB
}

// Natives
public plugin_natives()
{
    
register_native("ze_get_escape_coins""native_ze_get_escape_coins"1)
    
register_native("ze_set_escape_coins""native_ze_set_escape_coins"1)
}

public 
plugin_init()
{
    
register_plugin("[ZE] Escape Coins System"ZE_VERSIONAUTHORS)
    
    
// Hook Chains
    
RegisterHookChain(RG_CBasePlayer_TakeDamage"Fw_TakeDamage_Post"1)
    
    
// Commands
    //register_clcmd("say /EC", "Coins_Info")
    //register_clcmd("say_team /EC", "Coins_Info")
    
    // Static Values
    
g_iMaxClients get_member_game(m_nMaxPlayers)
    
    
// Cvars
    
g_pCvarSaveType register_cvar("ze_coins_save_type""0")
    
g_pCvarEscapeSuccess register_cvar("ze_escape_success_coins""15")
    
g_pCvarHumanInfected register_cvar("ze_human_infected_coins""5")
    
g_pCvarDamage register_cvar("ze_damage_required""300")
    
g_pCvarDamageCoins register_cvar("ze_damage_coins""4")
    
g_pCvarStartCoins register_cvar("ze_start_coins""50")
    
g_pCvarMaxCoins register_cvar("ze_max_coins""200000")
    
g_pCvarEarnChatNotice register_cvar("ze_earn_chat_notice""1")
    
    
g_pCvarDBInfo[Host] = register_cvar("ze_ec_host""localhost")
    
g_pCvarDBInfo[User] = register_cvar("ze_ec_user""user")
    
g_pCvarDBInfo[Pass] = register_cvar("ze_ec_pass""pass")
    
g_pCvarDBInfo[DB] = register_cvar("ze_ec_dbname""dbname")
    
    
// Initialize MySQL - Delay 0.1 second required so we make sure that our zombie_escape.cfg already executed and cvars values loaded from it
    
set_task(0.1"Delay_MySQL_Init")
    
// you can call this in plugin_cfg
}

public 
Coins_Info(id)
{
    
ze_colored_print(id"%L"LANG_PLAYER"COINS_INFO"g_iEscapeCoins[id])
}

public 
Delay_MySQL_Init()
{
    
MySQL_Init()
}

public 
MySQL_Init()
{
    if (!
get_pcvar_num(g_pCvarSaveType))
        return
    
    new 
szHost[64], szUser[32], szPass[32], szDB[128]
    
    
get_pcvar_string(g_pCvarDBInfo[Host], szHostcharsmax(szHost))
    
get_pcvar_string(g_pCvarDBInfo[User], szUsercharsmax(szUser))
    
get_pcvar_string(g_pCvarDBInfo[Pass], szPasscharsmax(szPass))
    
get_pcvar_string(g_pCvarDBInfo[DB], szDBcharsmax(szDB))
    
    
g_hTuple SQL_MakeDbTuple(szHostszUserszPassszDB)
    
    
// Let's ensure that the g_hTuple will be valid, we will access the database to make sure
    
new iErrorCodeszError[512], Handle:hSQLConnection
    
    hSQLConnection 
SQL_Connect(g_hTupleiErrorCodeszErrorcharsmax(szError))
    
    if(
hSQLConnection != Empty_Handle)
    {
        
log_amx("[MySQL] Successfully connected to host: %s (ALL IS OK)."szHost)
        
SQL_FreeHandle(hSQLConnection)
    }
    else
    {
        
// Disable plugin, and display the error
        
SQL_FreeHandle(hSQLConnection// why not? better be safe
        
set_fail_state("Failed to connect to MySQL database: %s"szError)
    }
    
    
// Create our table
    
SQL_ThreadQuery(g_hTuple"QueryCreateTable"g_szTable)
}

public 
QueryCreateTable(iFailStateHandle:hQueryszError[], iErrorszData[], iSizeFloat:flQueueTime
{
    
SQL_IsFail(iFailStateiErrorszErrorg_szLogFile)
}

public 
client_putinserver(id)
{
    if (
is_user_bot(id) || is_user_hltv(id))
        return
    
    
// Just 1 second delay
    
set_task(1.0"DelayLoad"id)
}

public 
DelayLoad(id)
{
    
LoadCoins(id)
}

public 
plugin_end()
{
    if (
get_pcvar_num(g_pCvarSaveType))
    {
        if (
g_hTuple != Empty_Handle)
        {
            
SQL_FreeHandle(g_hTuple)
        }
    }
    else
    {
        
nvault_close(nvault// why don't you close this too?
    
}
}

//this types of saves are nice to use when you know your server can crash,
//don't need to make so many queries every time, you can save their data when disconnecting
//also, it is better to use get_players to parse all players
// you have here some info how to use it https://wiki.alliedmods.net/Optimizing_Plugins_(AMX_Mod_X_Scripting)#Don.27t_Re-index_Arrays
public ze_roundend(WinTeam
{
    if (
WinTeam == ZE_TEAM_HUMAN)
    {
        for(new 
id 1id <= g_iMaxClientsid++)
        {
            
g_flDamage[id] = 0.0
            
            
if (!is_user_alive(id) || ze_is_user_zombie(id))
                continue
            
            
g_iEscapeCoins[id] += get_pcvar_num(g_pCvarEscapeSuccess)
            
            
SaveCoins(id)
            
            if (
get_pcvar_num(g_pCvarEarnChatNotice))
            {
                
ze_colored_print(id"%L"LANG_PLAYER"ESCAPE_SUCCESS_COINS"get_pcvar_num(g_pCvarEscapeSuccess))
            }
        }
    }
}

public 
ze_user_infected(iVictimiInfector)
{
    if (
iInfector == 0// Server ID
        
return

    
g_iEscapeCoins[iInfector] += get_pcvar_num(g_pCvarHumanInfected)
    
    
SaveCoins(iInfector)
    
    if (
get_pcvar_num(g_pCvarEarnChatNotice))
    {
        
ze_colored_print(iInfector"%L"LANG_PLAYER"HUMAN_INFECTED_COINS"get_pcvar_num(g_pCvarHumanInfected))
    }
}

public 
Fw_TakeDamage_Post(iVictimiInflictoriAttackerFloat:fDamagebitsDamageType)
{
    
// Player Damage Himself
    
if(!is_user_connected(iVictim) || !is_user_connected(iAttacker) || iVictim == iAttacker || rg_is_player_can_takedamage(iVictim,iAttacker))
        return 
HC_CONTINUE
    
    
/* // Two Players From one Team
    if (get_member(iAttacker, m_iTeam) == get_member(iVictim, m_iTeam))
        return HC_CONTINUE */
    
    // iVictim or iAttacker Not Alive
    
if (!is_user_alive(iVictim) || !is_user_alive(iAttacker))
        return 
HC_CONTINUE
    
    
// Attacker is Zombie
    
if (get_member(iAttackerm_iTeam) == TEAM_TERRORIST)
        return 
HC_CONTINUE
    
    
// Store Damage For every Player
    
g_flDamage[iAttacker] += fDamage
    
    
// Damage Calculator Equal or Higher than needed damage
    
while (g_flDamage[iAttacker] >= get_pcvar_float(g_pCvarDamage))
    {
        
g_iEscapeCoins[iAttacker] += (get_pcvar_num(g_pCvarDamageCoins))
        
g_flDamage[iAttacker] -= get_pcvar_float(g_pCvarDamage)
    }
        
    
SaveCoins(iAttacker)

    return 
HC_CONTINUE
}

LoadCoins(id)
{
    new 
szAuthID[35], szName[64]
    
get_user_name(idszNamecharsmax(szName))
    
get_user_authid(idszAuthIDcharsmax(szAuthID))
    
    if (!
get_pcvar_num(g_pCvarSaveType))
    {
        
// Open the Vault
        
g_iVaultHandle nvault_open(g_szVaultName)
        
        
// Get coins
        
new szCoins[16], iExistsiTimestamp;
        
iExists nvault_lookup(g_iVaultHandleszNameszCoinscharsmax(szCoins), iTimestamp);
        
/*
            you can do this

            if(iExists = nvault_lookup(g_iVaultHandle, szName, szCoins, charsmax(szCoins), iTimestamp))
            {
                data exists....
            }
            else 
            {
                data does not exists...
            }
    

            NOTE: it's not a good practice to open and close the nvault every time you save/load a record,
            just open it in plugin_init and close it in plugin_end
        */
    



        // Close Vault
        
nvault_close(g_iVaultHandle)
        
        if (!
iExists)
        {
            
// Player exist? Load start value then save
            
g_iEscapeCoins[id] = get_pcvar_num(g_pCvarStartCoins)
            
SaveCoins(id)
        }
        else
        {
            
g_iEscapeCoins[id] = str_to_num(szCoins)
        }
    }
    else
    {
        new 
szQuery[128], szData[5]
        
// formatex(szQuery, charsmax(szQuery), "SELECT `EC` FROM `zombie_escape` WHERE ( `Nick` = '%s' );", szName)
        
formatex(szQuerycharsmax(szQuery), "SELECT `EC` FROM `zombie_escape` WHERE `Nick` = '%s';"szName)
     
        
num_to_str(idszDatacharsmax(szData))
        
SQL_ThreadQuery(g_hTuple"QuerySelectData"szQueryszDatacharsmax(szData))
    }
}

public 
QuerySelectData(iFailStateHandle:hQueryszError[], iErrorszData[]) 
{
    if(
SQL_IsFail(iFailStateiErrorszErrorg_szLogFile))
        return
    
    new 
id str_to_num(szData)
    
    
// No results for this query means that player not saved before
    
if(!SQL_NumResults(hQuery))
    {
        
// This is new player
        
g_iEscapeCoins[id] = get_pcvar_num(g_pCvarStartCoins)
        
        
// Get user steamid
        
new szAuthID[35], szName[64], szIP[35]
        
get_user_authid(idszAuthIDcharsmax(szAuthID))
        
get_user_name(idszNamecharsmax(szName))
        
get_user_ip(idszIPcharsmax(szIP), 1)
        
        
// Insert his data to our database
        
new szQuery[128]
        
        
formatex(szQuerycharsmax(szQuery), "INSERT INTO `zombie_escape` (`Nick`, `IP`, `SteamID`, `EC`) VALUES ('%s', '%s', '%s', '%d');"szNameszIPszAuthIDg_iEscapeCoins[id])
        
SQL_ThreadQuery(g_hTuple"QueryInsertData"szQuery)
    
        
// freehandle query?
        
return
    }
    
    
// Get the "EC" column number (It's 2, always i don't like to hardcode :p)
    
new iEC_Column SQL_FieldNameToNum(hQuery"EC")
    
    
// Read the coins of this player
    
g_iEscapeCoins[id] = SQL_ReadResult(hQueryiEC_Column)

    
// freehandle query?
}

public 
QueryInsertData(iFailStateHandle:hQueryszError[], iErrorszData[], iSizeFloat:flQueueTime)
{
    
SQL_IsFail(iFailStateiErrorszErrorg_szLogFile)

    
// freehandle query?


EC = Escape Coins,but I don't try to fix this plugin,this one is fine,I try to fix the Level System Plugin,the first code from the first post,the second plugin is from where I tried to impliment the code for the first plugin

Code:
#include <zombie_escape>
#include <ze_vip>


// Native witch ze_infections plugin (by Urban)
native ze_get_infections(id);


// Defines
#define MAX_LEVEL 10
#define TASK_SHOWHUD 2020
#define TASK_DOUBLE 1133
#define REPEAT_TIME 60.0
#define ID_SHOWHUD (taskid - TASK_SHOWHUD)
#define LEVELUP "zombie_escape/new_level.wav"



enum
{
Host = 0,
User,
Pass,
DB
}

new const g_iMaxLevelsXP[MAX_LEVEL] =
{
20, // 1
60, // 2
120, // 3
200, // 4
300, // 5
400, // 6
580, // 7
700, // 8
920, // 9
1090, // 10

}

// Constants
new const g_szLevelsVault[] = "Levels"
new const g_szRanksVault[] = "Ranks"
new const g_szLogFile[] = "Levels.log" // MySQL Errors log file
new const g_szTable[] = 
" \
	CREATE TABLE IF NOT EXISTS `zombie_escape_level_system` \
	( \
		`SteamID` varchar(34) NOT NULL, \
		`Levels` int(16) NOT NULL, \
		`Escapes` int(16) NOT NULL \
	); \
"

// Messages
const Float:HUD_SPECT_X = -1.0
const Float:HUD_SPECT_Y = 0.70
const Float:HUD_STATS_X = 0.015
const Float:HUD_STATS_Y = 0.33

const HUD_STATS_ZOMBIE_R = 0
const HUD_STATS_ZOMBIE_G = 255
const HUD_STATS_ZOMBIE_B = 0

const HUD_STATS_HUMAN_R = 0
const HUD_STATS_HUMAN_G = 255
const HUD_STATS_HUMAN_B = 0

const HUD_STATS_SPEC_R = 0
const HUD_STATS_SPEC_G = 255
const HUD_STATS_SPEC_B = 0

// Variables
new g_iLevel[33],
g_iXP[33],
g_iMaxXP[33],
Float:g_fDamage[33],
g_MsgSync,
g_iLevelsVaultHandle,
g_Online,
g_iRanksVaultHandle,
Handle:g_hTuple,
Fw_LevelUP,
ForwardReturn,
bool:g_bIsDoubleHours

// Cvars
new g_pCvarZombieInfect,
g_pCvarEscapeSuccess,
g_pCvarEnableDamage,
g_pCvarRequiredDamage,
g_pCvarDamageAward,
g_pCvarStartXP,
g_pCvarPercentageStyle,
g_pCvarStartFromZero,
g_pCvarAddCommas,
g_pCvarLevelEffects,
g_pCvarSaveType,
g_pCvarDBInfo[4],
g_pCvarDoubleXP

public plugin_natives()
{
register_native("ze_get_user_xp", "native_ze_get_user_xp", 1)
register_native("ze_set_user_xp", "native_ze_set_user_xp", 1)
register_native("ze_get_user_level", "native_ze_get_user_level", 1)
register_native("ze_set_user_level", "native_ze_set_user_level", 1)
register_native("ze_get_user_max_xp", "native_ze_get_user_max_xp", 1)
}

public plugin_precache()
{
	precache_sound(LEVELUP)
}

public plugin_init()
{
	register_plugin("[ZE] Level-XP System", "1.9", "Raheem/JaCk")

// Hook Chains
RegisterHookChain(RG_CBasePlayer_TakeDamage, "Fw_TakeDamage_Post", 1)

Fw_LevelUP = CreateMultiForward("ze_on_levelup", ET_IGNORE, FP_CELL)

// Cvars
g_pCvarZombieInfect = register_cvar("ze_zombie_infect", "0")
g_pCvarEscapeSuccess = register_cvar("ze_escape_success", "1")
g_pCvarEnableDamage = register_cvar("ze_enable_dmg", "0")
g_pCvarRequiredDamage = register_cvar("ze_required_dmg", "50.0")
g_pCvarDamageAward = register_cvar("ze_dmg_award", "3")
g_pCvarStartXP = register_cvar("ze_start_xp", "1")
g_pCvarPercentageStyle = register_cvar("ze_enable_percentage_style", "0")
g_pCvarStartFromZero = register_cvar("ze_new_level_zero_xp", "1")
g_pCvarAddCommas = register_cvar("ze_add_commas_to_xp", "1")
g_pCvarLevelEffects = register_cvar("ze_level_up_effects", "0")
g_pCvarDoubleXP = register_cvar("ze_double_xp", "21-10")

g_pCvarSaveType = register_cvar("ze_levels_save_type", "0")
g_pCvarDBInfo[Host] = register_cvar("ze_levels_host", "127.0.0.1")
g_pCvarDBInfo[User] = register_cvar("ze_levels_user", "root")
g_pCvarDBInfo[Pass] = register_cvar("ze_levels_pass", "password")
g_pCvarDBInfo[DB] = register_cvar("ze_levels_dbname", "levels_db")

// Messages
g_MsgSync = CreateHudSyncObj()

	set_task(0.1, "Delay_MySQL_Init")

DoubleHours()

if (g_bIsDoubleHours)
{
	set_task(REPEAT_TIME, "HappyHours", TASK_DOUBLE, _, _, "b")
}
}

public plugin_end()
{
	if (get_pcvar_num(g_pCvarSaveType))
	{
	if (g_hTuple != Empty_Handle)
	{
		SQL_FreeHandle(g_hTuple)
	}

	}
}

public Delay_MySQL_Init()
{
	MySQL_Init()
}

public MySQL_Init()
{
	if (!get_pcvar_num(g_pCvarSaveType))
	return

new szHost[64], szUser[32], szPass[32], szDB[128]

get_pcvar_string(g_pCvarDBInfo[Host], szHost, charsmax(szHost))
get_pcvar_string(g_pCvarDBInfo[User], szUser, charsmax(szUser))
get_pcvar_string(g_pCvarDBInfo[Pass], szPass, charsmax(szPass))
get_pcvar_string(g_pCvarDBInfo[DB], szDB, charsmax(szDB))

g_hTuple = SQL_MakeDbTuple(szHost, szUser, szPass, szDB)

// Let's ensure that the g_hTuple will be valid, we will access the database to make sure
new iErrorCode, szError[512], Handle:hSQLConnection

hSQLConnection = SQL_Connect(g_hTuple, iErrorCode, szError, charsmax(szError))


if (hSQLConnection != Empty_Handle)
{
	log_amx("[MySQL][LVL] Successfully connected to host: %s (ALL IS OK).", szHost)
	SQL_FreeHandle(hSQLConnection)
}
else
{
	// Disable plugin
	set_fail_state("[LVL] Failed to connect to MySQL database: %s.", szError)
}

SQL_ThreadQuery(g_hTuple, "QueryCreateTable", g_szTable)
}

public QueryCreateTable(iFailState, Handle:hQuery, szError[], iError, szData[], iSize, Float:flQueueTime)
{
SQL_IsFail(iFailState, iError, szError, g_szLogFile)
}

public client_putinserver(id)
{
if(is_user_hltv(id) || is_user_bot(id))
	return
	
	// Just 1 second delay
	set_task(5.0, "DelayLoad", id)
	
	// Other tasks
	set_task(1.0, "Show_Hud", id+TASK_SHOWHUD, _, _, "b")
	
	if (g_bIsDoubleHours)
	{
	    set_task(REPEAT_TIME, "HappyHours", id+TASK_DOUBLE, _, _, "b")
	}

	if(ze_is_user_vip(id) & VIP_B)
	{
		g_Online++
	}
}

public HappyHours(taskid)
{
	DoubleHours()
	
	if (!g_bIsDoubleHours)
		remove_task(taskid)
	
	new szDoubleHours[32]
	
	get_pcvar_string(g_pCvarDoubleXP, szDoubleHours, charsmax(szDoubleHours))
	
	set_hudmessage(0, 255, 0, -0.5, 0.20, 0, 0.0, 10.0)
	show_hudmessage(0, "Double Experience Time")
}

public DelayLoad(id)
{
	// Load his data
	LoadData(id)
}

public client_disconnected(id)
{
	if(is_user_hltv(id) || is_user_bot(id))
		return
	
	remove_task(id+TASK_SHOWHUD)
	remove_task(id)

	if(ze_is_user_vip(id) & VIP_B)
	{
		g_Online--
	}
}

public Show_Hud(taskid)
{  
	new iPlayer = ID_SHOWHUD
	
	if (!is_user_alive(iPlayer))
	{
		iPlayer = pev(iPlayer, pev_iuser2)
		
		if (!is_user_alive(iPlayer))
			return
	}
	
	if (get_pcvar_num(g_pCvarPercentageStyle) != 0)
	{
		if(iPlayer != ID_SHOWHUD)
		{
			set_hudmessage(HUD_STATS_SPEC_R, HUD_STATS_SPEC_G, HUD_STATS_SPEC_B, HUD_SPECT_X, HUD_SPECT_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
			ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40 ^n[Escapes] - %0.2f %", g_iLevel[iPlayer], (float(g_iXP[iPlayer])/float(g_iMaxXP[iPlayer]), g_Online) * 100.0)
		}
		else if (ze_is_user_zombie(iPlayer))
		{
			new zeInfNeed = get_cvar_num("ze_infections_num")
			
			set_hudmessage(HUD_STATS_ZOMBIE_R, HUD_STATS_ZOMBIE_G, HUD_STATS_ZOMBIE_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
			ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40 ^n[Escapes] - %0.2f %^n[Infections] - %d/%d", g_iLevel[ID_SHOWHUD], (float(g_iXP[ID_SHOWHUD])/float(g_iMaxXP[ID_SHOWHUD]), g_Online) * 100.0, ze_get_infections(ID_SHOWHUD), zeInfNeed)
		}
		else
		{
			set_hudmessage(HUD_STATS_HUMAN_R, HUD_STATS_HUMAN_G, HUD_STATS_HUMAN_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
			ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40 ^n[Escapes] - %0.2f %", g_iLevel[ID_SHOWHUD], (float(g_iXP[ID_SHOWHUD])/float(g_iMaxXP[ID_SHOWHUD]), g_Online) * 100.0)
		}
	}
	else
	{
		if(iPlayer != ID_SHOWHUD)
		{
			if (get_pcvar_num(g_pCvarAddCommas) == 1)
			{
				new szSpecXP[15], szSpecMaxXP[15]
				
				AddCommas(g_iXP[iPlayer], szSpecXP, charsmax(szSpecXP))
				AddCommas(g_iMaxXP[iPlayer], szSpecMaxXP, charsmax(szSpecMaxXP))
				
				set_hudmessage(HUD_STATS_SPEC_R, HUD_STATS_SPEC_G, HUD_STATS_SPEC_B, HUD_SPECT_X, HUD_SPECT_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n[Escapes] - %s/%s", g_iLevel[iPlayer], szSpecXP, szSpecMaxXP, g_Online)
			}
			else
			{
				set_hudmessage(HUD_STATS_SPEC_R, HUD_STATS_SPEC_G, HUD_STATS_SPEC_B, HUD_SPECT_X, HUD_SPECT_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n[Escapes] - %d/%d", g_iLevel[iPlayer], g_iXP[iPlayer], g_iMaxXP[iPlayer], g_Online)
			}  
		}
		else if (ze_is_user_zombie(iPlayer))
		{
			if (get_pcvar_num(g_pCvarAddCommas) == 1)
			{
				new zeInfNeed = get_cvar_num("ze_infections_num")
				new szZombieXP[15], szZombieMaxXP[15]
				
				AddCommas(g_iXP[ID_SHOWHUD], szZombieXP, charsmax(szZombieXP))
				AddCommas(g_iMaxXP[ID_SHOWHUD], szZombieMaxXP, charsmax(szZombieMaxXP))
				
				set_hudmessage(HUD_STATS_ZOMBIE_R, HUD_STATS_ZOMBIE_G, HUD_STATS_ZOMBIE_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n[Escapes] - %s/%s^n[Infections] - %d/%d", g_iLevel[ID_SHOWHUD], szZombieXP, szZombieMaxXP, ze_get_infections(ID_SHOWHUD), zeInfNeed, g_Online)
			}
			else
			{
				new zeInfNeed = get_cvar_num("ze_infections_num")
				set_hudmessage(HUD_STATS_ZOMBIE_R, HUD_STATS_ZOMBIE_G, HUD_STATS_ZOMBIE_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n[Escapes] - %d/%d^n[Infections] - %d/%d", g_iLevel[ID_SHOWHUD], g_iXP[ID_SHOWHUD], g_iMaxXP[ID_SHOWHUD], ze_get_infections(ID_SHOWHUD), zeInfNeed, g_Online)
			}
		}
		else
		{
			if (get_pcvar_num(g_pCvarAddCommas) == 1)
			{
				new szHumanXP[15], szHumanMaxXP[15]
				
				AddCommas(g_iXP[ID_SHOWHUD], szHumanXP, charsmax(szHumanXP))
				AddCommas(g_iMaxXP[ID_SHOWHUD], szHumanMaxXP, charsmax(szHumanMaxXP))
				
				set_hudmessage(HUD_STATS_HUMAN_R, HUD_STATS_HUMAN_G, HUD_STATS_HUMAN_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n[Escapes] - %s/%s", g_iLevel[ID_SHOWHUD], szHumanXP, szHumanMaxXP, g_Online)
			}
			else
			{
				set_hudmessage(HUD_STATS_HUMAN_R, HUD_STATS_HUMAN_G, HUD_STATS_HUMAN_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n^n[Infections] - %d/%d", g_iLevel[ID_SHOWHUD], g_iXP[ID_SHOWHUD], g_iMaxXP[ID_SHOWHUD], g_Online)
			}
		}
	}
}

public ze_roundend(WinTeam)
{
	if (WinTeam == ZE_TEAM_HUMAN)
	{
		new iXP = g_bIsDoubleHours ? (get_pcvar_num(g_pCvarEscapeSuccess) * 2) : get_pcvar_num(g_pCvarEscapeSuccess)
		
		for(new id = 1; id <= get_member_game(m_nMaxPlayers); id++)
		{
			if( (ze_get_vip_flags(id) & VIP_B) )
			{
				iXP *= 2
			}

			if (!is_user_alive(id) || ze_is_user_zombie(id))
				continue
			
			Reward(id, (g_iXP[id] + iXP))
			ze_colored_print(id, "Good Job,Humans have escaped the Zombies! +!g%d !yEscape(s)", (iXP))
		}
	}
	
	remove_task(TASK_SHOWHUD)
}

public Check_User_Level(id)
{
	if (!is_user_connected(id))
		return
	
	if (g_iLevel[id] < MAX_LEVEL)
	{
		new szName[32]
		
		if (g_iXP[id] >= g_iMaxXP[id])
		{
			if (get_pcvar_num(g_pCvarStartFromZero) == 1)
			{
				g_iXP[id] = 0
			}
			
			g_iLevel[id]++
			g_iMaxXP[id] = g_iMaxLevelsXP[g_iLevel[id]]
			get_user_name(id, szName, charsmax(szName))
			ze_colored_print(0, "Congratulations to !g%s !yfor archiving (!gLevel!y:!g%i!y) and !y(!g%d escapes!y)!", szName, g_iLevel[id] ,g_iXP[id])
			ExecuteForward(Fw_LevelUP, ForwardReturn, id)
			SaveData(id)
			PlaySound(0, LEVELUP)
			
			if (get_pcvar_num(g_pCvarLevelEffects) != 0)
			{
				// Screen Fade
				message_begin(MSG_ONE, get_user_msgid("ScreenFade"), {0,0,0}, id)
				write_short(4096*2)
				write_short(4096*5)
				write_short(0x0001)
				write_byte(random(256))
				write_byte(random(256))
				write_byte(random(256))
				write_byte(150)
				message_end()
				
				// Screen Shake
				message_begin(MSG_ONE, get_user_msgid("ScreenShake"), {0,0,0}, id)
				write_short(255<<14)
				write_short(10<<14)
				write_short(255<<14)
				message_end()
			}
		}
	}
}

public ze_user_infected(iVictim, iInfector)
{
	if (iInfector == 0)
		return
	
	new iXP = g_bIsDoubleHours ? (get_pcvar_num(g_pCvarZombieInfect) * 2) : get_pcvar_num(g_pCvarZombieInfect)

	if((ze_get_vip_flags(iInfector) & VIP_B))
    {
        iXP *= 2
    }
	Reward(iInfector, (g_iXP[iInfector] + iXP))
}

public Fw_TakeDamage_Post(iVictim, iInflictor, iAttacker, Float:fDamage, bitsDamageType)
{
	// Player Damage Himself
	if (iVictim == iAttacker || !is_user_alive(iVictim) || !is_user_alive(iAttacker) || ze_is_user_zombie(iAttacker) || !get_pcvar_num(g_pCvarEnableDamage))
		return HC_CONTINUE
	
	// Same Team?
	if (get_member(iAttacker, m_iTeam) == get_member(iVictim, m_iTeam))
		return HC_CONTINUE
	
	// Store Damage For every Player
	g_fDamage[iAttacker] += fDamage
	
	// Damage Calculator Equal or Higher than needed damage
	if (g_fDamage[iAttacker] >= get_pcvar_float(g_pCvarRequiredDamage))
	{
		// Player did damage that a multiplication of the cvar? Increase coins by this factor
		new iMultiplier = floatround(g_fDamage[iAttacker] / get_pcvar_float(g_pCvarRequiredDamage))
		new iXP = ((g_bIsDoubleHours ? (get_pcvar_num(g_pCvarDamageAward) * 2) : get_pcvar_num(g_pCvarDamageAward)) * iMultiplier)
		Reward(iAttacker, (g_iXP[iAttacker] + iXP))
		
		// Rest The Damage Calculator
		g_fDamage[iAttacker] = 0.0
	}
	return HC_CONTINUE
}

public Reward(id, XP)
{
	if ((g_iLevel[id] + 1) < MAX_LEVEL)
	{
		g_iXP[id] = XP
		Check_User_Level(id)
	}
	else
	{
		if ((g_iXP[id] + XP) >= g_iMaxLevelsXP[MAX_LEVEL - 1])
		{
			g_iXP[id] = g_iMaxXP[id] = g_iMaxLevelsXP[MAX_LEVEL - 1]
		}
	}
	SaveData(id)
}

public SaveData(id)
{
	new szAuthID[35], szName[64]
	get_user_authid(id, szAuthID, charsmax(szAuthID))
	get_user_name(id, szName, charsmax(szName))
	
	if (!get_pcvar_num(g_pCvarSaveType))
	{
		new szData[256]
		formatex(szData , charsmax(szData), "%i %i", g_iLevel[id], g_iXP[id])
		
		// Open the Vaults
		g_iLevelsVaultHandle = nvault_open(g_szLevelsVault)
		g_iRanksVaultHandle = nvault_open(g_szRanksVault)
		
		// Saves His Data
		nvault_set(g_iLevelsVaultHandle, szAuthID, szData)
		nvault_set(g_iRanksVaultHandle, szAuthID, szName)
		
		// Close Vaults
		nvault_close(g_iLevelsVaultHandle)
		nvault_close(g_iRanksVaultHandle)
		
		new logtext[196], times[25], dest[64]
		get_localinfo("amxx_logs",dest,charsmax(dest))
		format(dest,charsmax(dest),"%s/Levels,Escapes Logs",dest)
		if(!dir_exists(dest))
		{
			mkdir(dest)
		}
		get_time("%Y",times,4)
		format(dest,charsmax(dest),"%s/%s",dest,times)
		if(!dir_exists(dest))
		{
			mkdir(dest)
		}
		get_time("%B",times,charsmax(times))
		format(dest,charsmax(dest),"%s/%s.txt",dest,times)
		if(!file_exists(dest))
		{
			write_file(dest,"")
		}
		get_time( "%d.%m.%Y", times, charsmax(times) );
		formatex(logtext, charsmax(logtext), "[%s] [Name: %s] - [SteamID %s] - [[Level] - %i] - [XP: %i]", times, szName, szAuthID, g_iLevel[id], g_iXP[id]);
		write_file(dest, logtext)
    
		
	}
	else
	{
		new szData[256]
		formatex(szData , charsmax(szData), "%i %i", g_iLevel[id], g_iXP[id])
		
		new szQuery[128]
		formatex(szQuery, charsmax(szQuery), "UPDATE `zombie_escape_level_system` SET `Levels` = '%d', `Escapes` = '%d' WHERE ( 'SteamID' = '%s');", g_iLevel[id],  g_iXP[id], szAuthID)
		SQL_ThreadQuery(g_hTuple, "QuerySelectData", szQuery)
	}
}

public QuerySetData(iFailState, Handle:hQuery, szError[], iError, szData[], iSize, Float:flQueueTime)
{
	SQL_IsFail(iFailState, iError, szError, g_szLogFile)
}

public QuerySetData2(iFailState, Handle:hQuery, szError[], iError, szData[], iSize, Float:flQueueTime)
{
	SQL_IsFail(iFailState, iError, szError, g_szLogFile)
}

public LoadData(id)
{
	new szAuthID[35], szName[64], szIP[35]
	get_user_authid(id, szAuthID, charsmax(szAuthID))
	get_user_name(id, szName, charsmax(szName))
	get_user_ip(id, szIP, charsmax(szIP), 1)
	
	if (!get_pcvar_num(g_pCvarSaveType))
	{
		new szData[256], iTimestamp, iExists
		
		// Open the Vault
		g_iLevelsVaultHandle = nvault_open(g_szLevelsVault)
		
		iExists = nvault_lookup(g_iLevelsVaultHandle, szAuthID, szData, charsmax(szData), iTimestamp)
		
		// Close Vault
		nvault_close(g_iLevelsVaultHandle)
		
		if (!iExists)
		{
			g_iLevel[id] = 0
			g_iXP[id] = get_pcvar_num(g_pCvarStartXP)
			SaveData(id)
			ze_colored_print(id, "Account Created!y: Name!y: (!g%s!y) SteamID !y^"!g%s!y^"", szName, szAuthID)
		}
		else
		{
			new iLevel[32], iXP[32]
			parse(szData, iLevel, 31, iXP, 31)
			
			g_iLevel[id] = str_to_num(iLevel)
			g_iXP[id] = str_to_num(iXP)

			if((ze_get_vip_flags(id) & VIP_B))
			{
				ze_colored_print(id, "!gAccount Loaded!y: (Name!y: !g%s!y) !t/!y (SteamID !y^"!g%s^"!y)", szName, szAuthID)
			}
			else
			{
				ze_colored_print(id, "!gAccount Loaded!y: (Name!y: !g%s!y) !t/!y (SteamID !y^"!g%s^"!y)", szName, szAuthID)
			}
		}
		
		g_iMaxXP[id] = g_iMaxLevelsXP[g_iLevel[id]]
	}
	else
	{
		new szQuery[128], szData[5]
		formatex(szQuery, charsmax(szQuery), "SELECT * FROM `zombie_escape_level_system` WHERE ( 'SteamID' = '%s' );", szAuthID)
		
		num_to_str(id, szData, charsmax(szData))
		SQL_ThreadQuery(g_hTuple, "QuerySelectData", szQuery, szData, charsmax(szData))
	}
}

public QuerySelectData(iFailState, Handle:hQuery, szError[], iError, szData[])
{
	if (SQL_IsFail(iFailState, iError, szError, g_szLogFile))
		return
	
	new id = str_to_num(szData)

	
	// No results for this query means this is new player
	if (!SQL_NumResults(hQuery))
	{
		g_iLevel[id] = 0
		g_iXP[id] = get_pcvar_num(g_pCvarStartXP)

		new szAuthID[35], szName[64], szIP[35]
		get_user_authid(id, szAuthID, charsmax(szAuthID))
		get_user_name(id, szName, charsmax(szName))
		get_user_ip(id, szIP, charsmax(szIP), 1)

		new szQuery[128]

		formatex(szQuery, charsmax(szQuery), "INSERT INTO `zombie_escape_level_system` (`SteamID`, `Levels`, `Escapes`) VALUES ('%s', '%d', '%d');", szAuthID, g_iLevel[id], g_iXP[id])
		SQL_ThreadQuery(g_hTuple, "QueryInsertData", szQuery)

		return
	}
	// Get the "Escape" column number (It's 2, always i don't like to hardcode :p)
	new iXP_Column = SQL_FieldNameToNum(hQuery, "Escapes")
	new iLevels_Column = SQL_FieldNameToNum(hQuery, "Levels")
	
	// Read the coins of this player
	g_iXP[id] = SQL_ReadResult(hQuery, iXP_Column)
	g_iLevel[id] = SQL_ReadResult(hQuery, iLevels_Column)
}

public QueryInsertData(iFailState, Handle:hQuery, szError[], iError, szData[], iSize, Float:flQueueTime)
{
	SQL_IsFail(iFailState, iError, szError, g_szLogFile)
}

public native_ze_get_user_xp(id)
{
	if(!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false;
	}
	
	return g_iXP[id]
}

public native_ze_set_user_xp(id, amount)
{
	if(!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false
	}
	
	DoubleHours()
	new addedXP = (amount - g_iXP[id])
	new iXP = g_bIsDoubleHours ? (addedXP * 2) : addedXP
	Reward(id, g_iXP[id] + iXP)
	return true
}

public native_ze_get_user_level(id)
{
	if(!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false;
	}
	
	return g_iLevel[id]
}

public native_ze_set_user_level(id, amount)
{
	if(!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false
	}
	
	if (amount > MAX_LEVEL)
	{
		log_error(AMX_ERR_NATIVE, "Level must be less than or equal to MAX_LEVEL (%d)", MAX_LEVEL)
		return false
	}
	
	g_iLevel[id] = amount
	
	if (get_pcvar_num(g_pCvarStartFromZero) == 1)
	{
		g_iXP[id] = 0
	}
	SaveData(id)
	
	return true
}

public native_ze_get_user_max_xp(id)
{
	if(!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false
	}
	
	return g_iMaxXP[id]
}

stock DoubleHours()
{
	new szTime[3], szDoubleHours[32], szDoubleHours_Start[32], szDoubleHours_End[32]
	get_time("%H", szTime, charsmax(szTime))
	
	get_pcvar_string(g_pCvarDoubleXP, szDoubleHours, charsmax(szDoubleHours))
	
	for (new ch = 0; ch <= charsmax(szDoubleHours); ch++)
	{
		if (szDoubleHours[ch] == '-')
			szDoubleHours[ch] = ' '
	}
	
	parse(szDoubleHours, szDoubleHours_Start, charsmax(szDoubleHours_Start), szDoubleHours_End, charsmax(szDoubleHours_End))
	
	new iTime, iDoubleHourStart, iDoubleHourEnd
	
	iTime = str_to_num(szTime)
	iDoubleHourStart = str_to_num(szDoubleHours_Start)
	iDoubleHourEnd = str_to_num(szDoubleHours_End)
	
	if (iDoubleHourEnd > iTime >= iDoubleHourStart)
	{
		g_bIsDoubleHours = true
	}
	else
	{
		g_bIsDoubleHours = false
	}
}
This is the code that it doesn't work,I get this error in the console

Code:
L 05/26/2023 - 11:29:46: [MySQL] Query failed: Duplicate entry 'STEAM_0:0:224689198' for key 'zombie_escape_levels.PRIMARY'
KerwinSweet2003 is offline
lexzor
Veteran Member
Join Date: Nov 2020
Old 05-26-2023 , 07:51   Re: Level System trying to move to SQL Database
Reply With Quote #4

for the table where you try to insert the data, the key chosen as primary already exists,

just check if the key already exists and don't insert it
lexzor is offline
KerwinSweet2003
Junior Member
Join Date: Nov 2022
Old 05-26-2023 , 09:40   Re: Level System trying to move to SQL Database
Reply With Quote #5

Quote:
Originally Posted by lexzor View Post
for the table where you try to insert the data, the key chosen as primary already exists,

just check if the key already exists and don't insert it
how do I do that,what do I need to change,I dont have experience in SQL,I just want the Levels and XP to be loaded on the player's SteamID.
KerwinSweet2003 is offline
Bugsy
AMX Mod X Moderator
Join Date: Feb 2005
Location: NJ, USA
Old 05-26-2023 , 23:32   Re: Level System trying to move to SQL Database
Reply With Quote #6

Is that happening on an INSERT INTO? You can try using REPLACE INTO instead, but you'll need to have all data specified for the existing row to not lose any data.

I don't have the time or patience to read all of your code, but if you can provide the table structure and SQL statements involved, I can help.
__________________
Bugsy is offline
KerwinSweet2003
Junior Member
Join Date: Nov 2022
Old 06-05-2023 , 08:00   Re: Level System trying to move to SQL Database
Reply With Quote #7

Quote:
Originally Posted by Bugsy View Post
Is that happening on an INSERT INTO? You can try using REPLACE INTO instead, but you'll need to have all data specified for the existing row to not lose any data.

I don't have the time or patience to read all of your code, but if you can provide the table structure and SQL statements involved, I can help.
Sorry for late reply,was too busy.I still have problem with the plugin,data is currently stored on nvault but players are losing their data sometimes when map is changing.The following plugin is the one that I m using,I tried to fix it but I was getting error (dublicate column "SteamID) I m trying to store the player's data on a single column not multiple,for ex when player gets XP the data will be replaced with the new one on the same column.

This is the plugin that I try to to have SQL support:

Code:
#include <zombie_escape>
#include <ze_vip>


// Native witch ze_infections plugin (by Urban)
native ze_get_infections(id);


// Defines
#define MAX_LEVEL 40
#define TASK_SHOWHUD 2020
#define TASK_DOUBLE 1133
#define REPEAT_TIME 60.0
#define ID_SHOWHUD (taskid - TASK_SHOWHUD)
#define LEVELUP "zombie_escape/new_level.wav"



enum
{
Host = 0,
User,
Pass,
DB
}

new const g_iMaxLevelsXP[MAX_LEVEL] =
{
20, // 1
60, // 2
120, // 3
200, // 4
300, // 5
400, // 6
580, // 7
700, // 8
920, // 9
1090, // 10
1330, // 11
1550, // 12
1830, // 13
2090, // 14
2410, // 15
2710, // 16
3070, // 17
3410, // 18
3790, // 19
4190, // 20
5210, // 21
6690, // 22
8710, // 23
11190, // 24
14210, // 25
17690, // 26
21710, // 27
26190, // 28
31210, // 29
36690, // 30
46710, // 31
61690, // 32
81710, // 33
106690, // 34
136710, // 35
176690, // 36
226710, // 37
286690, // 38
366710, // 39
456400, // 40
}

// Constants
new const g_szLevelsVault[] = "Levels"
new const g_szRanksVault[] = "Ranks"
new const g_szLogFile[] = "Levels.log" // MySQL Errors log file
new const g_szTable[] = 
" \
	CREATE TABLE IF NOT EXISTS `zombie_escape_levels` \
	( \
		`SteamID` varchar(64) NOT NULL, \
		`Levels` int(16) NOT NULL, \
		`Escapes` int(16) NOT NULL, \
		PRIMARY KEY (`SteamID`) \
	); \
"

// Messages
const Float:HUD_SPECT_X = -1.0
const Float:HUD_SPECT_Y = 0.70
const Float:HUD_STATS_X = 0.015
const Float:HUD_STATS_Y = 0.33

const HUD_STATS_ZOMBIE_R = 0
const HUD_STATS_ZOMBIE_G = 255
const HUD_STATS_ZOMBIE_B = 0

const HUD_STATS_HUMAN_R = 0
const HUD_STATS_HUMAN_G = 255
const HUD_STATS_HUMAN_B = 0

const HUD_STATS_SPEC_R = 0
const HUD_STATS_SPEC_G = 255
const HUD_STATS_SPEC_B = 0

// Variables
new g_iLevel[33],
g_iXP[33],
g_iMaxXP[33],
Float:g_fDamage[33],
g_MsgSync,
g_iLevelsVaultHandle,
g_Online,
g_iRanksVaultHandle,
Handle:g_hTuple,
Fw_LevelUP,
ForwardReturn,
bool:g_bIsDoubleHours

// Cvars
new g_pCvarZombieInfect,
g_pCvarEscapeSuccess,
g_pCvarEnableDamage,
g_pCvarRequiredDamage,
g_pCvarDamageAward,
g_pCvarStartXP,
g_pCvarPercentageStyle,
g_pCvarStartFromZero,
g_pCvarAddCommas,
g_pCvarLevelEffects,
g_pCvarSaveType,
g_pCvarDBInfo[4],
g_pCvarDoubleXP

public plugin_natives()
{
register_native("ze_get_user_xp", "native_ze_get_user_xp", 1)
register_native("ze_set_user_xp", "native_ze_set_user_xp", 1)
register_native("ze_get_user_level", "native_ze_get_user_level", 1)
register_native("ze_set_user_level", "native_ze_set_user_level", 1)
register_native("ze_get_user_max_xp", "native_ze_get_user_max_xp", 1)
}

public plugin_precache()
{
	precache_sound(LEVELUP)
}

public plugin_init()
{
	register_plugin("[ZE] Level-XP System", "1.9", "Raheem/JaCk")

	register_clcmd("say /info", "NextLevel")

// Hook Chains
RegisterHookChain(RG_CBasePlayer_TakeDamage, "Fw_TakeDamage_Post", 1)

Fw_LevelUP = CreateMultiForward("ze_on_levelup", ET_IGNORE, FP_CELL)

// Cvars
g_pCvarZombieInfect = register_cvar("ze_zombie_infect", "0")
g_pCvarEscapeSuccess = register_cvar("ze_escape_success", "1")
g_pCvarEnableDamage = register_cvar("ze_enable_dmg", "0")
g_pCvarRequiredDamage = register_cvar("ze_required_dmg", "50.0")
g_pCvarDamageAward = register_cvar("ze_dmg_award", "3")
g_pCvarStartXP = register_cvar("ze_start_xp", "1")
g_pCvarPercentageStyle = register_cvar("ze_enable_percentage_style", "0")
g_pCvarStartFromZero = register_cvar("ze_new_level_zero_xp", "1")
g_pCvarAddCommas = register_cvar("ze_add_commas_to_xp", "1")
g_pCvarLevelEffects = register_cvar("ze_level_up_effects", "0")
g_pCvarDoubleXP = register_cvar("ze_double_xp", "21-10")

g_pCvarSaveType = register_cvar("ze_levels_save_type", "0")
g_pCvarDBInfo[Host] = register_cvar("ze_levels_host", "127.0.0.1")
g_pCvarDBInfo[User] = register_cvar("ze_levels_user", "root")
g_pCvarDBInfo[Pass] = register_cvar("ze_levels_pass", "password")
g_pCvarDBInfo[DB] = register_cvar("ze_levels_dbname", "levels_db")

// Messages
g_MsgSync = CreateHudSyncObj()

	set_task(0.1, "Delay_MySQL_Init")

DoubleHours()

if (g_bIsDoubleHours)
{
	set_task(REPEAT_TIME, "HappyHours", TASK_DOUBLE, _, _, "b")
}
}

public plugin_end()
{
	if (get_pcvar_num(g_pCvarSaveType))
	{
	if (g_hTuple != Empty_Handle)
	{
		SQL_FreeHandle(g_hTuple)
	}

	}
}

public Delay_MySQL_Init()
{
	MySQL_Init()
}

public MySQL_Init()
{
	if (!get_pcvar_num(g_pCvarSaveType))
	return

new szHost[64], szUser[32], szPass[32], szDB[128]

get_pcvar_string(g_pCvarDBInfo[Host], szHost, charsmax(szHost))
get_pcvar_string(g_pCvarDBInfo[User], szUser, charsmax(szUser))
get_pcvar_string(g_pCvarDBInfo[Pass], szPass, charsmax(szPass))
get_pcvar_string(g_pCvarDBInfo[DB], szDB, charsmax(szDB))

g_hTuple = SQL_MakeDbTuple(szHost, szUser, szPass, szDB)

// Let's ensure that the g_hTuple will be valid, we will access the database to make sure
new iErrorCode, szError[512], Handle:hSQLConnection

hSQLConnection = SQL_Connect(g_hTuple, iErrorCode, szError, charsmax(szError))


if (hSQLConnection != Empty_Handle)
{
	log_amx("[MySQL][LVL] Successfully connected to host: %s (ALL IS OK).", szHost)
	SQL_FreeHandle(hSQLConnection)
}
else
{
	// Disable plugin
	set_fail_state("[LVL] Failed to connect to MySQL database: %s.", szError)
}

SQL_ThreadQuery(g_hTuple, "QueryCreateTable", g_szTable)
}

public QueryCreateTable(iFailState, Handle:hQuery, szError[], iError, szData[], iSize, Float:flQueueTime)
{
SQL_IsFail(iFailState, iError, szError, g_szLogFile)
}

public client_putinserver(id)
{
if(is_user_hltv(id) || is_user_bot(id))
	return
	
	// Just 1 second delay
	set_task(5.0, "DelayLoad", id)
	
	// Other tasks
	set_task(1.0, "Show_Hud", id+TASK_SHOWHUD, _, _, "b")
	
	if (g_bIsDoubleHours)
	{
	    set_task(REPEAT_TIME, "HappyHours", id+TASK_DOUBLE, _, _, "b")
	}

	if(ze_is_user_vip(id) & VIP_B)
	{
		g_Online++
	}
}

public HappyHours(taskid)
{
	DoubleHours()
	
	if (!g_bIsDoubleHours)
		remove_task(taskid)
	
	new szDoubleHours[32]
	
	get_pcvar_string(g_pCvarDoubleXP, szDoubleHours, charsmax(szDoubleHours))
	
	set_hudmessage(0, 255, 0, -0.5, 0.20, 0, 0.0, 10.0)
	show_hudmessage(0, "Double Experience Time")
}

public DelayLoad(id)
{
	// Load his data
	LoadData(id)
}

public client_disconnected(id)
{
	if(is_user_hltv(id) || is_user_bot(id))
		return
	
	remove_task(id+TASK_SHOWHUD)
	remove_task(id)

	if(ze_is_user_vip(id) & VIP_B)
	{
		g_Online--
	}
}

public Show_Hud(taskid)
{  
	new iPlayer = ID_SHOWHUD
	
	if (!is_user_alive(iPlayer))
	{
		iPlayer = pev(iPlayer, pev_iuser2)
		
		if (!is_user_alive(iPlayer))
			return
	}
	
	if (get_pcvar_num(g_pCvarPercentageStyle) != 0)
	{
		if(iPlayer != ID_SHOWHUD)
		{
			set_hudmessage(HUD_STATS_SPEC_R, HUD_STATS_SPEC_G, HUD_STATS_SPEC_B, HUD_SPECT_X, HUD_SPECT_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
			ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40 ^n[Escapes] - %0.2f %", g_iLevel[iPlayer], (float(g_iXP[iPlayer])/float(g_iMaxXP[iPlayer]), g_Online) * 100.0)
		}
		else if (ze_is_user_zombie(iPlayer))
		{
			new zeInfNeed = get_cvar_num("ze_infections_num")
			
			set_hudmessage(HUD_STATS_ZOMBIE_R, HUD_STATS_ZOMBIE_G, HUD_STATS_ZOMBIE_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
			ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40 ^n[Escapes] - %0.2f %^n[Infections] - %d/%d", g_iLevel[ID_SHOWHUD], (float(g_iXP[ID_SHOWHUD])/float(g_iMaxXP[ID_SHOWHUD]), g_Online) * 100.0, ze_get_infections(ID_SHOWHUD), zeInfNeed)
		}
		else
		{
			set_hudmessage(HUD_STATS_HUMAN_R, HUD_STATS_HUMAN_G, HUD_STATS_HUMAN_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
			ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40 ^n[Escapes] - %0.2f %", g_iLevel[ID_SHOWHUD], (float(g_iXP[ID_SHOWHUD])/float(g_iMaxXP[ID_SHOWHUD]), g_Online) * 100.0)
		}
	}
	else
	{
		if(iPlayer != ID_SHOWHUD)
		{
			if (get_pcvar_num(g_pCvarAddCommas) == 1)
			{
				new szSpecXP[15], szSpecMaxXP[15]
				
				AddCommas(g_iXP[iPlayer], szSpecXP, charsmax(szSpecXP))
				AddCommas(g_iMaxXP[iPlayer], szSpecMaxXP, charsmax(szSpecMaxXP))
				
				set_hudmessage(HUD_STATS_SPEC_R, HUD_STATS_SPEC_G, HUD_STATS_SPEC_B, HUD_SPECT_X, HUD_SPECT_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n[Escapes] - %s/%s", g_iLevel[iPlayer], szSpecXP, szSpecMaxXP, g_Online)
			}
			else
			{
				set_hudmessage(HUD_STATS_SPEC_R, HUD_STATS_SPEC_G, HUD_STATS_SPEC_B, HUD_SPECT_X, HUD_SPECT_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n[Escapes] - %d/%d", g_iLevel[iPlayer], g_iXP[iPlayer], g_iMaxXP[iPlayer], g_Online)
			}  
		}
		else if (ze_is_user_zombie(iPlayer))
		{
			if (get_pcvar_num(g_pCvarAddCommas) == 1)
			{
				new zeInfNeed = get_cvar_num("ze_infections_num")
				new szZombieXP[15], szZombieMaxXP[15]
				
				AddCommas(g_iXP[ID_SHOWHUD], szZombieXP, charsmax(szZombieXP))
				AddCommas(g_iMaxXP[ID_SHOWHUD], szZombieMaxXP, charsmax(szZombieMaxXP))
				
				set_hudmessage(HUD_STATS_ZOMBIE_R, HUD_STATS_ZOMBIE_G, HUD_STATS_ZOMBIE_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n[Escapes] - %s/%s^n[Infections] - %d/%d", g_iLevel[ID_SHOWHUD], szZombieXP, szZombieMaxXP, ze_get_infections(ID_SHOWHUD), zeInfNeed, g_Online)
			}
			else
			{
				new zeInfNeed = get_cvar_num("ze_infections_num")
				set_hudmessage(HUD_STATS_ZOMBIE_R, HUD_STATS_ZOMBIE_G, HUD_STATS_ZOMBIE_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n[Escapes] - %d/%d^n[Infections] - %d/%d", g_iLevel[ID_SHOWHUD], g_iXP[ID_SHOWHUD], g_iMaxXP[ID_SHOWHUD], ze_get_infections(ID_SHOWHUD), zeInfNeed, g_Online)
			}
		}
		else
		{
			if (get_pcvar_num(g_pCvarAddCommas) == 1)
			{
				new szHumanXP[15], szHumanMaxXP[15]
				
				AddCommas(g_iXP[ID_SHOWHUD], szHumanXP, charsmax(szHumanXP))
				AddCommas(g_iMaxXP[ID_SHOWHUD], szHumanMaxXP, charsmax(szHumanMaxXP))
				
				set_hudmessage(HUD_STATS_HUMAN_R, HUD_STATS_HUMAN_G, HUD_STATS_HUMAN_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n[Escapes] - %s/%s", g_iLevel[ID_SHOWHUD], szHumanXP, szHumanMaxXP, g_Online)
			}
			else
			{
				set_hudmessage(HUD_STATS_HUMAN_R, HUD_STATS_HUMAN_G, HUD_STATS_HUMAN_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n^n[Infections] - %d/%d", g_iLevel[ID_SHOWHUD], g_iXP[ID_SHOWHUD], g_iMaxXP[ID_SHOWHUD], g_Online)
			}
		}
	}
}

public ze_roundend(WinTeam)
{
	if (WinTeam == ZE_TEAM_HUMAN)
	{
		new iXP = g_bIsDoubleHours ? (get_pcvar_num(g_pCvarEscapeSuccess) * 2) : get_pcvar_num(g_pCvarEscapeSuccess)
		
		for(new id = 1; id <= get_member_game(m_nMaxPlayers); id++)
		{
			if( (ze_get_vip_flags(id) & VIP_B) )
			{
				iXP *= 2
			}

			if (!is_user_alive(id) || ze_is_user_zombie(id))
				continue
			
			Reward(id, (g_iXP[id] + iXP))
			ze_colored_print(id, "Good Job,Humans have escaped the Zombies! +!g%d !yEscape(s)", (iXP))
		}
	}
	
	remove_task(TASK_SHOWHUD)
}

public NextLevel(id)
{
	new szAuthID[35], szName[64], szIP[35]
	get_user_authid(id, szAuthID, charsmax(szAuthID))
	get_user_name(id, szName, charsmax(szName))
	get_user_ip(id, szIP, charsmax(szIP), 1)


	new flags = (get_user_flags(id))

	if((ze_get_vip_flags(id) & read_flags("b")) && flags & ADMIN_KICK)
	{
		ze_colored_print(id, "!gUser Info!y: (Name!y: !g%s!y) !t/!y (SteamID !y^"!g%s^"!y) / (IP !y^"!g%s!y^") ", szName, szAuthID, szIP)
		ze_colored_print(id, "!gAccount Info!y: (Level !g%i !y/ Escapes !g%d!y)", g_iLevel[id] ,g_iXP[id])
		ze_colored_print(id, "!gAccount Privilages!y: (VIP ACCESS!y): (!gYES!y) | (ADMIN ACCESS!y): (!gYES!y)")
	}
	else if (ze_get_vip_flags(id) & read_flags("b"))
	{
		ze_colored_print(id, "!gUser Info!y: (Name!y: !g%s!y) !t/!y (SteamID !y^"!g%s^"!y) / (IP !y^"!g%s!y^"!y) ", szName, szAuthID, szIP)
		ze_colored_print(id, "!gAccount Info!y: (Level !g%i !y/ Escapes !g%d!y)", g_iLevel[id] ,g_iXP[id])
		ze_colored_print(id, "!gAccount Privilages!y: (VIP ACCESS!y): (!gYES!y) | (ADMIN ACCESS!y): (!gNO!y)")
	}
	else if (flags & ADMIN_KICK)
	{
		ze_colored_print(id, "!gUser Info!y: (Name!y: !g%s!y) !t/!y (SteamID !y^"!g%s^"!y) / (IP !y^"!g%s!y^"!y) ", szName, szAuthID, szIP)
		ze_colored_print(id, "!gAccount Info!y: (Level !g%i !y/ Escapes !g%d!y)", g_iLevel[id] ,g_iXP[id])
		ze_colored_print(id, "!gAccount Privilages!y: (VIP ACCESS!y): (!gNO!y) | (ADMIN ACCESS!y): (!gYES!y)")
	}
	else 
	{
		ze_colored_print(id, "!gUser Info!y: (Name!y: !g%s!y) !t/!y (SteamID !y^"!g%s^"!y) / (IP !y^"!g%s!y^"!y) ", szName, szAuthID, szIP)
		ze_colored_print(id, "!gAccount Info!y: (Level !g%i !y/ Escapes !g%d!y)", g_iLevel[id] ,g_iXP[id])
		ze_colored_print(id, "!gAccount Privilages!y: (VIP ACCESS!y): (!gNO!y) | (ADMIN ACCESS!y): (!gNO!y)")
	}
}

public Check_User_Level(id)
{
	if (!is_user_connected(id))
		return
	
	if (g_iLevel[id] < MAX_LEVEL)
	{
		new szName[32]
		
		if (g_iXP[id] >= g_iMaxXP[id])
		{
			if (get_pcvar_num(g_pCvarStartFromZero) == 1)
			{
				g_iXP[id] = 0
			}
			
			g_iLevel[id]++
			g_iMaxXP[id] = g_iMaxLevelsXP[g_iLevel[id]]
			get_user_name(id, szName, charsmax(szName))
			ze_colored_print(0, "Congratulations to !g%s !yfor archiving (!gLevel!y:!g%i!y) and !y(!g%d escapes!y)!", szName, g_iLevel[id] ,g_iXP[id])
			ExecuteForward(Fw_LevelUP, ForwardReturn, id)
			SaveData(id)
			PlaySound(0, LEVELUP)
			
			if (get_pcvar_num(g_pCvarLevelEffects) != 0)
			{
				// Screen Fade
				message_begin(MSG_ONE, get_user_msgid("ScreenFade"), {0,0,0}, id)
				write_short(4096*2)
				write_short(4096*5)
				write_short(0x0001)
				write_byte(random(256))
				write_byte(random(256))
				write_byte(random(256))
				write_byte(150)
				message_end()
				
				// Screen Shake
				message_begin(MSG_ONE, get_user_msgid("ScreenShake"), {0,0,0}, id)
				write_short(255<<14)
				write_short(10<<14)
				write_short(255<<14)
				message_end()
			}
		}
	}
}

public ze_user_infected(iVictim, iInfector)
{
	if (iInfector == 0)
		return
	
	new iXP = g_bIsDoubleHours ? (get_pcvar_num(g_pCvarZombieInfect) * 2) : get_pcvar_num(g_pCvarZombieInfect)

	if((ze_get_vip_flags(iInfector) & VIP_B))
    {
        iXP *= 2
    }
	Reward(iInfector, (g_iXP[iInfector] + iXP))
}

public Fw_TakeDamage_Post(iVictim, iInflictor, iAttacker, Float:fDamage, bitsDamageType)
{
	// Player Damage Himself
	if (iVictim == iAttacker || !is_user_alive(iVictim) || !is_user_alive(iAttacker) || ze_is_user_zombie(iAttacker) || !get_pcvar_num(g_pCvarEnableDamage))
		return HC_CONTINUE
	
	// Same Team?
	if (get_member(iAttacker, m_iTeam) == get_member(iVictim, m_iTeam))
		return HC_CONTINUE
	
	// Store Damage For every Player
	g_fDamage[iAttacker] += fDamage
	
	// Damage Calculator Equal or Higher than needed damage
	if (g_fDamage[iAttacker] >= get_pcvar_float(g_pCvarRequiredDamage))
	{
		// Player did damage that a multiplication of the cvar? Increase coins by this factor
		new iMultiplier = floatround(g_fDamage[iAttacker] / get_pcvar_float(g_pCvarRequiredDamage))
		new iXP = ((g_bIsDoubleHours ? (get_pcvar_num(g_pCvarDamageAward) * 2) : get_pcvar_num(g_pCvarDamageAward)) * iMultiplier)
		Reward(iAttacker, (g_iXP[iAttacker] + iXP))
		
		// Rest The Damage Calculator
		g_fDamage[iAttacker] = 0.0
	}
	return HC_CONTINUE
}

public Reward(id, XP)
{
	if ((g_iLevel[id] + 1) < MAX_LEVEL)
	{
		g_iXP[id] = XP
		Check_User_Level(id)
	}
	else
	{
		if ((g_iXP[id] + XP) >= g_iMaxLevelsXP[MAX_LEVEL - 1])
		{
			g_iXP[id] = g_iMaxXP[id] = g_iMaxLevelsXP[MAX_LEVEL - 1]
		}
	}
	SaveData(id)
}

public SaveData(id)
{
	new szAuthID[35], szName[64]
	get_user_authid(id, szAuthID, charsmax(szAuthID))
	get_user_name(id, szName, charsmax(szName))
	
	if (!get_pcvar_num(g_pCvarSaveType))
	{
		new szData[256]
		formatex(szData , charsmax(szData), "%i %i", g_iLevel[id], g_iXP[id])
		
		// Open the Vaults
		g_iLevelsVaultHandle = nvault_open(g_szLevelsVault)
		g_iRanksVaultHandle = nvault_open(g_szRanksVault)
		
		// Saves His Data
		nvault_set(g_iLevelsVaultHandle, szAuthID, szData)
		nvault_set(g_iRanksVaultHandle, szAuthID, szName)
		
		// Close Vaults
		nvault_close(g_iLevelsVaultHandle)
		nvault_close(g_iRanksVaultHandle)
		
		new logtext[196], times[25], dest[64]
		get_localinfo("amxx_logs",dest,charsmax(dest))
		format(dest,charsmax(dest),"%s/Levels,Escapes Logs",dest)
		if(!dir_exists(dest))
		{
			mkdir(dest)
		}
		get_time("%Y",times,4)
		format(dest,charsmax(dest),"%s/%s",dest,times)
		if(!dir_exists(dest))
		{
			mkdir(dest)
		}
		get_time("%B",times,charsmax(times))
		format(dest,charsmax(dest),"%s/%s.txt",dest,times)
		if(!file_exists(dest))
		{
			write_file(dest,"")
		}
		get_time( "%d.%m.%Y", times, charsmax(times) );
		formatex(logtext, charsmax(logtext), "[%s] [Name: %s] - [SteamID %s] - [[Level] - %i] - [XP: %i]", times, szName, szAuthID, g_iLevel[id], g_iXP[id]);
		write_file(dest, logtext)
    
		
	}
	else
	{
		new szData[256]
		formatex(szData , charsmax(szData), "%i %i", g_iLevel[id], g_iXP[id])
		
		new szQuery[128]
		formatex(szQuery, charsmax(szQuery), "UPDATE `zombie_escape_levels` SET `Levels` = '%d', `Escapes` = '%d' WHERE ( 'SteamID' = '%s');", g_iLevel[id],  g_iXP[id], szAuthID)
		SQL_ThreadQuery(g_hTuple, "QuerySelectData", szQuery)
	}
}

public QuerySetData(iFailState, Handle:hQuery, szError[], iError, szData[], iSize, Float:flQueueTime)
{
	SQL_IsFail(iFailState, iError, szError, g_szLogFile)
}

public QuerySetData2(iFailState, Handle:hQuery, szError[], iError, szData[], iSize, Float:flQueueTime)
{
	SQL_IsFail(iFailState, iError, szError, g_szLogFile)
}

public LoadData(id)
{
	new szAuthID[35], szName[64], szIP[35]
	get_user_authid(id, szAuthID, charsmax(szAuthID))
	get_user_name(id, szName, charsmax(szName))
	get_user_ip(id, szIP, charsmax(szIP), 1)
	
	if (!get_pcvar_num(g_pCvarSaveType))
	{
		new szData[256], iTimestamp, iExists
		
		// Open the Vault
		g_iLevelsVaultHandle = nvault_open(g_szLevelsVault)
		
		iExists = nvault_lookup(g_iLevelsVaultHandle, szAuthID, szData, charsmax(szData), iTimestamp)
		
		// Close Vault
		nvault_close(g_iLevelsVaultHandle)
		
		if (!iExists)
		{
			g_iLevel[id] = 0
			g_iXP[id] = get_pcvar_num(g_pCvarStartXP)
			SaveData(id)
			ze_colored_print(id, "Account Created!y: Name!y: (!g%s!y) SteamID !y^"!g%s!y^"", szName, szAuthID)
		}
		else
		{
			new iLevel[32], iXP[32]
			parse(szData, iLevel, 31, iXP, 31)
			
			g_iLevel[id] = str_to_num(iLevel)
			g_iXP[id] = str_to_num(iXP)

			if((ze_get_vip_flags(id) & VIP_B) && is_user_admin(id))
			{
				ze_colored_print(id, "!gAccount Loaded!y: (Name!y: !g%s!y) !t/!y (SteamID !y^"!g%s^"!y)", szName, szAuthID)
				ze_colored_print(id, "!gAccount Info!y: (Level !g%i !y/ Escapes !g%d!y) / (!gVIP ACCESS!y): (!gYES!y) (!gVPN ALLOWED!y): (!gYES!y)", g_iLevel[id] ,g_iXP[id])
			}
			else if(ze_get_vip_flags(id) & VIP_B)
			{
				ze_colored_print(id, "!gAccount Loaded!y: (Name!y: !g%s!y) !t/!y (SteamID !y^"!g%s^"!y)", szName, szAuthID)
				ze_colored_print(id, "!gAccount Info!y: (Level !g%i !y/ Escapes !g%d!y) / (!gVIP ACCESS!y): (!gYES!y) (!gVPN ALLOWED!y): (!gNO!y)", g_iLevel[id] ,g_iXP[id])
			}
			else if(is_user_admin(id))
			{
				ze_colored_print(id, "!gAccount Loaded!y: (Name!y: !g%s!y) !t/!y (SteamID !y^"!g%s^"!y)", szName, szAuthID)
				ze_colored_print(id, "!gAccount Info!y: (Level !g%i !y/ Escapes !g%d!y) / (!gVIP ACCESS!y): (!gNO!y) (!gVPN ALLOWED!y): (!gYES!y)", g_iLevel[id] ,g_iXP[id])
			}
			else 
			{
				ze_colored_print(id, "!gAccount Loaded!y: (Name!y: !g%s!y) !t/!y (SteamID !y^"!g%s^"!y)", szName, szAuthID)
				ze_colored_print(id, "!gAccount Info!y: (Level !g%i !y/ Escapes !g%d!y) / (!gVIP ACCESS!y): (!gNO!y) (!gVPN ALLOWED!y): (!gNO!y)", g_iLevel[id] ,g_iXP[id])
			}
		}
		
		g_iMaxXP[id] = g_iMaxLevelsXP[g_iLevel[id]]
	}
	else
	{
		new szQuery[128], szData[5]
		formatex(szQuery, charsmax(szQuery), "SELECT * FROM `zombie_escape_levels` WHERE ( 'SteamID' = '%s' );", szAuthID)
		
		num_to_str(id, szData, charsmax(szData))
		SQL_ThreadQuery(g_hTuple, "QuerySelectData", szQuery, szData, charsmax(szData))

		g_iMaxXP[id] = g_iMaxLevelsXP[g_iLevel[id]]
	}
}

public QuerySelectData(iFailState, Handle:hQuery, szError[], iError, szData[])
{
	if (SQL_IsFail(iFailState, iError, szError, g_szLogFile))
		return
	
	new id = str_to_num(szData)

	
	// No results for this query means this is new player
	if (!SQL_NumResults(hQuery))
	{
		g_iLevel[id] = 0
		g_iXP[id] = get_pcvar_num(g_pCvarStartXP)

		new szAuthID[35], szName[64], szIP[35]
		get_user_authid(id, szAuthID, charsmax(szAuthID))
		get_user_name(id, szName, charsmax(szName))
		get_user_ip(id, szIP, charsmax(szIP), 1)

		new szQuery[128]

		formatex(szQuery, charsmax(szQuery), "INSERT INTO `zombie_escape_levels` (`SteamID`, `Levels`, `Escapes`) VALUES ('%s', '%d', '%d');", szAuthID, g_iLevel[id], g_iXP[id])
		SQL_ThreadQuery(g_hTuple, "QueryInsertData", szQuery)

		return
	}
	// Get the "Escape" column number (It's 2, always i don't like to hardcode :p)
	new iXP_Column = SQL_FieldNameToNum(hQuery, "Escapes")
	new iLevels_Column = SQL_FieldNameToNum(hQuery, "Levels")
	
	// Read the coins of this player
	g_iXP[id] = SQL_ReadResult(hQuery, iXP_Column)
	g_iLevel[id] = SQL_ReadResult(hQuery, iLevels_Column)
}

public QueryInsertData(iFailState, Handle:hQuery, szError[], iError, szData[], iSize, Float:flQueueTime)
{
	SQL_IsFail(iFailState, iError, szError, g_szLogFile)
}

public native_ze_get_user_xp(id)
{
	if(!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false;
	}
	
	return g_iXP[id]
}

public native_ze_set_user_xp(id, amount)
{
	if(!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false
	}
	
	DoubleHours()
	new addedXP = (amount - g_iXP[id])
	new iXP = g_bIsDoubleHours ? (addedXP * 2) : addedXP
	Reward(id, g_iXP[id] + iXP)
	return true
}

public native_ze_get_user_level(id)
{
	if(!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false;
	}
	
	return g_iLevel[id]
}

public native_ze_set_user_level(id, amount)
{
	if(!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false
	}
	
	if (amount > MAX_LEVEL)
	{
		log_error(AMX_ERR_NATIVE, "Level must be less than or equal to MAX_LEVEL (%d)", MAX_LEVEL)
		return false
	}
	
	g_iLevel[id] = amount
	
	if (get_pcvar_num(g_pCvarStartFromZero) == 1)
	{
		g_iXP[id] = 0
	}
	SaveData(id)
	
	return true
}

public native_ze_get_user_max_xp(id)
{
	if(!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false
	}
	
	return g_iMaxXP[id]
}

stock DoubleHours()
{
	new szTime[3], szDoubleHours[32], szDoubleHours_Start[32], szDoubleHours_End[32]
	get_time("%H", szTime, charsmax(szTime))
	
	get_pcvar_string(g_pCvarDoubleXP, szDoubleHours, charsmax(szDoubleHours))
	
	for (new ch = 0; ch <= charsmax(szDoubleHours); ch++)
	{
		if (szDoubleHours[ch] == '-')
			szDoubleHours[ch] = ' '
	}
	
	parse(szDoubleHours, szDoubleHours_Start, charsmax(szDoubleHours_Start), szDoubleHours_End, charsmax(szDoubleHours_End))
	
	new iTime, iDoubleHourStart, iDoubleHourEnd
	
	iTime = str_to_num(szTime)
	iDoubleHourStart = str_to_num(szDoubleHours_Start)
	iDoubleHourEnd = str_to_num(szDoubleHours_End)
	
	if (iDoubleHourEnd > iTime >= iDoubleHourStart)
	{
		g_bIsDoubleHours = true
	}
	else
	{
		g_bIsDoubleHours = false
	}
}

Includes used + ze_infections.sma (has native) : https://files.fm/u/jgxhuddxf


What I want is (g_iLevel[id], g_iXP[id]) to be saved/loaded on user's steamid.If you need more info,I can give.
KerwinSweet2003 is offline
KerwinSweet2003
Junior Member
Join Date: Nov 2022
Old 06-05-2023 , 15:30   Re: Level System trying to move to SQL Database
Reply With Quote #8

Quote:
Originally Posted by Bugsy View Post
Is that happening on an INSERT INTO? You can try using REPLACE INTO instead, but you'll need to have all data specified for the existing row to not lose any data.

I don't have the time or patience to read all of your code, but if you can provide the table structure and SQL statements involved, I can help.
Now I read again your message,I tried using REPLACE INTO,by doing that the error dissapears,but when the player gets xp,it just replaces the xp he got,it doesn't add +1 xp,it just replaces it instead of adding it.If you understood what I mean
KerwinSweet2003 is offline
bigdaddy424
Senior Member
Join Date: Oct 2021
Location: Jupiter
Old 06-05-2023 , 20:34   Re: Level System trying to move to SQL Database
Reply With Quote #9

on line 227 you have this
Code:
if (hSQLConnection != Empty_Handle) {     log_amx("[MySQL][LVL] Successfully connected to host: %s (ALL IS OK).", szHost)     SQL_FreeHandle(hSQLConnection) } else {     // Disable plugin     set_fail_state("[LVL] Failed to connect to MySQL database: %s.", szError) }
youre closing the connection with FreeHandle mate.

btw the database cvars are not save and can be seen by anyone else.
here's a template to get started
Code:
#include <amxmodx> #include <sqlx> //#define USE_OTHER_DATABASE #if defined USE_OTHER_DATABASE     #define MYSQL_HOST ""     #define MYSQL_USER ""     #define MYSQL_PASSWORD ""     #define MYSQL_DATABASE "" #endif #define MYSQL_TABLE "" new Handle:MYSQL_CONNECTION public plugin_cfg(){     MYSQL_Init() } public plugin_end(){     SQL_FreeHandle(MYSQL_CONNECTION) } public MYSQL_Init(){     #if !defined USE_OTHER_DATABASE         MYSQL_CONNECTION = SQL_MakeStdTuple() // configs/sql.cfg     #else         MYSQL_CONNECTION = SQL_MakeDbTuple(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE)     #endif     SQL_ThreadQuery(MYSQL_CONNECTION, "IgnoredOutput", "SELECT 1;") } public IgnoredOutput(failState, Handle:query, error[], errNum){     if(failState == TQUERY_CONNECT_FAILED){         set_fail_state("Connection to database server failed")     }     if(errNum){         log_amx("MYSQL Error : (%d)%s", errNum, error)     } }
good luck
__________________
bigdaddy424 is offline
KerwinSweet2003
Junior Member
Join Date: Nov 2022
Old 06-06-2023 , 14:46   Re: Level System trying to move to SQL Database
Reply With Quote #10

Quote:
Originally Posted by bigdaddy424 View Post
on line 227 you have this
Code:
if (hSQLConnection != Empty_Handle) {     log_amx("[MySQL][LVL] Successfully connected to host: %s (ALL IS OK).", szHost)     SQL_FreeHandle(hSQLConnection) } else {     // Disable plugin     set_fail_state("[LVL] Failed to connect to MySQL database: %s.", szError) }
youre closing the connection with FreeHandle mate.

btw the database cvars are not save and can be seen by anyone else.
here's a template to get started
Code:
#include <amxmodx> #include <sqlx> //#define USE_OTHER_DATABASE #if defined USE_OTHER_DATABASE     #define MYSQL_HOST ""     #define MYSQL_USER ""     #define MYSQL_PASSWORD ""     #define MYSQL_DATABASE "" #endif #define MYSQL_TABLE "" new Handle:MYSQL_CONNECTION public plugin_cfg(){     MYSQL_Init() } public plugin_end(){     SQL_FreeHandle(MYSQL_CONNECTION) } public MYSQL_Init(){     #if !defined USE_OTHER_DATABASE         MYSQL_CONNECTION = SQL_MakeStdTuple() // configs/sql.cfg     #else         MYSQL_CONNECTION = SQL_MakeDbTuple(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE)     #endif     SQL_ThreadQuery(MYSQL_CONNECTION, "IgnoredOutput", "SELECT 1;") } public IgnoredOutput(failState, Handle:query, error[], errNum){     if(failState == TQUERY_CONNECT_FAILED){         set_fail_state("Connection to database server failed")     }     if(errNum){         log_amx("MYSQL Error : (%d)%s", errNum, error)     } }
good luck
I think I managed to replace everything you gave me but I still have the same problem,when player is getting xp,there is this error in console (failed: Duplicate entry 'STEAM_0:0:224689198' for key 'zombie_escape_levels.PRIMARY') and in mysql table this is how it looks like (https://imgur.com/a/kRwI1TG)

Code:
#include <zombie_escape>
#include <ze_vip>
#include <amxmodx>
#include <sqlx>


// Native witch ze_infections plugin (by Urban)
native ze_get_infections(id);

#define USE_OTHER_DATABASE

// Defines
#define MAX_LEVEL 40
#define TASK_SHOWHUD 2020
#define TASK_DOUBLE 1133
#define REPEAT_TIME 60.0
#define ID_SHOWHUD (taskid - TASK_SHOWHUD)
#define LEVELUP "zombie_escape/new_level.wav"



#if defined USE_OTHER_DATABASE
    #define MYSQL_HOST "hidden"
    #define MYSQL_USER "hidden"
    #define MYSQL_PASSWORD "hidden"
    #define MYSQL_DATABASE "hidden"
#endif
#define MYSQL_TABLE "zombie_escape_levels"
new Handle:MYSQL_CONNECTION

new const g_iMaxLevelsXP[MAX_LEVEL] =
{
20, // 1
60, // 2
120, // 3
200, // 4
300, // 5
400, // 6
580, // 7
700, // 8
920, // 9
1090, // 10
1330, // 11
1550, // 12
1830, // 13
2090, // 14
2410, // 15
2710, // 16
3070, // 17
3410, // 18
3790, // 19
4190, // 20
5210, // 21
6690, // 22
8710, // 23
11190, // 24
14210, // 25
17690, // 26
21710, // 27
26190, // 28
31210, // 29
36690, // 30
46710, // 31
61690, // 32
81710, // 33
106690, // 34
136710, // 35
176690, // 36
226710, // 37
286690, // 38
366710, // 39
456400, // 40
}

// Constants
new const g_szLevelsVault[] = "Levels"
new const g_szRanksVault[] = "Ranks"
new const g_szLogFile[] = "Levels.log" // MySQL Errors log file
new const g_szTable[] = 
" \
	CREATE TABLE IF NOT EXISTS `zombie_escape_levels` \
	( \
		`SteamID` varchar(64) NOT NULL, \
		`Levels` int(16) NOT NULL, \
		`Escapes` int(16) NOT NULL, \
		PRIMARY KEY (`SteamID`) \
	); \
"

// Messages
const Float:HUD_SPECT_X = -1.0
const Float:HUD_SPECT_Y = 0.70
const Float:HUD_STATS_X = 0.015
const Float:HUD_STATS_Y = 0.33

const HUD_STATS_ZOMBIE_R = 0
const HUD_STATS_ZOMBIE_G = 255
const HUD_STATS_ZOMBIE_B = 0

const HUD_STATS_HUMAN_R = 0
const HUD_STATS_HUMAN_G = 255
const HUD_STATS_HUMAN_B = 0

const HUD_STATS_SPEC_R = 0
const HUD_STATS_SPEC_G = 255
const HUD_STATS_SPEC_B = 0

// Variables
new g_iLevel[33],
g_iXP[33],
g_iMaxXP[33],
Float:g_fDamage[33],
g_MsgSync,
g_iLevelsVaultHandle,
g_Online,
g_iRanksVaultHandle,
Fw_LevelUP,
ForwardReturn,
bool:g_bIsDoubleHours

// Cvars
new g_pCvarZombieInfect,
g_pCvarEscapeSuccess,
g_pCvarEnableDamage,
g_pCvarRequiredDamage,
g_pCvarDamageAward,
g_pCvarStartXP,
g_pCvarPercentageStyle,
g_pCvarStartFromZero,
g_pCvarAddCommas,
g_pCvarLevelEffects,
g_pCvarSaveType,
g_pCvarDoubleXP

public plugin_natives()
{
register_native("ze_get_user_xp", "native_ze_get_user_xp", 1)
register_native("ze_set_user_xp", "native_ze_set_user_xp", 1)
register_native("ze_get_user_level", "native_ze_get_user_level", 1)
register_native("ze_set_user_level", "native_ze_set_user_level", 1)
register_native("ze_get_user_max_xp", "native_ze_get_user_max_xp", 1)
}

public plugin_precache()
{
	precache_sound(LEVELUP)
}

public plugin_init()
{
	register_plugin("[ZE] Level-XP System", "1.9", "Raheem/JaCk")

	register_clcmd("say /info", "NextLevel")

// Hook Chains
RegisterHookChain(RG_CBasePlayer_TakeDamage, "Fw_TakeDamage_Post", 1)

Fw_LevelUP = CreateMultiForward("ze_on_levelup", ET_IGNORE, FP_CELL)

// Cvars
g_pCvarZombieInfect = register_cvar("ze_zombie_infect", "0")
g_pCvarEscapeSuccess = register_cvar("ze_escape_success", "1")
g_pCvarEnableDamage = register_cvar("ze_enable_dmg", "0")
g_pCvarRequiredDamage = register_cvar("ze_required_dmg", "50.0")
g_pCvarDamageAward = register_cvar("ze_dmg_award", "3")
g_pCvarStartXP = register_cvar("ze_start_xp", "1")
g_pCvarPercentageStyle = register_cvar("ze_enable_percentage_style", "0")
g_pCvarStartFromZero = register_cvar("ze_new_level_zero_xp", "1")
g_pCvarAddCommas = register_cvar("ze_add_commas_to_xp", "1")
g_pCvarLevelEffects = register_cvar("ze_level_up_effects", "0")
g_pCvarDoubleXP = register_cvar("ze_double_xp", "21-10")

g_pCvarSaveType = register_cvar("ze_levels_save_type", "0")

// Messages
g_MsgSync = CreateHudSyncObj()

	set_task(0.1, "Delay_MySQL_Init")

DoubleHours()

if (g_bIsDoubleHours)
{
	set_task(REPEAT_TIME, "HappyHours", TASK_DOUBLE, _, _, "b")
}
}

public plugin_end()
{
	if (get_pcvar_num(g_pCvarSaveType))
	{
	SQL_FreeHandle(MYSQL_CONNECTION)
	}
}

public plugin_cfg()
{
    MYSQL_Init()
}

public Delay_MySQL_Init()
{
	MYSQL_Init()
}

public MYSQL_Init(){
    #if !defined USE_OTHER_DATABASE
        MYSQL_CONNECTION = SQL_MakeStdTuple() // configs/sql.cfg
    #else
        MYSQL_CONNECTION = SQL_MakeDbTuple(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE)
    #endif

    SQL_ThreadQuery(MYSQL_CONNECTION, "IgnoredOutput", "SELECT 1;")
	SQL_ThreadQuery(MYSQL_CONNECTION, "QueryCreateTable", g_szTable)
}

public IgnoredOutput(failState, Handle:query, error[], errNum){
    if(failState == TQUERY_CONNECT_FAILED){
        set_fail_state("Connection to database server failed")
    }

    if(errNum){
        log_amx("MYSQL Error : (%d)%s", errNum, error)
    }
}


public QueryCreateTable(iFailState, Handle:hQuery, szError[], iError, szData[], iSize, Float:flQueueTime)
{
SQL_IsFail(iFailState, iError, szError, g_szLogFile)
}

public client_putinserver(id)
{
if(is_user_hltv(id) || is_user_bot(id))
	return
	
	// Just 1 second delay
	set_task(5.0, "DelayLoad", id)
	
	// Other tasks
	set_task(1.0, "Show_Hud", id+TASK_SHOWHUD, _, _, "b")
	
	if (g_bIsDoubleHours)
	{
	    set_task(REPEAT_TIME, "HappyHours", id+TASK_DOUBLE, _, _, "b")
	}

	if(ze_is_user_vip(id) & VIP_B)
	{
		g_Online++
	}
}

public HappyHours(taskid)
{
	DoubleHours()
	
	if (!g_bIsDoubleHours)
		remove_task(taskid)
	
	new szDoubleHours[32]
	
	get_pcvar_string(g_pCvarDoubleXP, szDoubleHours, charsmax(szDoubleHours))
	
	set_hudmessage(0, 255, 0, -0.5, 0.20, 0, 0.0, 10.0)
	show_hudmessage(0, "Double Experience Time")
}

public DelayLoad(id)
{
	// Load his data
	LoadData(id)
}

public client_disconnected(id)
{
	if(is_user_hltv(id) || is_user_bot(id))
		return
	
	remove_task(id+TASK_SHOWHUD)
	remove_task(id)

	if(ze_is_user_vip(id) & VIP_B)
	{
		g_Online--
	}
}

public Show_Hud(taskid)
{  
	new iPlayer = ID_SHOWHUD
	
	if (!is_user_alive(iPlayer))
	{
		iPlayer = pev(iPlayer, pev_iuser2)
		
		if (!is_user_alive(iPlayer))
			return
	}
	
	if (get_pcvar_num(g_pCvarPercentageStyle) != 0)
	{
		if(iPlayer != ID_SHOWHUD)
		{
			set_hudmessage(HUD_STATS_SPEC_R, HUD_STATS_SPEC_G, HUD_STATS_SPEC_B, HUD_SPECT_X, HUD_SPECT_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
			ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40 ^n[Escapes] - %0.2f %", g_iLevel[iPlayer], (float(g_iXP[iPlayer])/float(g_iMaxXP[iPlayer]), g_Online) * 100.0)
		}
		else if (ze_is_user_zombie(iPlayer))
		{
			new zeInfNeed = get_cvar_num("ze_infections_num")
			
			set_hudmessage(HUD_STATS_ZOMBIE_R, HUD_STATS_ZOMBIE_G, HUD_STATS_ZOMBIE_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
			ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40 ^n[Escapes] - %0.2f %^n[Infections] - %d/%d", g_iLevel[ID_SHOWHUD], (float(g_iXP[ID_SHOWHUD])/float(g_iMaxXP[ID_SHOWHUD]), g_Online) * 100.0, ze_get_infections(ID_SHOWHUD), zeInfNeed)
		}
		else
		{
			set_hudmessage(HUD_STATS_HUMAN_R, HUD_STATS_HUMAN_G, HUD_STATS_HUMAN_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
			ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40 ^n[Escapes] - %0.2f %", g_iLevel[ID_SHOWHUD], (float(g_iXP[ID_SHOWHUD])/float(g_iMaxXP[ID_SHOWHUD]), g_Online) * 100.0)
		}
	}
	else
	{
		if(iPlayer != ID_SHOWHUD)
		{
			if (get_pcvar_num(g_pCvarAddCommas) == 1)
			{
				new szSpecXP[15], szSpecMaxXP[15]
				
				AddCommas(g_iXP[iPlayer], szSpecXP, charsmax(szSpecXP))
				AddCommas(g_iMaxXP[iPlayer], szSpecMaxXP, charsmax(szSpecMaxXP))
				
				set_hudmessage(HUD_STATS_SPEC_R, HUD_STATS_SPEC_G, HUD_STATS_SPEC_B, HUD_SPECT_X, HUD_SPECT_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n[Escapes] - %s/%s", g_iLevel[iPlayer], szSpecXP, szSpecMaxXP, g_Online)
			}
			else
			{
				set_hudmessage(HUD_STATS_SPEC_R, HUD_STATS_SPEC_G, HUD_STATS_SPEC_B, HUD_SPECT_X, HUD_SPECT_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n[Escapes] - %d/%d", g_iLevel[iPlayer], g_iXP[iPlayer], g_iMaxXP[iPlayer], g_Online)
			}  
		}
		else if (ze_is_user_zombie(iPlayer))
		{
			if (get_pcvar_num(g_pCvarAddCommas) == 1)
			{
				new zeInfNeed = get_cvar_num("ze_infections_num")
				new szZombieXP[15], szZombieMaxXP[15]
				
				AddCommas(g_iXP[ID_SHOWHUD], szZombieXP, charsmax(szZombieXP))
				AddCommas(g_iMaxXP[ID_SHOWHUD], szZombieMaxXP, charsmax(szZombieMaxXP))
				
				set_hudmessage(HUD_STATS_ZOMBIE_R, HUD_STATS_ZOMBIE_G, HUD_STATS_ZOMBIE_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n[Escapes] - %s/%s^n[Infections] - %d/%d", g_iLevel[ID_SHOWHUD], szZombieXP, szZombieMaxXP, ze_get_infections(ID_SHOWHUD), zeInfNeed, g_Online)
			}
			else
			{
				new zeInfNeed = get_cvar_num("ze_infections_num")
				set_hudmessage(HUD_STATS_ZOMBIE_R, HUD_STATS_ZOMBIE_G, HUD_STATS_ZOMBIE_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n[Escapes] - %d/%d^n[Infections] - %d/%d", g_iLevel[ID_SHOWHUD], g_iXP[ID_SHOWHUD], g_iMaxXP[ID_SHOWHUD], ze_get_infections(ID_SHOWHUD), zeInfNeed, g_Online)
			}
		}
		else
		{
			if (get_pcvar_num(g_pCvarAddCommas) == 1)
			{
				new szHumanXP[15], szHumanMaxXP[15]
				
				AddCommas(g_iXP[ID_SHOWHUD], szHumanXP, charsmax(szHumanXP))
				AddCommas(g_iMaxXP[ID_SHOWHUD], szHumanMaxXP, charsmax(szHumanMaxXP))
				
				set_hudmessage(HUD_STATS_HUMAN_R, HUD_STATS_HUMAN_G, HUD_STATS_HUMAN_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n[Escapes] - %s/%s", g_iLevel[ID_SHOWHUD], szHumanXP, szHumanMaxXP, g_Online)
			}
			else
			{
				set_hudmessage(HUD_STATS_HUMAN_R, HUD_STATS_HUMAN_G, HUD_STATS_HUMAN_B, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
				ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "[Level] - %d|40^n^n[Infections] - %d/%d", g_iLevel[ID_SHOWHUD], g_iXP[ID_SHOWHUD], g_iMaxXP[ID_SHOWHUD], g_Online)
			}
		}
	}
}

public ze_roundend(WinTeam)
{
	if (WinTeam == ZE_TEAM_HUMAN)
	{
		new iXP = g_bIsDoubleHours ? (get_pcvar_num(g_pCvarEscapeSuccess) * 2) : get_pcvar_num(g_pCvarEscapeSuccess)
		
		for(new id = 1; id <= get_member_game(m_nMaxPlayers); id++)
		{
			if( (ze_get_vip_flags(id) & VIP_B) )
			{
				iXP *= 2
			}

			if (!is_user_alive(id) || ze_is_user_zombie(id))
				continue
			
			Reward(id, (g_iXP[id] + iXP))
			ze_colored_print(id, "Good Job,Humans have escaped the Zombies! +!g%d !yEscape(s)", (iXP))
		}
	}
	
	remove_task(TASK_SHOWHUD)
}

public NextLevel(id)
{
	new szAuthID[35], szName[64], szIP[35]
	get_user_authid(id, szAuthID, charsmax(szAuthID))
	get_user_name(id, szName, charsmax(szName))
	get_user_ip(id, szIP, charsmax(szIP), 1)


	new flags = (get_user_flags(id))

	if((ze_get_vip_flags(id) & read_flags("b")) && flags & ADMIN_KICK)
	{
		ze_colored_print(id, "!gUser Info!y: (Name!y: !g%s!y) !t/!y (SteamID !y^"!g%s^"!y) / (IP !y^"!g%s!y^") ", szName, szAuthID, szIP)
		ze_colored_print(id, "!gAccount Info!y: (Level !g%i !y/ Escapes !g%d!y)", g_iLevel[id] ,g_iXP[id])
		ze_colored_print(id, "!gAccount Privilages!y: (VIP ACCESS!y): (!gYES!y) | (ADMIN ACCESS!y): (!gYES!y)")
	}
	else if (ze_get_vip_flags(id) & read_flags("b"))
	{
		ze_colored_print(id, "!gUser Info!y: (Name!y: !g%s!y) !t/!y (SteamID !y^"!g%s^"!y) / (IP !y^"!g%s!y^"!y) ", szName, szAuthID, szIP)
		ze_colored_print(id, "!gAccount Info!y: (Level !g%i !y/ Escapes !g%d!y)", g_iLevel[id] ,g_iXP[id])
		ze_colored_print(id, "!gAccount Privilages!y: (VIP ACCESS!y): (!gYES!y) | (ADMIN ACCESS!y): (!gNO!y)")
	}
	else if (flags & ADMIN_KICK)
	{
		ze_colored_print(id, "!gUser Info!y: (Name!y: !g%s!y) !t/!y (SteamID !y^"!g%s^"!y) / (IP !y^"!g%s!y^"!y) ", szName, szAuthID, szIP)
		ze_colored_print(id, "!gAccount Info!y: (Level !g%i !y/ Escapes !g%d!y)", g_iLevel[id] ,g_iXP[id])
		ze_colored_print(id, "!gAccount Privilages!y: (VIP ACCESS!y): (!gNO!y) | (ADMIN ACCESS!y): (!gYES!y)")
	}
	else 
	{
		ze_colored_print(id, "!gUser Info!y: (Name!y: !g%s!y) !t/!y (SteamID !y^"!g%s^"!y) / (IP !y^"!g%s!y^"!y) ", szName, szAuthID, szIP)
		ze_colored_print(id, "!gAccount Info!y: (Level !g%i !y/ Escapes !g%d!y)", g_iLevel[id] ,g_iXP[id])
		ze_colored_print(id, "!gAccount Privilages!y: (VIP ACCESS!y): (!gNO!y) | (ADMIN ACCESS!y): (!gNO!y)")
	}
}

public Check_User_Level(id)
{
	if (!is_user_connected(id))
		return
	
	if (g_iLevel[id] < MAX_LEVEL)
	{
		new szName[32]
		
		if (g_iXP[id] >= g_iMaxXP[id])
		{
			if (get_pcvar_num(g_pCvarStartFromZero) == 1)
			{
				g_iXP[id] = 0
			}
			
			g_iLevel[id]++
			g_iMaxXP[id] = g_iMaxLevelsXP[g_iLevel[id]]
			get_user_name(id, szName, charsmax(szName))
			ze_colored_print(0, "Congratulations to !g%s !yfor archiving (!gLevel!y:!g%i!y) and !y(!g%d escapes!y)!", szName, g_iLevel[id] ,g_iXP[id])
			ExecuteForward(Fw_LevelUP, ForwardReturn, id)
			SaveData(id)
			PlaySound(0, LEVELUP)
			
			if (get_pcvar_num(g_pCvarLevelEffects) != 0)
			{
				// Screen Fade
				message_begin(MSG_ONE, get_user_msgid("ScreenFade"), {0,0,0}, id)
				write_short(4096*2)
				write_short(4096*5)
				write_short(0x0001)
				write_byte(random(256))
				write_byte(random(256))
				write_byte(random(256))
				write_byte(150)
				message_end()
				
				// Screen Shake
				message_begin(MSG_ONE, get_user_msgid("ScreenShake"), {0,0,0}, id)
				write_short(255<<14)
				write_short(10<<14)
				write_short(255<<14)
				message_end()
			}
		}
	}
}

public ze_user_infected(iVictim, iInfector)
{
	if (iInfector == 0)
		return
	
	new iXP = g_bIsDoubleHours ? (get_pcvar_num(g_pCvarZombieInfect) * 2) : get_pcvar_num(g_pCvarZombieInfect)

	if((ze_get_vip_flags(iInfector) & VIP_B))
    {
        iXP *= 2
    }
	Reward(iInfector, (g_iXP[iInfector] + iXP))
}

public Fw_TakeDamage_Post(iVictim, iInflictor, iAttacker, Float:fDamage, bitsDamageType)
{
	// Player Damage Himself
	if (iVictim == iAttacker || !is_user_alive(iVictim) || !is_user_alive(iAttacker) || ze_is_user_zombie(iAttacker) || !get_pcvar_num(g_pCvarEnableDamage))
		return HC_CONTINUE
	
	// Same Team?
	if (get_member(iAttacker, m_iTeam) == get_member(iVictim, m_iTeam))
		return HC_CONTINUE
	
	// Store Damage For every Player
	g_fDamage[iAttacker] += fDamage
	
	// Damage Calculator Equal or Higher than needed damage
	if (g_fDamage[iAttacker] >= get_pcvar_float(g_pCvarRequiredDamage))
	{
		// Player did damage that a multiplication of the cvar? Increase coins by this factor
		new iMultiplier = floatround(g_fDamage[iAttacker] / get_pcvar_float(g_pCvarRequiredDamage))
		new iXP = ((g_bIsDoubleHours ? (get_pcvar_num(g_pCvarDamageAward) * 2) : get_pcvar_num(g_pCvarDamageAward)) * iMultiplier)
		Reward(iAttacker, (g_iXP[iAttacker] + iXP))
		
		// Rest The Damage Calculator
		g_fDamage[iAttacker] = 0.0
	}
	return HC_CONTINUE
}

public Reward(id, XP)
{
	if ((g_iLevel[id] + 1) < MAX_LEVEL)
	{
		g_iXP[id] = XP
		Check_User_Level(id)
	}
	else
	{
		if ((g_iXP[id] + XP) >= g_iMaxLevelsXP[MAX_LEVEL - 1])
		{
			g_iXP[id] = g_iMaxXP[id] = g_iMaxLevelsXP[MAX_LEVEL - 1]
		}
	}
	SaveData(id)
}

public SaveData(id)
{
	new szAuthID[35], szName[64]
	get_user_authid(id, szAuthID, charsmax(szAuthID))
	get_user_name(id, szName, charsmax(szName))
	
	if (!get_pcvar_num(g_pCvarSaveType))
	{
		new szData[256]
		formatex(szData , charsmax(szData), "%i %i", g_iLevel[id], g_iXP[id])
		
		// Open the Vaults
		g_iLevelsVaultHandle = nvault_open(g_szLevelsVault)
		g_iRanksVaultHandle = nvault_open(g_szRanksVault)
		
		// Saves His Data
		nvault_set(g_iLevelsVaultHandle, szAuthID, szData)
		nvault_set(g_iRanksVaultHandle, szAuthID, szName)
		
		// Close Vaults
		nvault_close(g_iLevelsVaultHandle)
		nvault_close(g_iRanksVaultHandle)
		
		new logtext[196], times[25], dest[64]
		get_localinfo("amxx_logs",dest,charsmax(dest))
		format(dest,charsmax(dest),"%s/Levels,Escapes Logs",dest)
		if(!dir_exists(dest))
		{
			mkdir(dest)
		}
		get_time("%Y",times,4)
		format(dest,charsmax(dest),"%s/%s",dest,times)
		if(!dir_exists(dest))
		{
			mkdir(dest)
		}
		get_time("%B",times,charsmax(times))
		format(dest,charsmax(dest),"%s/%s.txt",dest,times)
		if(!file_exists(dest))
		{
			write_file(dest,"")
		}
		get_time( "%d.%m.%Y", times, charsmax(times) );
		formatex(logtext, charsmax(logtext), "[%s] [Name: %s] - [SteamID %s] - [[Level] - %i] - [XP: %i]", times, szName, szAuthID, g_iLevel[id], g_iXP[id]);
		write_file(dest, logtext)
    
		
	}
	else
	{
		new szData[256]
		formatex(szData , charsmax(szData), "%i %i", g_iLevel[id], g_iXP[id])
		
		new szQuery[128]
		formatex(szQuery, charsmax(szQuery), "UPDATE `zombie_escape_levels` SET `Levels` = '%d', `Escapes` = '%d' WHERE ( 'SteamID' = '%s');", g_iLevel[id],  g_iXP[id], szAuthID)
		SQL_ThreadQuery(MYSQL_CONNECTION, "QuerySelectData", szQuery)
	}
}

public QuerySetData(iFailState, Handle:hQuery, szError[], iError, szData[], iSize, Float:flQueueTime)
{
	SQL_IsFail(iFailState, iError, szError, g_szLogFile)
}

public QuerySetData2(iFailState, Handle:hQuery, szError[], iError, szData[], iSize, Float:flQueueTime)
{
	SQL_IsFail(iFailState, iError, szError, g_szLogFile)
}

public LoadData(id)
{
	new szAuthID[35], szName[64], szIP[35]
	get_user_authid(id, szAuthID, charsmax(szAuthID))
	get_user_name(id, szName, charsmax(szName))
	get_user_ip(id, szIP, charsmax(szIP), 1)
	
	if (!get_pcvar_num(g_pCvarSaveType))
	{
		new szData[256], iTimestamp, iExists
		
		// Open the Vault
		g_iLevelsVaultHandle = nvault_open(g_szLevelsVault)
		
		iExists = nvault_lookup(g_iLevelsVaultHandle, szAuthID, szData, charsmax(szData), iTimestamp)
		
		// Close Vault
		nvault_close(g_iLevelsVaultHandle)
		
		if (!iExists)
		{
			g_iLevel[id] = 0
			g_iXP[id] = get_pcvar_num(g_pCvarStartXP)
			SaveData(id)
			ze_colored_print(id, "Account Created!y: Name!y: (!g%s!y) SteamID !y^"!g%s!y^"", szName, szAuthID)
		}
		else
		{
			new iLevel[32], iXP[32]
			parse(szData, iLevel, 31, iXP, 31)
			
			g_iLevel[id] = str_to_num(iLevel)
			g_iXP[id] = str_to_num(iXP)

			if((ze_get_vip_flags(id) & VIP_B) && is_user_admin(id))
			{
				ze_colored_print(id, "!gAccount Loaded!y: (Name!y: !g%s!y) !t/!y (SteamID !y^"!g%s^"!y)", szName, szAuthID)
				ze_colored_print(id, "!gAccount Info!y: (Level !g%i !y/ Escapes !g%d!y) / (!gVIP ACCESS!y): (!gYES!y) (!gVPN ALLOWED!y): (!gYES!y)", g_iLevel[id] ,g_iXP[id])
			}
			else if(ze_get_vip_flags(id) & VIP_B)
			{
				ze_colored_print(id, "!gAccount Loaded!y: (Name!y: !g%s!y) !t/!y (SteamID !y^"!g%s^"!y)", szName, szAuthID)
				ze_colored_print(id, "!gAccount Info!y: (Level !g%i !y/ Escapes !g%d!y) / (!gVIP ACCESS!y): (!gYES!y) (!gVPN ALLOWED!y): (!gNO!y)", g_iLevel[id] ,g_iXP[id])
			}
			else if(is_user_admin(id))
			{
				ze_colored_print(id, "!gAccount Loaded!y: (Name!y: !g%s!y) !t/!y (SteamID !y^"!g%s^"!y)", szName, szAuthID)
				ze_colored_print(id, "!gAccount Info!y: (Level !g%i !y/ Escapes !g%d!y) / (!gVIP ACCESS!y): (!gNO!y) (!gVPN ALLOWED!y): (!gYES!y)", g_iLevel[id] ,g_iXP[id])
			}
			else 
			{
				ze_colored_print(id, "!gAccount Loaded!y: (Name!y: !g%s!y) !t/!y (SteamID !y^"!g%s^"!y)", szName, szAuthID)
				ze_colored_print(id, "!gAccount Info!y: (Level !g%i !y/ Escapes !g%d!y) / (!gVIP ACCESS!y): (!gNO!y) (!gVPN ALLOWED!y): (!gNO!y)", g_iLevel[id] ,g_iXP[id])
			}
		}
		
		g_iMaxXP[id] = g_iMaxLevelsXP[g_iLevel[id]]
	}
	else
	{
		new szQuery[128], szData[5]
		formatex(szQuery, charsmax(szQuery), "SELECT * FROM `zombie_escape_levels` WHERE ( 'SteamID' = '%s' );", szAuthID)
		
		num_to_str(id, szData, charsmax(szData))
		SQL_ThreadQuery(MYSQL_CONNECTION, "QuerySelectData", szQuery, szData, charsmax(szData))

		g_iMaxXP[id] = g_iMaxLevelsXP[g_iLevel[id]]
	}
}

public QuerySelectData(iFailState, Handle:hQuery, szError[], iError, szData[])
{
	if (SQL_IsFail(iFailState, iError, szError, g_szLogFile))
		return
	
	new id = str_to_num(szData)

	
	// No results for this query means this is new player
	if (!SQL_NumResults(hQuery))
	{
		g_iLevel[id] = 0
		g_iXP[id] = get_pcvar_num(g_pCvarStartXP)

		new szAuthID[35], szName[64], szIP[35]
		get_user_authid(id, szAuthID, charsmax(szAuthID))
		get_user_name(id, szName, charsmax(szName))
		get_user_ip(id, szIP, charsmax(szIP), 1)

		new szQuery[128]

		formatex(szQuery, charsmax(szQuery), "INSERT INTO `zombie_escape_levels` (`SteamID`, `Levels`, `Escapes`) VALUES ('%s', '%d', '%d');", szAuthID, g_iLevel[id], g_iXP[id])
		SQL_ThreadQuery(MYSQL_CONNECTION, "QueryInsertData", szQuery)

		return
	}
	// Get the "Escape" column number (It's 2, always i don't like to hardcode :p)
	new iXP_Column = SQL_FieldNameToNum(hQuery, "Escapes")
	new iLevels_Column = SQL_FieldNameToNum(hQuery, "Levels")
	
	// Read the coins of this player
	g_iXP[id] = SQL_ReadResult(hQuery, iXP_Column)
	g_iLevel[id] = SQL_ReadResult(hQuery, iLevels_Column)
}

public QueryInsertData(iFailState, Handle:hQuery, szError[], iError, szData[], iSize, Float:flQueueTime)
{
	SQL_IsFail(iFailState, iError, szError, g_szLogFile)
}

public native_ze_get_user_xp(id)
{
	if(!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false;
	}
	
	return g_iXP[id]
}

public native_ze_set_user_xp(id, amount)
{
	if(!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false
	}
	
	DoubleHours()
	new addedXP = (amount - g_iXP[id])
	new iXP = g_bIsDoubleHours ? (addedXP * 2) : addedXP
	Reward(id, g_iXP[id] + iXP)
	return true
}

public native_ze_get_user_level(id)
{
	if(!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false;
	}
	
	return g_iLevel[id]
}

public native_ze_set_user_level(id, amount)
{
	if(!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false
	}
	
	if (amount > MAX_LEVEL)
	{
		log_error(AMX_ERR_NATIVE, "Level must be less than or equal to MAX_LEVEL (%d)", MAX_LEVEL)
		return false
	}
	
	g_iLevel[id] = amount
	
	if (get_pcvar_num(g_pCvarStartFromZero) == 1)
	{
		g_iXP[id] = 0
	}
	SaveData(id)
	
	return true
}

public native_ze_get_user_max_xp(id)
{
	if(!is_user_connected(id))
	{
		log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player id (%d)", id)
		return false
	}
	
	return g_iMaxXP[id]
}

stock DoubleHours()
{
	new szTime[3], szDoubleHours[32], szDoubleHours_Start[32], szDoubleHours_End[32]
	get_time("%H", szTime, charsmax(szTime))
	
	get_pcvar_string(g_pCvarDoubleXP, szDoubleHours, charsmax(szDoubleHours))
	
	for (new ch = 0; ch <= charsmax(szDoubleHours); ch++)
	{
		if (szDoubleHours[ch] == '-')
			szDoubleHours[ch] = ' '
	}
	
	parse(szDoubleHours, szDoubleHours_Start, charsmax(szDoubleHours_Start), szDoubleHours_End, charsmax(szDoubleHours_End))
	
	new iTime, iDoubleHourStart, iDoubleHourEnd
	
	iTime = str_to_num(szTime)
	iDoubleHourStart = str_to_num(szDoubleHours_Start)
	iDoubleHourEnd = str_to_num(szDoubleHours_End)
	
	if (iDoubleHourEnd > iTime >= iDoubleHourStart)
	{
		g_bIsDoubleHours = true
	}
	else
	{
		g_bIsDoubleHours = false
	}
}
What should I change so I don't get that dublicate error and to be able to save player's data in 1 column instead of multiple colums?
KerwinSweet2003 is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 08:47.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode