Skip to content

Commit 50f4bee

Browse files
[ADMIN] Allows saving of JSON datums server side (ParadiseSS13#21860)
* Allows saving of JSON datums server side * derp * I am so livid I am webediting this * my god I have fallen off
1 parent fc7176b commit 50f4bee

File tree

7 files changed

+207
-4
lines changed

7 files changed

+207
-4
lines changed

SQL/paradise_schema.sql

+16
Original file line numberDiff line numberDiff line change
@@ -606,3 +606,19 @@ CREATE TABLE `tickets` (
606606
CONSTRAINT `all_responses` CHECK (json_valid(`all_responses`)),
607607
CONSTRAINT `awho` CHECK (json_valid(`awho`))
608608
) COLLATE='utf8mb4_general_ci' ENGINE=InnoDB;
609+
610+
--
611+
-- Table structure for table `json_datum_saves`
612+
--
613+
DROP TABLE IF EXISTS `json_datum_saves`;
614+
CREATE TABLE `json_datum_saves` (
615+
`id` INT(11) NOT NULL AUTO_INCREMENT,
616+
`ckey` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
617+
`slotname` VARCHAR(32) NOT NULL COLLATE 'utf8mb4_general_ci',
618+
`slotjson` LONGTEXT NOT NULL COLLATE 'utf8mb4_general_ci',
619+
`created` DATETIME NOT NULL DEFAULT current_timestamp(),
620+
`updated` DATETIME NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
621+
PRIMARY KEY (`id`) USING BTREE,
622+
UNIQUE INDEX `ckey_unique` (`ckey`, `slotname`) USING BTREE,
623+
INDEX `ckey` (`ckey`) USING BTREE
624+
) COLLATE = 'utf8mb4_general_ci' ENGINE = InnoDB;

SQL/updates/49-50.sql

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Updating SQL from 49 to 50 -AffectedArc07
2+
# Add new JSON datum saves table
3+
CREATE TABLE `json_datum_saves` (
4+
`id` INT(11) NOT NULL AUTO_INCREMENT,
5+
`ckey` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
6+
`slotname` VARCHAR(32) NOT NULL COLLATE 'utf8mb4_general_ci',
7+
`slotjson` LONGTEXT NOT NULL COLLATE 'utf8mb4_general_ci',
8+
`created` DATETIME NOT NULL DEFAULT current_timestamp(),
9+
`updated` DATETIME NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
10+
PRIMARY KEY (`id`) USING BTREE,
11+
UNIQUE INDEX `ckey_unique` (`ckey`, `slotname`) USING BTREE,
12+
INDEX `ckey` (`ckey`) USING BTREE
13+
) COLLATE = 'utf8mb4_general_ci' ENGINE = InnoDB;

code/__DEFINES/misc_defines.dm

+1-1
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@
375375
#define INVESTIGATE_BOMB "bombs"
376376

377377
// The SQL version required by this version of the code
378-
#define SQL_VERSION 49
378+
#define SQL_VERSION 50
379379

380380
// Vending machine stuff
381381
#define CAT_NORMAL 1

code/modules/admin/admin_verbs.dm

+2-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ GLOBAL_LIST_INIT(admin_verbs_spawn, list(
117117
/datum/admins/proc/spawn_atom, /*allows us to spawn instances*/
118118
/client/proc/respawn_character,
119119
/client/proc/admin_deserialize,
120-
/client/proc/create_crate
120+
/client/proc/create_crate,
121+
/client/proc/json_spawn_menu
121122
))
122123
GLOBAL_LIST_INIT(admin_verbs_server, list(
123124
/client/proc/reload_admins,

code/modules/admin/topic.dm

+67
Original file line numberDiff line numberDiff line change
@@ -3360,6 +3360,73 @@
33603360
var/mob/about_to_be_banned = locateUID(href_list["adminalert"])
33613361
usr.client.cmd_admin_alert_message(about_to_be_banned)
33623362

3363+
else if(href_list["spawnjsondatum"])
3364+
// Get the name and JSON to spawn
3365+
var/datum/db_query/dbq = SSdbcore.NewQuery("SELECT slotname, slotjson FROM json_datum_saves WHERE ckey=:ckey AND id=:id", list(
3366+
"ckey" = usr.ckey,
3367+
"id" = href_list["spawnjsondatum"]
3368+
))
3369+
if(!dbq.warn_execute())
3370+
qdel(dbq)
3371+
return
3372+
3373+
var/slot_name = null
3374+
var/slot_json = null
3375+
3376+
// Read it
3377+
while(dbq.NextRow())
3378+
slot_name = dbq.item[1]
3379+
slot_json = dbq.item[2]
3380+
3381+
qdel(dbq)
3382+
3383+
// Double check
3384+
var/spawn_choice = alert(usr, "Are you sure you wish to spawn '[slot_name]' at your current location?", "Warning", "Yes", "No")
3385+
if(spawn_choice != "Yes")
3386+
return
3387+
3388+
// Log this for gods sake
3389+
message_admins("[key_name_admin(usr)] spawned an atom from a JSON DB save.")
3390+
log_admin("[key_name(usr)] spawned an atom from a JSON DB save, JSON Text: [slot_json]")
3391+
json_to_object(slot_json, get_turf(usr))
3392+
3393+
else if(href_list["deletejsondatum"])
3394+
// Get the name
3395+
var/datum/db_query/dbq = SSdbcore.NewQuery("SELECT slotname FROM json_datum_saves WHERE ckey=:ckey AND id=:id", list(
3396+
"ckey" = usr.ckey,
3397+
"id" = href_list["deletejsondatum"]
3398+
))
3399+
if(!dbq.warn_execute())
3400+
qdel(dbq)
3401+
return
3402+
3403+
var/slot_name = null
3404+
3405+
// Read it
3406+
while(dbq.NextRow())
3407+
slot_name = dbq.item[1]
3408+
3409+
qdel(dbq)
3410+
3411+
// Double check
3412+
var/delete_choice = alert(usr, "Are you sure you wish to delete '[slot_name]'? This cannot be undone!", "Warning", "Yes", "No")
3413+
if(delete_choice != "Yes")
3414+
return
3415+
3416+
var/datum/db_query/dbq2 = SSdbcore.NewQuery("DELETE FROM json_datum_saves WHERE ckey=:ckey AND id=:id", list(
3417+
"ckey" = usr.ckey,
3418+
"id" = href_list["deletejsondatum"]
3419+
))
3420+
3421+
if(!dbq2.warn_execute())
3422+
qdel(dbq2)
3423+
return
3424+
3425+
qdel(dbq2)
3426+
owner.json_spawn_menu() // Refresh their menu
3427+
to_chat(usr, "Slot <code>[slot_name]</code> deleted.")
3428+
3429+
33633430
/client/proc/create_eventmob_for(mob/living/carbon/human/H, killthem = 0)
33643431
if(!check_rights(R_EVENT))
33653432
return

code/modules/admin/verbs/serialization.dm

+107-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,75 @@
1111
return
1212

1313
var/atom/movable/AM = holder.marked_datum
14-
to_chat(src, json_encode(AM.serialize()))
14+
15+
var/json_data = json_encode(AM.serialize())
16+
17+
var/choice = alert(usr, "Would you like to store this on your PC or server side?", "Storage Location", "PC", "Server", "Cancel")
18+
if(!choice || choice == "Cancel")
19+
return
20+
21+
if(choice == "PC")
22+
to_chat(src, json_data)
23+
24+
if(choice == "Server")
25+
// Right, get their slot names
26+
var/list/slots = list("--NEW--")
27+
var/datum/db_query/dbq = SSdbcore.NewQuery("SELECT slotname FROM json_datum_saves WHERE ckey=:ckey", list("ckey" = usr.ckey))
28+
if(!dbq.warn_execute())
29+
qdel(dbq)
30+
return
31+
32+
while(dbq.NextRow())
33+
slots += dbq.item[1]
34+
35+
qdel(dbq)
36+
37+
var/slot_choice = input(usr, "Select a slot to update, or create a new one.", "Slot Selection") as null|anything in slots
38+
39+
if(!slot_choice)
40+
return
41+
42+
if(slot_choice == "--NEW--")
43+
// New slot, save to DB
44+
var/chosen_slot_name = input(usr, "Name your slot", "Slot name") as null|text
45+
if(!chosen_slot_name || length(chosen_slot_name) == 0)
46+
return
47+
48+
// Sanitize the name
49+
var/clean_name = sanitize(copytext(chosen_slot_name, 1, 32)) // 32 chars is your max
50+
51+
// And save
52+
var/datum/db_query/dbq2 = SSdbcore.NewQuery("INSERT INTO json_datum_saves (ckey, slotname, slotjson) VALUES(:ckey, :slotname, :slotjson)", list(
53+
"ckey" = usr.ckey,
54+
"slotname" = clean_name,
55+
"slotjson" = json_data
56+
))
57+
if(!dbq2.warn_execute())
58+
qdel(dbq2)
59+
return
60+
61+
qdel(dbq2)
62+
to_chat(usr, "Successfully saved <code>[clean_name]</code>. You can spawn it from <code>Debug > Spawn Saved JSON Datum</code>.")
63+
64+
else
65+
// Existing slot, warn first
66+
var/confirmation = alert(usr, "Are you sure you want to update '[slot_choice]'? This cannot be undone!", "You sure?", "Yes", "No")
67+
if(confirmation != "Yes")
68+
return
69+
70+
// Now update
71+
var/datum/db_query/dbq2 = SSdbcore.NewQuery("UPDATE json_datum_saves SET slotjson=:slotjson WHERE slotname=:slotname AND ckey=:ckey", list(
72+
"slotjson" = json_data,
73+
"ckey" = usr.ckey,
74+
"slotname" = slot_choice
75+
))
76+
if(!dbq2.warn_execute())
77+
qdel(dbq2)
78+
return
79+
80+
qdel(dbq2)
81+
to_chat(usr, "Successfully updated <code>[slot_choice]</code>. You can spawn it from <code>Debug > Spawn Saved JSON Datum</code>.")
82+
1583

1684
/client/proc/admin_deserialize()
1785
set name = "Deserialize JSON datum"
@@ -26,3 +94,41 @@
2694
json_to_object(json_text, get_turf(usr))
2795
message_admins("[key_name_admin(usr)] spawned an atom from a custom JSON object.")
2896
log_admin("[key_name(usr)] spawned an atom from a custom JSON object, JSON Text: [json_text]")
97+
98+
99+
/client/proc/json_spawn_menu()
100+
set name = "Spawn Saved JSON Datum"
101+
set desc = "Spawns a JSON datums saved server side"
102+
set category = "Debug"
103+
104+
// This needs a holder to function
105+
if(!check_rights(R_SPAWN) || !holder)
106+
return
107+
108+
// Right, get their slot names
109+
var/list/slots = list()
110+
var/datum/db_query/dbq = SSdbcore.NewQuery("SELECT slotname, id FROM json_datum_saves WHERE ckey=:ckey", list("ckey" = usr.ckey))
111+
if(!dbq.warn_execute())
112+
qdel(dbq)
113+
return
114+
115+
while(dbq.NextRow())
116+
slots[dbq.item[1]] += dbq.item[2]
117+
qdel(dbq)
118+
119+
120+
var/datum/browser/popup = new(usr, "jsonspawnmenu", "JSON Spawn Menu", 400, 300)
121+
122+
// Cache this to reduce proc jumps
123+
var/holder_uid = holder.UID()
124+
125+
var/list/rows = list()
126+
rows += "<table><tr><th scope='col' width='90%'>Slot</th><th scope='col' width='10%'>Actions</th></tr>"
127+
for(var/slotname in slots)
128+
rows += "<tr><td>[slotname]</td><td><a href='?src=[holder_uid];spawnjsondatum=[slots[slotname]]'>Spawn</a>&nbsp;&nbsp;<a href='?src=[holder_uid];deletejsondatum=[slots[slotname]]'>Delete</a></td></tr>"
129+
130+
rows += "</table>"
131+
132+
popup.set_content(rows.Join(""))
133+
popup.open(FALSE)
134+

config/example/config.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ ipc_screens = [
144144
# Enable/disable the database on a whole
145145
sql_enabled = false
146146
# SQL version. If this is a mismatch, round start will be delayed
147-
sql_version = 49
147+
sql_version = 50
148148
# SQL server address. Can be an IP or DNS name
149149
sql_address = "127.0.0.1"
150150
# SQL server port

0 commit comments

Comments
 (0)