Creates login plugin for TGUI to streamline and unify login frontend and backend

This commit is contained in:
mochi
2020-09-19 16:48:48 +02:00
parent 9a50149fa2
commit f30dffc6b7
8 changed files with 245 additions and 79 deletions
+13 -56
View File
@@ -14,9 +14,6 @@
icon_screen = "medcomp"
req_one_access = list(ACCESS_MEDICAL, ACCESS_FORENSICS_LOCKERS)
circuit = /obj/item/circuitboard/med_data
var/obj/item/card/id/scan = null
var/authenticated = null
var/rank = null
var/screen = null
var/datum/data/record/active1 = null
var/datum/data/record/active2 = null
@@ -65,11 +62,7 @@
return ..()
/obj/machinery/computer/med_data/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/card/id) && !scan)
usr.drop_item()
O.forceMove(src)
scan = O
tgui_interact(user)
if(tgui_login_attackby(O, user))
return
return ..()
@@ -92,14 +85,10 @@
/obj/machinery/computer/med_data/tgui_data(mob/user)
var/data[0]
data["temp"] = temp
data["scan"] = scan ? scan.name : null
data["authenticated"] = authenticated
data["rank"] = rank
data["screen"] = screen
data["printing"] = printing
data["isAI"] = isAI(user)
data["isRobot"] = isrobot(user)
if(authenticated)
tgui_login_data(data, user)
if(data["loginState"]["logged_in"])
switch(screen)
if(MED_DATA_R_LIST)
if(!isnull(GLOB.data_core.general))
@@ -199,58 +188,21 @@
. = TRUE
if(tgui_act_modal(action, params))
return
if(tgui_login_act(action, params))
return
switch(action)
if("cleartemp")
temp = null
if("scan")
if(scan)
scan.forceMove(loc)
if(ishuman(usr) && !usr.get_active_hand())
usr.put_in_hands(scan)
scan = null
else
var/obj/item/I = usr.get_active_hand()
if(istype(I, /obj/item/card/id))
usr.drop_item()
I.forceMove(src)
scan = I
if("login")
var/login_type = text2num(params["login_type"])
if(login_type == LOGIN_TYPE_NORMAL && istype(scan))
if(check_access(scan))
authenticated = scan.registered_name
rank = scan.assignment
else if(login_type == LOGIN_TYPE_AI && isAI(usr))
authenticated = usr.name
rank = "AI"
else if(login_type == LOGIN_TYPE_ROBOT && isrobot(usr))
authenticated = usr.name
var/mob/living/silicon/robot/R = usr
rank = "[R.modtype] [R.braintype]"
if(authenticated)
active1 = null
active2 = null
screen = MED_DATA_R_LIST
else
. = FALSE
if(.)
return
if(authenticated)
if(tgui_login_get().logged_in)
. = TRUE
switch(action)
if("logout")
if(scan)
scan.forceMove(loc)
if(ishuman(usr) && !usr.get_active_hand())
usr.put_in_hands(scan)
scan = null
authenticated = null
screen = null
active1 = null
active2 = null
if("screen")
screen = clamp(text2num(params["screen"]) || 0, MED_DATA_R_LIST, MED_DATA_MEDBOT)
active1 = null
@@ -403,10 +355,11 @@
else if(istype(active1) && (field in active1.fields))
active1.fields[field] = answer
if("add_c")
if(!length(answer) || !istype(active2) || !length(authenticated))
var/datum/tgui_login/state = tgui_login_get()
if(!length(answer) || !istype(active2) || !length(state.name))
return
active2.fields["comments"] += list(list(
header = "Made by [authenticated] ([rank]) on [GLOB.current_date_string] [station_time_timestamp()]",
header = "Made by [state.name] ([state.name]) on [GLOB.current_date_string] [station_time_timestamp()]",
text = answer
))
else
@@ -493,6 +446,10 @@
..(severity)
/obj/machinery/computer/med_data/tgui_login_on_login(datum/tgui_login/state)
active1 = null
active2 = null
screen = MED_DATA_R_LIST
/obj/machinery/computer/med_data/laptop
name = "medical laptop"
+202
View File
@@ -0,0 +1,202 @@
/**
* tgui login
*
* Allows the handling of logins using IDs within tgui.
*
* Two key procs:
* * [/obj/proc/tgui_login_act] - Call in your tgui_act() proc to catch any login actions and handle them.
* * [/obj/proc/tgui_login_data] - Call in your tgui_data() proc to pass login info.
*
* How to use (DM side):
* 1. Call [/obj/proc/tgui_login_act] at the start of your tgui_act() proc
* 2. Call [/obj/proc/tgui_login_data] in your tgui_data() proc while passing the data list
* 3. In your object, call [/obj/proc/tgui_login_get] to get the current login state.
* 4. Optional: call [/obj/proc/tgui_login_attackby] in your attackby() to make the login process easier.
*
* How to use (JS side): Use the <LoginScreen /> and <LoginInfo /> interfaces.
*/
GLOBAL_LIST(tgui_logins)
/**
* Call this from a proc that is called in tgui_act() to process login actions
*
* Arguments:
* * action - The called action
* * params - The params to the action
*/
/obj/proc/tgui_login_act(action = "", params)
. = null
switch(action)
if("login_insert")
var/datum/tgui_login/state = tgui_login_get()
if(state.id) // An ID is already inserted, eject it
return tgui_login_eject(state = state)
else // No ID, attempt to insert one in
return tgui_login_insert(usr.get_active_hand(), state = state)
if("login_eject")
return tgui_login_eject()
if("login_login")
return tgui_login_login(text2num(params["login_type"]))
if("login_logout")
return tgui_login_logout()
/**
* Adds login state data.
*
* Arguments:
* * data - The data list to be returned
* * user - The user calling tgui_data()
* * state - The current login state
*/
/obj/proc/tgui_login_data(list/data, mob/user, datum/tgui_login/state = tgui_login_get())
data["loginState"] = list(
"id" = state.id ? state.id.name : null,
"name" = state.name,
"rank" = state.rank,
"logged_in" = state.logged_in,
)
data["isAI"] = isAI(user)
data["isRobot"] = isrobot(user)
/**
* Convenience function to perform login actions when
* the source object is hit by specific items.
*
* Arguments:
* * O - The object
* * user - The user
*/
/obj/proc/tgui_login_attackby(obj/item/O, mob/user)
if(istype(O, /obj/item/card/id) && tgui_login_insert(O))
tgui_interact(user)
return TRUE
/**
* Attempts to insert an object as an ID.
*
* Arguments:
* * O - The object to try inserting
* * state - The current login state
*/
/obj/proc/tgui_login_insert(obj/item/O, datum/tgui_login/state = tgui_login_get())
if(state.id)
return
if(istype(O, /obj/item/card/id))
// Move the ID inside
usr.drop_item()
O.forceMove(src)
// Update the state
state.id = O
return TRUE
/**
* Attempts to eject the inserted ID.
*
* Arguments:
* * state - The current login state
*/
/obj/proc/tgui_login_eject(datum/tgui_login/state = tgui_login_get())
if(!state.id)
return
// Drop the ID
state.id.forceMove(loc)
if(ishuman(usr) && !usr.get_active_hand())
usr.put_in_hands(state.id)
// Update the state
state.id = null
return TRUE
/**
* Attempts to log in with the given login type.
*
* Arguments:
* * login_type - The login type: LOGIN_TYPE_NORMAL (checks for inserted ID), LOGIN_TYPE_AI and LOGIN_TYPE_ROBOT
* * state - The current login state
*/
/obj/proc/tgui_login_login(login_type = LOGIN_TYPE_NORMAL, datum/tgui_login/state = tgui_login_get())
if(!state.id || state.logged_in)
return
if(login_type == LOGIN_TYPE_NORMAL)
if(check_access(state.id))
state.name = state.id.registered_name
state.rank = state.id.assignment
else if(login_type == LOGIN_TYPE_AI && isAI(usr))
state.name = usr.name
state.rank = "AI"
else if(login_type == LOGIN_TYPE_ROBOT && isrobot(usr))
var/mob/living/silicon/robot/R = usr
state.name = usr.name
state.rank = "[R.modtype] [R.braintype]"
state.logged_in = TRUE
tgui_login_on_login(state = state)
return TRUE
/**
* Attempts to log out.
*
* Arguments:
* * state - The current login state
*/
/obj/proc/tgui_login_logout(datum/tgui_login/state = tgui_login_get())
if(!state.logged_in)
return
state.name = state.rank = ""
state.logged_in = FALSE
tgui_login_on_logout(state = state)
return TRUE
/**
* Returns (or creates) the login state for the source object.
*
* Arguments:
* * state - The current login state
*/
/obj/proc/tgui_login_get()
. = LAZYACCESS(GLOB.tgui_logins, UID())
if(!.)
LAZYINITLIST(GLOB.tgui_logins)
. = GLOB.tgui_logins[UID()] = new /datum/tgui_login
/**
* Called on successful login.
*
* Arguments:
* * state - The current login state
*/
/obj/proc/tgui_login_on_login(datum/tgui_login/state = tgui_login_get())
return
/**
* Called on successful logout.
*
* Arguments:
* * state - The current login state
*/
/obj/proc/tgui_login_on_logout(datum/tgui_login/state = tgui_login_get())
return
/**
* Login state (there should be only one for one datum)
*/
/datum/tgui_login
var/obj/item/card/id/id = null
var/name = ""
var/rank = ""
var/logged_in = FALSE
/datum/tgui_login/New(id, name, rank)
src.id = id
src.name = name
src.rank = rank