Players & Auth
Login flows, dialogs, admin flags and per-player state.
Knight does not force an authentication policy. A login flow is a pattern you build with callbacks, dialogs and the database.
A minimal login flow
knight
let DIALOG_LOGIN = 100;
let DIALOG_REGISTER = 101;
let loggedIn = {};
system::start() {
let db = sqlite_open("data/accounts.db");
sqlite_exec(db, "CREATE TABLE IF NOT EXISTS accounts (name TEXT PRIMARY KEY, hash TEXT)");
};
player::connect(int playerid) {
let db = sqlite_open("data/accounts.db");
let r = sqlite_query(db, "SELECT name FROM accounts WHERE name = ?", PlayerName(playerid));
if (r != null && cache_get_row_count(r) > 0) {
ShowPlayerDialog(playerid, DIALOG_LOGIN, 1, "Login", "Password:", "Login", "Cancel");
} else {
ShowPlayerDialog(playerid, DIALOG_REGISTER, 1, "Register", "Choose a password:", "Register", "Cancel");
}
};
dialog::response(int playerid, int id, bool accepted, string input, int listitem) {
if (id == DIALOG_REGISTER) {
if (!accepted) { KickPlayer(playerid, "cancelled"); return; }
let hash = hash_password(input);
let db = sqlite_open("data/accounts.db");
sqlite_exec(db, "INSERT INTO accounts VALUES (?, ?)", PlayerName(playerid), hash);
loggedIn[PlayerName(playerid)] = true;
SendClientMessage(playerid, "Registered.");
return;
}
if (id == DIALOG_LOGIN) {
let db = sqlite_open("data/accounts.db");
let r = sqlite_query(db, "SELECT hash FROM accounts WHERE name = ?", PlayerName(playerid));
if (r != null && cache_get_row_count(r) > 0
&& verify_password(input, cache_get_value_name(r, 0, "hash"))) {
loggedIn[PlayerName(playerid)] = true;
SendClientMessage(playerid, "Logged in.");
} else {
ShowPlayerDialog(playerid, DIALOG_LOGIN, 1, "Login", "Wrong password:", "Login", "Cancel");
}
}
};
Gating class and spawn
knight
player::request_class(int playerid, int classid) {
return loggedIn[PlayerName(playerid)] == true;
};
player::request_spawn(int playerid) {
return loggedIn[PlayerName(playerid)] == true;
};
Warning
Returning
false from request_class blocks selection; request_spawn returning false tells the client the spawn was denied.Player state and getters
knight
SetPlayerHealth(playerid, 100.0);
SetPlayerArmour(playerid, 50.0);
GivePlayerMoney(playerid, 500);
SetPlayerScore(playerid, 10);
SetPlayerInterior(playerid, 0);
SetPlayerVirtualWorld(playerid, 0);
let hp = GetPlayerHealth(playerid);
let money = GetPlayerMoney(playerid);
let team = GetPlayerTeam(playerid);
let pos = GetPlayerPos(playerid);
Admin flags
knight
SetPlayerAdmin(playerid, true);
if (IsPlayerAdmin(playerid)) {
SendClientMessage(playerid, "You are an admin.");
}