Untitled

Anonymous
plain_text
05/22/2026 5:03 PM
6.3 KB
8
Indexable
if not configManager.getBoolean(configKeys.CLEAN_DATABASE) then
	return
end

local config = {
	deleteAccountWithNoPlayers = true,
	printResult = true,
	saveResultToFile = true,
	logFileName = "cleanplayers.txt",
}

local cleanup = {
	{ level = 8,   time = 30  * 24 * 60 * 60 },
	{ level = 50,  time = 90  * 24 * 60 * 60 },
	{ level = 100, time = 180 * 24 * 60 * 60 },
	{ level = 200, time = 360 * 24 * 60 * 60 },
	{ level = 300, time = 720 * 24 * 60 * 60 },
	{ level = 400, time = 1095 * 24 * 60 * 60 },
	{ level = 500, time = 1460 * 24 * 60 * 60 },
}

-- ─── helpers ─────────────────────────────────────────────────────────────────

local function queryCount(query)
	local result = db.storeQuery(query)
	if not result then
		return 0
	end
	local n = Result.getNumber(result, "count")
	Result.free(result)
	return n
end

local function getPlayerCount()
	return queryCount("SELECT COUNT(`id`) AS `count` FROM `players`;")
end

local function getAccountCount()
	return queryCount("SELECT COUNT(`id`) AS `count` FROM `accounts`;")
end

-- ─── startup event ────────────────────────────────────────────────────────────

local playerCleaner = GlobalEvent("PlayerCleaner")
playerCleaner:type("startup")

function playerCleaner.onStartup()
	local beforePlayers  = getPlayerCount()
	local beforeAccounts = getAccountCount()

	local ignoredNames = {
		"Rook Sample",
		"Sorcerer Sample",
		"Druid Sample",
		"Paladin Sample",
		"Knight Sample",
		"Monk Sample",
		"GOD",
	}

	local escapedNames = {}
	for i, name in ipairs(ignoredNames) do
		escapedNames[i] = db.escapeString(name)
	end
	local ignoredList = table.concat(escapedNames, ",")

	local pids = {}

	for _, tier in ipairs(cleanup) do
		local query = string.format(
			"SELECT `id`, `account_id` FROM `players`" ..
			" WHERE `level` < %d" ..
			" AND `name` NOT IN(%s)" ..
			" AND `group_id` < 2" ..
			" AND `lastlogin` < UNIX_TIMESTAMP() - %d" ..
			" AND `lastlogin` > 0;",
			tier.level,
			ignoredList,
			tier.time
		)

		local result = db.storeQuery(query)
		if result then
			repeat
				local pid = Result.getNumber(result, "id")
				local aid = Result.getNumber(result, "account_id")
				pids[pid] = aid
			until not Result.next(result)
			Result.free(result)
		end
	end

	-- ── delete players ──────────────────────────────────────────────────────
	for pid, _ in pairs(pids) do
		db.query(string.format(
			"DELETE FROM `znote_players` WHERE `player_id` = %d;",
			tonumber(pid)
		))
		db.query(string.format(
			"DELETE FROM `players` WHERE `id` = %d;",
			tonumber(pid)
		))
	end

	-- ── delete empty accounts ─────────────────────────────────────────────────
	if config.deleteAccountWithNoPlayers then
		local aidsProcessed = {}

		for _, aid in pairs(pids) do
			if not aidsProcessed[aid] then
				aidsProcessed[aid] = true

				local cnt = queryCount(string.format(
					"SELECT COUNT(`id`) AS `count` FROM `players` WHERE `account_id` = %d;",
					tonumber(aid)
				))

				if cnt <= 0 then
					db.query(string.format(
						"DELETE FROM `znote_accounts` WHERE `account_id` = %d;",
						tonumber(aid)
					))
					db.query(string.format(
						"DELETE FROM `accounts` WHERE `id` = %d;",
						tonumber(aid)
					))
				end
			end
		end
	end

	-- ── report ───────────────────────────────────────────────────────────────
	local deletedPlayers  = beforePlayers  - getPlayerCount()
	local deletedAccounts = beforeAccounts - getAccountCount()

	if deletedPlayers > 0 or deletedAccounts > 0 then
		local text = string.format(
			">> [DBCLEANUP] %d inactive player(s)%s deleted from the database.",
			deletedPlayers,
			config.deleteAccountWithNoPlayers
				and (" and " .. deletedAccounts .. " empty account(s)")
				or ""
		)

		if config.printResult then
			print("")
			print(text)
			print("")
		end

		if config.saveResultToFile then
			local file = io.open("data/logs/" .. config.logFileName, "a")
			if file then
				file:write("[" .. os.date("%d %B %Y %X") .. "] " .. text .. "\n\n")
				file:close()
			end
		end
	end

	return true
end

playerCleaner:register()
Editor is loading...
Leave a Comment