Moves pAI saves to the DB

This commit is contained in:
AffectedArc07
2021-10-04 19:15:53 +01:00
parent 2aa0abde72
commit c358a20498
12 changed files with 273 additions and 114 deletions
@@ -1,60 +1,65 @@
/*
name
key
description
role
comments
ready = 0
*/
/datum/pai_save
/// Client that owns the pAI
var/client/owner
/// pAI's name
var/pai_name
/// pAI's description
var/description
/// pAI's role
var/role
/// pAI's OOC comments
var/ooc_comments
/datum/paiCandidate/proc/savefile_path(mob/user)
return "data/player_saves/[copytext(user.ckey, 1, 2)]/[user.ckey]/pai.sav"
/datum/pai_save/New(client/C)
..()
owner = C
/datum/paiCandidate/proc/savefile_save(mob/user)
if(IsGuestKey(user.key))
return 0
/datum/pai_save/Destroy(force, ...)
owner = null
GLOB.paiController.pai_candidates -= src
return ..()
var/savefile/F = new /savefile(src.savefile_path(user))
// This proc seems useless but its used by client data loading
/datum/pai_save/proc/get_query()
var/datum/db_query/query = SSdbcore.NewQuery("SELECT pai_name, description, preferred_role, ooc_comments FROM pai_saves WHERE ckey=:ckey", list(
"ckey" = owner.ckey
))
return query
// Loads our data up
/datum/pai_save/proc/load_data(datum/db_query/Q)
while(Q.NextRow())
pai_name = Q.item[1]
description = Q.item[2]
role = Q.item[3]
ooc_comments = Q.item[4]
F["name"] << src.name
F["description"] << src.description
F["role"] << src.role
F["comments"] << src.comments
// Reload save from DB if the user edits it
/datum/pai_save/proc/reload_save()
var/datum/db_query/Q = get_query()
if(!Q.warn_execute())
qdel(Q)
return
load_data(Q)
qdel(Q)
F["version"] << 1
// Save their save to the DB
/datum/pai_save/proc/save_to_db()
var/datum/db_query/query = SSdbcore.NewQuery({"
INSERT INTO pai_saves (ckey, pai_name, description, preferred_role, ooc_comments)
VALUES (:ckey, :pai_name, :description, :preferred_role, :ooc_comments)
ON DUPLICATE KEY UPDATE pai_name=:pai_name2, description=:description2, preferred_role=:preferred_role2, ooc_comments=:ooc_comments2
"}, list(
"ckey" = owner.ckey,
"pai_name" = pai_name,
"description" = description,
"preferred_role" = role,
"ooc_comments" = ooc_comments,
"pai_name2" = pai_name,
"description2" = description,
"preferred_role2" = role,
"ooc_comments2" = ooc_comments
))
return 1
// loads the savefile corresponding to the mob's ckey
// if silent=true, report incompatible savefiles
// returns 1 if loaded (or file was incompatible)
// returns 0 if savefile did not exist
/datum/paiCandidate/proc/savefile_load(mob/user, silent = 1)
if(IsGuestKey(user.key))
return 0
var/path = savefile_path(user)
if(!fexists(path))
return 0
var/savefile/F = new /savefile(path)
if(!F) return //Not everyone has a pai savefile.
var/version = null
F["version"] >> version
if(isnull(version) || version != 1)
fdel(path)
if(!silent)
alert(user, "Your savefile was incompatible with this version and was deleted.")
return 0
F["name"] >> src.name
F["description"] >> src.description
F["role"] >> src.role
F["comments"] >> src.comments
return 1
query.warn_execute()
qdel(query)
+36 -55
View File
@@ -2,14 +2,6 @@
GLOBAL_DATUM_INIT(paiController, /datum/paiController, new) // Global handler for pAI candidates
/datum/paiCandidate
var/name
var/key
var/description
var/role
var/comments
var/ready = 0
/datum/paiController
var/list/pai_candidates = list()
var/list/asked = list()
@@ -18,7 +10,7 @@ GLOBAL_DATUM_INIT(paiController, /datum/paiController, new) // Global handler fo
/datum/paiController/Topic(href, href_list[])
var/datum/paiCandidate/candidate = locateUID(href_list["candidate"])
var/datum/pai_save/candidate = locateUID(href_list["candidate"])
if(candidate)
if(!istype(candidate))
@@ -32,14 +24,14 @@ GLOBAL_DATUM_INIT(paiController, /datum/paiController, new) // Global handler fo
return
if(usr.incapacitated() || isobserver(usr) || !card.Adjacent(usr))
return
if(istype(card, /obj/item/paicard) && istype(candidate, /datum/paiCandidate))
if(istype(card, /obj/item/paicard) && istype(candidate, /datum/pai_save))
var/mob/living/silicon/pai/pai = new(card)
if(!candidate.name)
if(!candidate.pai_name)
pai.name = pick(GLOB.ninja_names)
else
pai.name = candidate.name
pai.name = candidate.pai_name
pai.real_name = pai.name
pai.key = candidate.key
pai.key = candidate.owner.ckey
card.setPersonality(pai)
card.looking_for_personality = 0
@@ -64,7 +56,7 @@ GLOBAL_DATUM_INIT(paiController, /datum/paiController, new) // Global handler fo
return
if(candidate)
if(candidate.key && usr.key && candidate.key != usr.key)
if(candidate.owner.ckey && usr.ckey && candidate.owner.ckey != usr.ckey)
message_admins("Warning: possible href exploit by [key_name_admin(usr)] (paiController/Topic, candidate and usr have different keys)")
log_debug("Warning: possible href exploit by [key_name(usr)] (paiController/Topic, candidate and usr have different keys)")
return
@@ -75,9 +67,9 @@ GLOBAL_DATUM_INIT(paiController, /datum/paiController, new) // Global handler fo
switch(option)
if("name")
t = input("Enter a name for your pAI", "pAI Name", candidate.name) as text
t = input("Enter a name for your pAI", "pAI Name", candidate.pai_name) as text
if(t)
candidate.name = sanitize(copytext(t,1,MAX_NAME_LEN))
candidate.pai_name = sanitize(copytext(t,1,MAX_NAME_LEN))
if("desc")
t = input("Enter a description for your pAI", "pAI Description", candidate.description) as message
if(t)
@@ -87,26 +79,26 @@ GLOBAL_DATUM_INIT(paiController, /datum/paiController, new) // Global handler fo
if(t)
candidate.role = sanitize(copytext(t,1,MAX_MESSAGE_LEN))
if("ooc")
t = input("Enter any OOC comments", "pAI OOC Comments", candidate.comments) as message
t = input("Enter any OOC comments", "pAI OOC Comments", candidate.ooc_comments) as message
if(t)
candidate.comments = sanitize(copytext(t,1,MAX_MESSAGE_LEN))
candidate.ooc_comments = sanitize(copytext(t,1,MAX_MESSAGE_LEN))
if("save")
candidate.savefile_save(usr)
if("load")
candidate.savefile_load(usr)
candidate.save_to_db(usr)
if("reload")
candidate.reload_save(usr)
//In case people have saved unsanitized stuff.
if(candidate.name)
candidate.name = sanitize(copytext(candidate.name,1,MAX_NAME_LEN))
if(candidate.pai_name)
candidate.pai_name = sanitize(copytext(candidate.pai_name, 1, MAX_NAME_LEN))
if(candidate.description)
candidate.description = sanitize(copytext(candidate.description,1,MAX_MESSAGE_LEN))
candidate.description = sanitize(copytext(candidate.description, 1, MAX_MESSAGE_LEN))
if(candidate.role)
candidate.role = sanitize(copytext(candidate.role,1,MAX_MESSAGE_LEN))
if(candidate.comments)
candidate.comments = sanitize(copytext(candidate.comments,1,MAX_MESSAGE_LEN))
candidate.role = sanitize(copytext(candidate.role, 1, MAX_MESSAGE_LEN))
if(candidate.ooc_comments)
candidate.ooc_comments = sanitize(copytext(candidate.ooc_comments, 1, MAX_MESSAGE_LEN))
if("submit")
if(candidate)
candidate.ready = 1
GLOB.paiController.pai_candidates |= candidate
for(var/obj/item/paicard/p in world)
if(p.looking_for_personality == 1)
p.alertUpdate()
@@ -114,18 +106,8 @@ GLOBAL_DATUM_INIT(paiController, /datum/paiController, new) // Global handler fo
return
recruitWindow(usr)
/datum/paiController/proc/recruitWindow(mob/M as mob)
var/datum/paiCandidate/candidate
for(var/datum/paiCandidate/c in pai_candidates)
if(!istype(c) || !istype(M))
break
if(c.key == M.key)
candidate = c
if(!candidate)
candidate = new /datum/paiCandidate()
candidate.key = M.key
pai_candidates.Add(candidate)
/datum/paiController/proc/recruitWindow(mob/M)
var/datum/pai_save/candidate = M.client.pai_save
var/dat = ""
dat += {"
@@ -194,7 +176,7 @@ GLOBAL_DATUM_INIT(paiController, /datum/paiController, new) // Global handler fo
<table>
<tr class="d0">
<th rowspan="2"><a href='byond://?src=[UID()];option=name;new=1;candidate=[candidate.UID()]'>Name</a>:</th>
<td class="desc">[candidate.name]&nbsp;</td>
<td class="desc">[candidate.pai_name]&nbsp;</td>
</tr>
<tr class="d1">
<td>What you plan to call yourself. Suggestions: Any character name you would choose for a station character OR an AI.</td>
@@ -215,7 +197,7 @@ GLOBAL_DATUM_INIT(paiController, /datum/paiController, new) // Global handler fo
</tr>
<tr class="d0">
<th rowspan="2"><a href='byond://?src=[UID()];option=ooc;new=1;candidate=[candidate.UID()]'>OOC Comments</a>:</th>
<td class="desc">[candidate.comments]&nbsp;</td>
<td class="desc">[candidate.ooc_comments]&nbsp;</td>
</tr>
<tr class="d1">
<td>Anything you'd like to address specifically to the player reading this in an OOC manner. \"I prefer more serious RP.\", \"I'm still learning the interface!\", etc. Feel free to leave this blank if you want.</td>
@@ -230,7 +212,7 @@ GLOBAL_DATUM_INIT(paiController, /datum/paiController, new) // Global handler fo
</tr>
<tr>
<td class="button">
<a href='byond://?src=[UID()];option=load;new=1;candidate=[candidate.UID()]' class="button">Load Personality</a>
<a href='byond://?src=[UID()];option=reload;new=1;candidate=[candidate.UID()]' class="button">Reload Personality</a>
</td>
</tr>
</table><br>
@@ -246,14 +228,13 @@ GLOBAL_DATUM_INIT(paiController, /datum/paiController, new) // Global handler fo
/datum/paiController/proc/findPAI(obj/item/paicard/p, mob/user)
requestRecruits(p, user)
var/list/available = list()
for(var/datum/paiCandidate/c in GLOB.paiController.pai_candidates)
if(c.ready)
var/found = 0
for(var/mob/o in GLOB.respawnable_list)
if(o.key == c.key)
found = 1
if(found)
available.Add(c)
for(var/datum/pai_save/c in GLOB.paiController.pai_candidates)
var/found = 0
for(var/mob/o in GLOB.respawnable_list)
if(o.ckey == c.owner.ckey)
found = 1
if(found)
available.Add(c)
var/dat = ""
dat += {"
@@ -325,12 +306,12 @@ GLOBAL_DATUM_INIT(paiController, /datum/paiController, new) // Global handler fo
"}
dat += "<p>Displaying available AI personalities from central database... If there are no entries, or if a suitable entry is not listed, check again later as more personalities may be added.</p>"
for(var/datum/paiCandidate/c in available)
for(var/datum/pai_save/c in available)
dat += {"
<table class="desc">
<tr class="d0">
<th>Name:</th>
<td>[c.name]</td>
<td>[c.pai_name]</td>
</tr>
<tr class="d1">
<th>Description:</th>
@@ -342,11 +323,11 @@ GLOBAL_DATUM_INIT(paiController, /datum/paiController, new) // Global handler fo
</tr>
<tr class="d1">
<th>OOC Comments:</th>
<td>[c.comments]</td>
<td>[c.ooc_comments]</td>
</tr>
</table>
<table class="download">
<td class="download"><a href='byond://?src=[UID()];download=1;candidate=[c.UID()];device=\ref[p]' class="button"><b>Download [c.name]</b></a>
<td class="download"><a href='byond://?src=[UID()];download=1;candidate=[c.UID()];device=\ref[p]' class="button"><b>Download [c.pai_name]</b></a>
</td>
</table>
<br>