Skip to content

GetPlayerHwid

The player’s PC on this server - for bans a new name, address or reinstall does not get around.

Four parts of 16 hex digits joined by dashes, always in this order: system-board-disk-machine - the PC’s system id, its main board’s serial, the serial of the disk Windows runs from, and Windows’ own install id. A part the PC has no real value for is 0000000000000000. The same PC gives the same parts at every join to this server, whatever name the player types, whatever address they come from, after a reinstall of the game. Unlike GetPlayerUid it survives a wiped app-data folder, and a new Windows changes only the last part.

Every part is made with this server’s own key, so the parts of one PC on two servers have nothing in common, and the PC’s serials themselves never reach the server. A player who swaps their disk changes one part - so compare with CompareHwid and treat two or more shared parts as the same PC, rather than comparing the whole string.

It is there from OnPlayerConnect on. "" when their game sent none (a join without the launcher, an older game) - a strict server turns such players away. Their game’s word: a modified game can send other parts, so this makes ban evasion hard, not impossible.

GetPlayerHwid(pid)
Parameter Type
pid number the player

string - system-board-disk-machine, 67 characters; "" when none

-- bans that follow the PC: loaded once, checked at every join
local BANS = {}
function OnGameModeInit()
db = GetDatabase()
db:ExecuteSync("CREATE TABLE IF NOT EXISTS bans (name VARCHAR(24), hwid CHAR(67), reason VARCHAR(200))")
for _, row in ipairs(db:QuerySync("SELECT hwid, reason FROM bans") or {}) do BANS[#BANS + 1] = row end
end
function OnPlayerConnect(pid)
local hwid = GetPlayerHwid(pid)
if hwid == "" then Kick(pid, "Join through the launcher.") return end
for _, ban in ipairs(BANS) do
if CompareHwid(hwid, ban.hwid) >= 2 then Kick(pid, "Banned: " .. ban.reason) return end
end
end
function BanPc(pid, reason)
local ban = { hwid = GetPlayerHwid(pid), reason = reason }
BANS[#BANS + 1] = ban
db:Execute("INSERT INTO bans (name, hwid, reason) VALUES (@n, @h, @r)", { n = GetPlayerName(pid), h = ban.hwid, r = reason })
for _, other in ipairs(GetPlayersByHwid(ban.hwid)) do Kick(other, "Banned: " .. reason) end -- their other names too
end

GetPlayerHardware · CompareHwid · GetPlayersByHwid · GetPlayerUid · Kick · the Players group of the index