/*================================================================================

	-----------------------------------
	-*- [ZP] Ammo Packs Save (Map-Scoped) -*-
	-----------------------------------

	Saves each player's ammo packs when they disconnect and restores them when
	they reconnect - but ONLY within the same map. The save file is wiped at the
	start of every map so ammo packs never carry over to the next map.

================================================================================*/

#include <amxmodx>
#include <amxmisc>
#include <zombie_plague_special>

#define PLUGIN_NAME	"[ZP] Ammo Packs Save (Map-Scoped)"
#define PLUGIN_VERSION	"1.0"
#define PLUGIN_AUTHOR	"Kimi Code"

#define SAVE_FILE	"data/zp_ammo_map.txt"

new g_szSavePath[128]

public plugin_init()
{
	register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR)

	new szBasedir[64]
	get_basedir(szBasedir, charsmax(szBasedir))
	formatex(g_szSavePath, charsmax(g_szSavePath), "%s/%s", szBasedir, SAVE_FILE)

	// Wipe the file at map start so ammo never carries to the next map
	wipe_save_file()
}

public client_disconnected(id)
{
	if(!is_user_connected(id) || is_user_bot(id))
		return

	new iAmmo = zp_get_user_ammo_packs(id)
	if(iAmmo <= 0)
		return

	new szKey[64]
	get_player_key(id, szKey, charsmax(szKey))

	save_entry(szKey, iAmmo)
}

public client_putinserver(id)
{
	if(!is_user_connected(id) || is_user_bot(id))
		return

	new szKey[64]
	get_player_key(id, szKey, charsmax(szKey))

	new iAmmo = load_entry(szKey)
	if(iAmmo > 0)
		zp_set_user_ammo_packs(id, iAmmo)
}

get_player_key(id, szKey[], iLen)
{
	new szAuth[64]
	get_user_authid(id, szAuth, charsmax(szAuth))

	// Cracked/no-Steam servers often give empty or LAN authids - fall back to name
	if(szAuth[0] && !equal(szAuth, "") && containi(szAuth, "LAN") == -1)
	{
		copy(szKey, iLen, szAuth)
		return
	}

	get_user_name(id, szKey, iLen)
	strtolower(szKey)
}

wipe_save_file()
{
	new fp = fopen(g_szSavePath, "w")
	if(fp)
		fclose(fp)
}

save_entry(const szKey[], iAmmo)
{
	new fp = fopen(g_szSavePath, "r")
	new szTemp[256]
	new bool:bFound = false
	new szOut[4096]
	new iOutPos = 0

	if(fp)
	{
		while(!feof(fp))
		{
			fgets(fp, szTemp, charsmax(szTemp))
			trim(szTemp)
			if(!szTemp[0])
				continue

			new szFileKey[64], szFileAmmo[16]
			parse(szTemp, szFileKey, charsmax(szFileKey), szFileAmmo, charsmax(szFileAmmo))

			if(equal(szFileKey, szKey))
			{
				bFound = true
				iOutPos += formatex(szOut[iOutPos], charsmax(szOut) - iOutPos, "%s %d^n", szFileKey, iAmmo)
			}
			else
			{
				iOutPos += formatex(szOut[iOutPos], charsmax(szOut) - iOutPos, "%s^n", szTemp)
			}
		}
		fclose(fp)
	}

	if(!bFound)
		iOutPos += formatex(szOut[iOutPos], charsmax(szOut) - iOutPos, "%s %d^n", szKey, iAmmo)

	fp = fopen(g_szSavePath, "w")
	if(fp)
	{
		fputs(fp, szOut)
		fclose(fp)
	}
}

load_entry(const szKey[])
{
	new fp = fopen(g_szSavePath, "r")
	if(!fp)
		return 0

	new szTemp[256]
	new iAmmo = 0

	while(!feof(fp))
	{
		fgets(fp, szTemp, charsmax(szTemp))
		trim(szTemp)
		if(!szTemp[0])
			continue

		new szFileKey[64], szFileAmmo[16]
		parse(szTemp, szFileKey, charsmax(szFileKey), szFileAmmo, charsmax(szFileAmmo))

		if(equal(szFileKey, szKey))
		{
			iAmmo = str_to_num(szFileAmmo)
			break
		}
	}

	fclose(fp)
	return iAmmo
}
