mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 02:09:41 +00:00
Upgrades SDQL2 and refactors it to a datum
This commit is contained in:
@@ -5,5 +5,12 @@
|
|||||||
|
|
||||||
#define TICK_CHECK ( TICK_USAGE > Master.current_ticklimit )
|
#define TICK_CHECK ( TICK_USAGE > Master.current_ticklimit )
|
||||||
#define CHECK_TICK if TICK_CHECK stoplag()
|
#define CHECK_TICK if TICK_CHECK stoplag()
|
||||||
|
=======
|
||||||
#define TICK_USAGE world.tick_usage
|
#define TICK_USAGE world.tick_usage
|
||||||
|
|
||||||
|
#define TICK_CHECK ( TICK_USAGE > Master.current_ticklimit )
|
||||||
|
#define CHECK_TICK ( TICK_CHECK ? stoplag() : 0 )
|
||||||
|
>>>>>>> ae64d73... Upgrades SDQL2 and refactors it to a datum (#5793)
|
||||||
|
|
||||||
|
#define TICK_CHECK_HIGH_PRIORITY ( TICK_USAGE > 95 )
|
||||||
|
#define CHECK_TICK_HIGH_PRIORITY ( TICK_CHECK_HIGH_PRIORITY? stoplag() : 0 )
|
||||||
|
|||||||
@@ -1,6 +1,19 @@
|
|||||||
#define ALL (~0)
|
/*
|
||||||
|
These defines are specific to the atom/flags_1 bitmask
|
||||||
|
*/
|
||||||
|
#define ALL (~0) //For convenience.
|
||||||
#define NONE 0
|
#define NONE 0
|
||||||
|
|
||||||
|
//for convenience
|
||||||
|
#define ENABLE_BITFIELD(variable, flag) (variable |= (flag))
|
||||||
|
#define DISABLE_BITFIELD(variable, flag) (variable &= ~(flag))
|
||||||
|
#define CHECK_BITFIELD(variable, flag) (variable & flag)
|
||||||
|
|
||||||
|
//check if all bitflags specified are present
|
||||||
|
#define CHECK_MULTIPLE_BITFIELDS(flagvar, flags) ((flagvar & (flags)) == flags)
|
||||||
|
|
||||||
|
GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768))
|
||||||
|
|
||||||
// datum_flags
|
// datum_flags
|
||||||
#define DF_VAR_EDITED (1<<0)
|
#define DF_VAR_EDITED (1<<0)
|
||||||
#define DF_ISPROCESSING (1<<1)
|
#define DF_ISPROCESSING (1<<1)
|
||||||
|
|||||||
@@ -2,5 +2,7 @@ GLOBAL_LIST_EMPTY(admins) //all clients whom are admins
|
|||||||
GLOBAL_PROTECT(admins)
|
GLOBAL_PROTECT(admins)
|
||||||
GLOBAL_LIST_EMPTY(deadmins) //all ckeys who have used the de-admin verb.
|
GLOBAL_LIST_EMPTY(deadmins) //all ckeys who have used the de-admin verb.
|
||||||
GLOBAL_LIST_EMPTY(stealthminID)
|
GLOBAL_LIST_EMPTY(stealthminID)
|
||||||
|
<<<<<<< HEAD
|
||||||
GLOBAL_LIST_EMPTY(directory) //all ckeys with associated client
|
GLOBAL_LIST_EMPTY(directory) //all ckeys with associated client
|
||||||
GLOBAL_LIST_EMPTY(players_by_zlevel)
|
GLOBAL_LIST_EMPTY(clients)
|
||||||
|
GLOBAL_LIST_EMPTY(players_by_zlevel)
|
||||||
@@ -432,7 +432,7 @@ proc/isInSight(var/atom/A, var/atom/B)
|
|||||||
|
|
||||||
/proc/Show2Group4Delay(obj/O, list/group, delay=0)
|
/proc/Show2Group4Delay(obj/O, list/group, delay=0)
|
||||||
if(!isobj(O)) return
|
if(!isobj(O)) return
|
||||||
if(!group) group = clients
|
if(!group) group = GLOB.clients
|
||||||
for(var/client/C in group)
|
for(var/client/C in group)
|
||||||
C.screen += O
|
C.screen += O
|
||||||
if(delay)
|
if(delay)
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
var/list/clients = list() //list of all clients
|
|
||||||
var/list/admins = list() //list of all clients whom are admins
|
var/list/admins = list() //list of all clients whom are admins
|
||||||
var/list/directory = list() //list of all ckeys with associated client
|
|
||||||
|
|
||||||
//Since it didn't really belong in any other category, I'm putting this here
|
//Since it didn't really belong in any other category, I'm putting this here
|
||||||
//This is for procs to replace all the goddamn 'in world's that are chilling around the code
|
//This is for procs to replace all the goddamn 'in world's that are chilling around the code
|
||||||
|
|||||||
@@ -147,74 +147,31 @@ var/round_start_time = 0
|
|||||||
|
|
||||||
//Takes a value of time in deciseconds.
|
//Takes a value of time in deciseconds.
|
||||||
//Returns a text value of that number in hours, minutes, or seconds.
|
//Returns a text value of that number in hours, minutes, or seconds.
|
||||||
/proc/DisplayTimeText(time_value, truncate = FALSE)
|
/proc/DisplayTimeText(time_value, round_seconds_to = 0.1)
|
||||||
var/second = (time_value)*0.1
|
var/second = round(time_value * 0.1, round_seconds_to)
|
||||||
var/second_adjusted = null
|
|
||||||
var/second_rounded = FALSE
|
|
||||||
var/minute = null
|
|
||||||
var/hour = null
|
|
||||||
var/day = null
|
|
||||||
|
|
||||||
if(!second)
|
if(!second)
|
||||||
return "0 seconds"
|
return "right now"
|
||||||
if(second >= 60)
|
if(second < 60)
|
||||||
minute = FLOOR(second/60, 1)
|
return "[second] second[(second != 1)? "s":""]"
|
||||||
second = round(second - (minute*60), 0.1)
|
var/minute = FLOOR(second / 60, 1)
|
||||||
second_rounded = TRUE
|
second = MODULUS(second, 60)
|
||||||
if(second) //check if we still have seconds remaining to format, or if everything went into minute.
|
var/secondT
|
||||||
second_adjusted = round(second) //used to prevent '1 seconds' being shown
|
if(second)
|
||||||
if(day || hour || minute)
|
secondT = " and [second] second[(second != 1)? "s":""]"
|
||||||
if(second_adjusted == 1 && second >= 1)
|
if(minute < 60)
|
||||||
second = " and 1 second"
|
return "[minute] minute[(minute != 1)? "s":""][secondT]"
|
||||||
else if(second > 1)
|
var/hour = FLOOR(minute / 60, 1)
|
||||||
second = " and [second_adjusted] seconds"
|
minute = MODULUS(minute, 60)
|
||||||
else //shows a fraction if seconds is < 1
|
var/minuteT
|
||||||
if(second_rounded) //no sense rounding again if it's already done
|
if(minute)
|
||||||
second = " and [second] seconds"
|
minuteT = " and [minute] minute[(minute != 1)? "s":""]"
|
||||||
else
|
if(hour < 24)
|
||||||
second = " and [round(second, 0.1)] seconds"
|
return "[hour] hour[(hour != 1)? "s":""][minuteT][secondT]"
|
||||||
else
|
var/day = FLOOR(hour / 24, 1)
|
||||||
if(second_adjusted == 1 && second >= 1)
|
hour = MODULUS(hour, 24)
|
||||||
second = "[truncate ? "second" : "1 second"]"
|
var/hourT
|
||||||
else if(second > 1)
|
|
||||||
second = "[second_adjusted] seconds"
|
|
||||||
else
|
|
||||||
if(second_rounded)
|
|
||||||
second = "[second] seconds"
|
|
||||||
else
|
|
||||||
second = "[round(second, 0.1)] seconds"
|
|
||||||
else
|
|
||||||
second = null
|
|
||||||
|
|
||||||
if(!minute)
|
|
||||||
return "[second]"
|
|
||||||
if(minute >= 60)
|
|
||||||
hour = FLOOR(minute/60, 1)
|
|
||||||
minute = (minute - (hour*60))
|
|
||||||
if(minute) //alot simpler from here since you don't have to worry about fractions
|
|
||||||
if(minute != 1)
|
|
||||||
if((day || hour) && second)
|
|
||||||
minute = ", [minute] minutes"
|
|
||||||
else if((day || hour) && !second)
|
|
||||||
minute = " and [minute] minutes"
|
|
||||||
else
|
|
||||||
minute = "[minute] minutes"
|
|
||||||
else
|
|
||||||
if((day || hour) && second)
|
|
||||||
minute = ", 1 minute"
|
|
||||||
else if((day || hour) && !second)
|
|
||||||
minute = " and 1 minute"
|
|
||||||
else
|
|
||||||
minute = "[truncate ? "minute" : "1 minute"]"
|
|
||||||
else
|
|
||||||
minute = null
|
|
||||||
|
|
||||||
if(!hour)
|
|
||||||
return "[minute][second]"
|
|
||||||
if(hour >= 24)
|
|
||||||
day = FLOOR(hour/24, 1)
|
|
||||||
hour = (hour - (day*24))
|
|
||||||
if(hour)
|
if(hour)
|
||||||
|
<<<<<<< HEAD
|
||||||
if(hour != 1)
|
if(hour != 1)
|
||||||
if(day && (minute || second))
|
if(day && (minute || second))
|
||||||
hour = ", [hour] hours"
|
hour = ", [hour] hours"
|
||||||
@@ -240,3 +197,7 @@ var/round_start_time = 0
|
|||||||
day = "[truncate ? "day" : "1 day"]"
|
day = "[truncate ? "day" : "1 day"]"
|
||||||
|
|
||||||
return "[day][hour][minute][second]"
|
return "[day][hour][minute][second]"
|
||||||
|
=======
|
||||||
|
hourT = " and [hour] hour[(hour != 1)? "s":""]"
|
||||||
|
return "[day] day[(day != 1)? "s":""][hourT][minuteT][secondT]"
|
||||||
|
>>>>>>> ae64d73... Upgrades SDQL2 and refactors it to a datum (#5793)
|
||||||
|
|||||||
@@ -1461,3 +1461,5 @@ var/mob/dview/dview_mob = new
|
|||||||
|
|
||||||
/proc/pass()
|
/proc/pass()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
#define NAMEOF(datum, X) (#X || ##datum.##X)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
<<<<<<< HEAD
|
||||||
SUBSYSTEM_DEF(vote)
|
SUBSYSTEM_DEF(vote)
|
||||||
name = "Vote"
|
name = "Vote"
|
||||||
wait = 10
|
wait = 10
|
||||||
@@ -371,3 +372,378 @@ SUBSYSTEM_DEF(vote)
|
|||||||
|
|
||||||
if(SSvote)
|
if(SSvote)
|
||||||
src << browse(SSvote.interface(src), "window=vote;size=500x[300 + SSvote.choices.len * 25]")
|
src << browse(SSvote.interface(src), "window=vote;size=500x[300 + SSvote.choices.len * 25]")
|
||||||
|
=======
|
||||||
|
SUBSYSTEM_DEF(vote)
|
||||||
|
|
||||||
|
name = "Vote"
|
||||||
|
|
||||||
|
wait = 10
|
||||||
|
|
||||||
|
priority = FIRE_PRIORITY_VOTE
|
||||||
|
|
||||||
|
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||||
|
|
||||||
|
flags = SS_KEEP_TIMING | SS_NO_INIT
|
||||||
|
|
||||||
|
var/list/round_voters = list()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Current vote
|
||||||
|
|
||||||
|
var/initiator
|
||||||
|
|
||||||
|
var/started_time
|
||||||
|
|
||||||
|
var/time_remaining
|
||||||
|
|
||||||
|
var/duration
|
||||||
|
|
||||||
|
var/mode
|
||||||
|
|
||||||
|
var/question
|
||||||
|
|
||||||
|
var/list/choices = list()
|
||||||
|
|
||||||
|
var/list/gamemode_names = list()
|
||||||
|
|
||||||
|
var/list/voted = list()
|
||||||
|
|
||||||
|
var/list/current_votes = list()
|
||||||
|
|
||||||
|
var/list/additional_text = list()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/datum/controller/subsystem/vote/fire(resumed)
|
||||||
|
|
||||||
|
if(mode)
|
||||||
|
|
||||||
|
time_remaining = round((started_time + duration - world.time)/10)
|
||||||
|
|
||||||
|
if(mode == VOTE_GAMEMODE && ticker.current_state >= GAME_STATE_SETTING_UP)
|
||||||
|
|
||||||
|
to_chat(world, "<b>Gamemode vote aborted: Game has already started.</b>")
|
||||||
|
|
||||||
|
reset()
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
if(time_remaining <= 0)
|
||||||
|
|
||||||
|
result()
|
||||||
|
|
||||||
|
reset()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/datum/controller/subsystem/vote/proc/autotransfer()
|
||||||
|
|
||||||
|
initiate_vote(VOTE_CREW_TRANSFER, "the server", 1)
|
||||||
|
|
||||||
|
log_debug("The server has called a crew transfer vote.")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/datum/controller/subsystem/vote/proc/autogamemode()
|
||||||
|
|
||||||
|
initiate_vote(VOTE_GAMEMODE, "the server", 1)
|
||||||
|
|
||||||
|
log_debug("The server has called a gamemode vote.")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/datum/controller/subsystem/vote/proc/reset()
|
||||||
|
|
||||||
|
initiator = null
|
||||||
|
|
||||||
|
started_time = null
|
||||||
|
|
||||||
|
duration = null
|
||||||
|
|
||||||
|
time_remaining = null
|
||||||
|
|
||||||
|
mode = null
|
||||||
|
|
||||||
|
question = null
|
||||||
|
|
||||||
|
choices.Cut()
|
||||||
|
|
||||||
|
voted.Cut()
|
||||||
|
|
||||||
|
current_votes.Cut()
|
||||||
|
|
||||||
|
additional_text.Cut()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/datum/controller/subsystem/vote/proc/get_result() // Get the highest number of votes
|
||||||
|
|
||||||
|
var/greatest_votes = 0
|
||||||
|
|
||||||
|
var/total_votes = 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for(var/option in choices)
|
||||||
|
|
||||||
|
var/votes = choices[option]
|
||||||
|
|
||||||
|
total_votes += votes
|
||||||
|
|
||||||
|
if(votes > greatest_votes)
|
||||||
|
|
||||||
|
greatest_votes = votes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(!config.vote_no_default && choices.len) // Default-vote for everyone who didn't vote
|
||||||
|
|
||||||
|
var/non_voters = (GLOB.clients.len - total_votes)
|
||||||
|
|
||||||
|
if(non_voters > 0)
|
||||||
|
|
||||||
|
if(mode == VOTE_RESTART)
|
||||||
|
|
||||||
|
choices["Continue Playing"] += non_voters
|
||||||
|
|
||||||
|
if(choices["Continue Playing"] >= greatest_votes)
|
||||||
|
|
||||||
|
greatest_votes = choices["Continue Playing"]
|
||||||
|
|
||||||
|
else if(mode == VOTE_GAMEMODE)
|
||||||
|
|
||||||
|
if(master_mode in choices)
|
||||||
|
|
||||||
|
choices[master_mode] += non_voters
|
||||||
|
|
||||||
|
if(choices[master_mode] >= greatest_votes)
|
||||||
|
|
||||||
|
greatest_votes = choices[master_mode]
|
||||||
|
|
||||||
|
else if(mode == VOTE_CREW_TRANSFER)
|
||||||
|
|
||||||
|
var/factor = 0.5
|
||||||
|
|
||||||
|
switch(world.time / (10 * 60)) // minutes
|
||||||
|
|
||||||
|
if(0 to 60)
|
||||||
|
|
||||||
|
factor = 0.5
|
||||||
|
|
||||||
|
if(61 to 120)
|
||||||
|
|
||||||
|
factor = 0.8
|
||||||
|
|
||||||
|
if(121 to 240)
|
||||||
|
|
||||||
|
factor = 1
|
||||||
|
|
||||||
|
if(241 to 300)
|
||||||
|
|
||||||
|
factor = 1.2
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
factor = 1.4
|
||||||
|
|
||||||
|
choices["Initiate Crew Transfer"] = round(choices["Initiate Crew Transfer"] * factor)
|
||||||
|
|
||||||
|
world << "<font color='purple'>Crew Transfer Factor: [factor]</font>"
|
||||||
|
|
||||||
|
greatest_votes = max(choices["Initiate Crew Transfer"], choices["Continue The Round"])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
. = list() // Get all options with that many votes and return them in a list
|
||||||
|
|
||||||
|
if(greatest_votes)
|
||||||
|
|
||||||
|
for(var/option in choices)
|
||||||
|
|
||||||
|
if(choices[option] == greatest_votes)
|
||||||
|
|
||||||
|
. += option
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/datum/controller/subsystem/vote/proc/announce_result()
|
||||||
|
|
||||||
|
var/list/winners = get_result()
|
||||||
|
|
||||||
|
var/text
|
||||||
|
|
||||||
|
if(winners.len > 0)
|
||||||
|
|
||||||
|
if(winners.len > 1)
|
||||||
|
|
||||||
|
if(mode != VOTE_GAMEMODE || ticker.hide_mode == 0) // Here we are making sure we don't announce potential game modes
|
||||||
|
|
||||||
|
text = "<b>Vote Tied Between:</b>\n"
|
||||||
|
|
||||||
|
for(var/option in winners)
|
||||||
|
|
||||||
|
text += "\t[option]\n"
|
||||||
|
|
||||||
|
. = pick(winners)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for(var/key in current_votes)
|
||||||
|
|
||||||
|
if(choices[current_votes[key]] == .)
|
||||||
|
|
||||||
|
round_voters += key // Keep track of who voted for the winning round.
|
||||||
|
|
||||||
|
if(mode != VOTE_GAMEMODE || . == "Extended" || ticker.hide_mode == 0) // Announce Extended gamemode, but not other gamemodes
|
||||||
|
|
||||||
|
text += "<b>Vote Result: [mode == VOTE_GAMEMODE ? gamemode_names[.] : .]</b>"
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
text += "<b>The vote has ended.</b>"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
text += "<b>Vote Result: Inconclusive - No Votes!</b>"
|
||||||
|
|
||||||
|
if(mode == VOTE_ADD_ANTAGONIST)
|
||||||
|
|
||||||
|
antag_add_failed = 1
|
||||||
|
|
||||||
|
log_vote(text)
|
||||||
|
|
||||||
|
to_chat(world, "<font color='purple'>[text]</font>")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/datum/controller/subsystem/vote/proc/result()
|
||||||
|
|
||||||
|
. = announce_result()
|
||||||
|
|
||||||
|
var/restart = 0
|
||||||
|
|
||||||
|
if(.)
|
||||||
|
|
||||||
|
switch(mode)
|
||||||
|
|
||||||
|
if(VOTE_RESTART)
|
||||||
|
|
||||||
|
if(. == "Restart Round")
|
||||||
|
|
||||||
|
restart = 1
|
||||||
|
|
||||||
|
if(VOTE_GAMEMODE)
|
||||||
|
|
||||||
|
if(master_mode != .)
|
||||||
|
|
||||||
|
world.save_mode(.)
|
||||||
|
|
||||||
|
if(ticker && ticker.mode)
|
||||||
|
|
||||||
|
restart = 1
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
master_mode = .
|
||||||
|
|
||||||
|
if(VOTE_CREW_TRANSFER)
|
||||||
|
|
||||||
|
if(. == "Initiate Crew Transfer")
|
||||||
|
|
||||||
|
init_shift_change(null, 1)
|
||||||
|
|
||||||
|
if(VOTE_ADD_ANTAGONIST)
|
||||||
|
|
||||||
|
if(isnull(.) || . == "None")
|
||||||
|
|
||||||
|
antag_add_failed = 1
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
additional_antag_types |= antag_names_to_ids[.]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(mode == VOTE_GAMEMODE) //fire this even if the vote fails.
|
||||||
|
|
||||||
|
if(!round_progressing)
|
||||||
|
|
||||||
|
round_progressing = 1
|
||||||
|
|
||||||
|
world << "<font color='red'><b>The round will start soon.</b></font>"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(restart)
|
||||||
|
|
||||||
|
world << "World restarting due to vote..."
|
||||||
|
|
||||||
|
feedback_set_details("end_error", "restart vote")
|
||||||
|
|
||||||
|
if(blackbox)
|
||||||
|
|
||||||
|
blackbox.save_all_data_to_sql()
|
||||||
|
|
||||||
|
sleep(50)
|
||||||
|
|
||||||
|
log_game("Rebooting due to restart vote")
|
||||||
|
|
||||||
|
world.Reboot()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/datum/controller/subsystem/vote/proc/submit_vote(ckey, newVote)
|
||||||
|
|
||||||
|
if(mode)
|
||||||
|
|
||||||
|
if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
if(current_votes[ckey])
|
||||||
|
|
||||||
|
choices[choices[current_votes[ckey]]]--
|
||||||
|
|
||||||
|
if(newVote && newVote >= 1 && newVote <= choices.len)
|
||||||
|
|
||||||
|
choices[choices[newVote]]++
|
||||||
|
|
||||||
|
current_votes[ckey] = newVote
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
current_votes[ckey] = null
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key, automatic = FALSE, time = config.vote_period)
|
||||||
|
|
||||||
|
if(!mode)
|
||||||
|
|
||||||
|
if(started_time != null && !(check_rights(R_ADMIN) || automatic))
|
||||||
|
|
||||||
|
var/next_allowed_time = (started_time + config.vote_delay)
|
||||||
|
|
||||||
|
if(next_allowed_time > world.time)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
reset()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
switch(vote_type)
|
||||||
|
|
||||||
|
if(VOTE_RESTART)
|
||||||
|
|
||||||
|
choices.Add("Restart Round", "Continue Playing")
|
||||||
|
|
||||||
|
if(VOTE_GAMEMODE)
|
||||||
|
|
||||||
|
if(ticker.current_state >= GAME_STATE_SETTING_UP)
|
||||||
|
|
||||||
|
|||||||
21
code/datums/datumvars.dm
Normal file
21
code/datums/datumvars.dm
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#define VV_MSG_MARKED "<br><font size='1' color='red'><b>Marked Object</b></font>"
|
||||||
|
#define VV_MSG_EDITED "<br><font size='1' color='red'><b>Var Edited</b></font>"
|
||||||
|
#define VV_MSG_DELETED "<br><font size='1' color='red'><b>Deleted</b></font>"
|
||||||
|
|
||||||
|
/datum/proc/CanProcCall(procname)
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/datum/proc/can_vv_get(var_name)
|
||||||
|
//Pending refactor of vv_hidden
|
||||||
|
//return TRUE
|
||||||
|
|
||||||
|
return !(var_name in VV_hidden())
|
||||||
|
|
||||||
|
/datum/proc/vv_edit_var(var_name, var_value) //called whenever a var is edited
|
||||||
|
//Pending refactor of vv_static
|
||||||
|
//if(var_name == NAMEOF(src, vars))
|
||||||
|
// return FALSE
|
||||||
|
if(var_name in VV_static())
|
||||||
|
return FALSE
|
||||||
|
vars[var_name] = var_value
|
||||||
|
return TRUE
|
||||||
@@ -464,7 +464,7 @@ proc/display_roundstart_logout_report()
|
|||||||
|
|
||||||
if(L.ckey)
|
if(L.ckey)
|
||||||
var/found = 0
|
var/found = 0
|
||||||
for(var/client/C in clients)
|
for(var/client/C in GLOB.clients)
|
||||||
if(C.ckey == L.ckey)
|
if(C.ckey == L.ckey)
|
||||||
found = 1
|
found = 1
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
var/list/Lines = list()
|
var/list/Lines = list()
|
||||||
|
|
||||||
if(holder && (R_ADMIN & holder.rights || R_MOD & holder.rights))
|
if(holder && (R_ADMIN & holder.rights || R_MOD & holder.rights))
|
||||||
for(var/client/C in clients)
|
for(var/client/C in GLOB.clients)
|
||||||
var/entry = "\t[C.key]"
|
var/entry = "\t[C.key]"
|
||||||
if(C.holder && C.holder.fakekey)
|
if(C.holder && C.holder.fakekey)
|
||||||
entry += " <i>(as [C.holder.fakekey])</i>"
|
entry += " <i>(as [C.holder.fakekey])</i>"
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
Lines += entry
|
Lines += entry
|
||||||
else
|
else
|
||||||
for(var/client/C in clients)
|
for(var/client/C in GLOB.clients)
|
||||||
var/entry = "\t"
|
var/entry = "\t"
|
||||||
if(C.holder && C.holder.fakekey)
|
if(C.holder && C.holder.fakekey)
|
||||||
entry += "[C.holder.fakekey]"
|
entry += "[C.holder.fakekey]"
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
/client/proc/is_key_ignored(var/key_to_check)
|
/client/proc/is_key_ignored(var/key_to_check)
|
||||||
key_to_check = ckey(key_to_check)
|
key_to_check = ckey(key_to_check)
|
||||||
if(key_to_check in prefs.ignored_players)
|
if(key_to_check in prefs.ignored_players)
|
||||||
if(directory[key_to_check] in admins) // This is here so this is only evaluated if someone is actually being blocked.
|
if(GLOB.directory[key_to_check] in admins) // This is here so this is only evaluated if someone is actually being blocked.
|
||||||
return 0
|
return 0
|
||||||
return 1
|
return 1
|
||||||
return 0
|
return 0
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
if(holder.rights & R_ADMIN)
|
if(holder.rights & R_ADMIN)
|
||||||
ooc_style = "admin"
|
ooc_style = "admin"
|
||||||
|
|
||||||
for(var/client/target in clients)
|
for(var/client/target in GLOB.clients)
|
||||||
if(target.is_preference_enabled(/datum/client_preference/show_ooc))
|
if(target.is_preference_enabled(/datum/client_preference/show_ooc))
|
||||||
if(target.is_key_ignored(key)) // If we're ignored by this person, then do nothing.
|
if(target.is_key_ignored(key)) // If we're ignored by this person, then do nothing.
|
||||||
continue
|
continue
|
||||||
@@ -124,7 +124,7 @@
|
|||||||
var/list/in_range = get_mobs_and_objs_in_view_fast(T,world.view,0)
|
var/list/in_range = get_mobs_and_objs_in_view_fast(T,world.view,0)
|
||||||
var/list/m_viewers = in_range["mobs"]
|
var/list/m_viewers = in_range["mobs"]
|
||||||
|
|
||||||
var/list/receivers = list() // Clients, not mobs.
|
var/list/receivers = list() //Clients, not mobs.
|
||||||
var/list/r_receivers = list()
|
var/list/r_receivers = list()
|
||||||
|
|
||||||
var/display_name = key
|
var/display_name = key
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
var/list/Lines = list()
|
var/list/Lines = list()
|
||||||
|
|
||||||
if(holder && (R_ADMIN & holder.rights || R_MOD & holder.rights))
|
if(holder && (R_ADMIN & holder.rights || R_MOD & holder.rights))
|
||||||
for(var/client/C in clients)
|
for(var/client/C in GLOB.clients)
|
||||||
var/entry = "\t[C.key]"
|
var/entry = "\t[C.key]"
|
||||||
if(C.holder && C.holder.fakekey)
|
if(C.holder && C.holder.fakekey)
|
||||||
entry += " <i>(as [C.holder.fakekey])</i>"
|
entry += " <i>(as [C.holder.fakekey])</i>"
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
entry += " (<A HREF='?_src_=holder;adminmoreinfo=\ref[C.mob]'>?</A>)"
|
entry += " (<A HREF='?_src_=holder;adminmoreinfo=\ref[C.mob]'>?</A>)"
|
||||||
Lines += entry
|
Lines += entry
|
||||||
else
|
else
|
||||||
for(var/client/C in clients)
|
for(var/client/C in GLOB.clients)
|
||||||
if(C.holder && C.holder.fakekey)
|
if(C.holder && C.holder.fakekey)
|
||||||
Lines += C.holder.fakekey
|
Lines += C.holder.fakekey
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration =
|
|||||||
a_ip = src.owner:address
|
a_ip = src.owner:address
|
||||||
|
|
||||||
var/who
|
var/who
|
||||||
for(var/client/C in clients)
|
for(var/client/C in GLOB.clients)
|
||||||
if(!who)
|
if(!who)
|
||||||
who = "[C]"
|
who = "[C]"
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -286,7 +286,7 @@ proc/admin_notice(var/message, var/rights)
|
|||||||
dat += "<body>"
|
dat += "<body>"
|
||||||
|
|
||||||
var/p_age = "unknown"
|
var/p_age = "unknown"
|
||||||
for(var/client/C in clients)
|
for(var/client/C in GLOB.clients)
|
||||||
if(C.ckey == key)
|
if(C.ckey == key)
|
||||||
p_age = C.player_age
|
p_age = C.player_age
|
||||||
break
|
break
|
||||||
@@ -730,28 +730,28 @@ var/datum/announcement/minor/admin_min_announcer = new
|
|||||||
//Split on pipe or \n
|
//Split on pipe or \n
|
||||||
decomposed = splittext(message,regex("\\||$","m"))
|
decomposed = splittext(message,regex("\\||$","m"))
|
||||||
decomposed += "0" //Tack on a final 0 sleep to make 3-per-message evenly
|
decomposed += "0" //Tack on a final 0 sleep to make 3-per-message evenly
|
||||||
|
|
||||||
//Time to find how they screwed up.
|
//Time to find how they screwed up.
|
||||||
//Wasn't the right length
|
//Wasn't the right length
|
||||||
if((decomposed.len) % 3) //+1 to accomidate the lack of a wait time for the last message
|
if((decomposed.len) % 3) //+1 to accomidate the lack of a wait time for the last message
|
||||||
to_chat(usr,"<span class='warning'>You passed [decomposed.len] segments (senders+messages+pauses). You must pass a multiple of 3, minus 1 (no pause after the last message). That means a sender and message on every other line (starting on the first), separated by a pipe character (|), and a number every other line that is a pause in seconds.</span>")
|
to_chat(usr,"<span class='warning'>You passed [decomposed.len] segments (senders+messages+pauses). You must pass a multiple of 3, minus 1 (no pause after the last message). That means a sender and message on every other line (starting on the first), separated by a pipe character (|), and a number every other line that is a pause in seconds.</span>")
|
||||||
return
|
return
|
||||||
|
|
||||||
//Too long a conversation
|
//Too long a conversation
|
||||||
if((decomposed.len / 3) > 20)
|
if((decomposed.len / 3) > 20)
|
||||||
to_chat(usr,"<span class='warning'>This conversation is too long! 20 messages maximum, please.</span>")
|
to_chat(usr,"<span class='warning'>This conversation is too long! 20 messages maximum, please.</span>")
|
||||||
return
|
return
|
||||||
|
|
||||||
//Missed some sleeps, or sanitized to nothing.
|
//Missed some sleeps, or sanitized to nothing.
|
||||||
for(var/i = 1; i < decomposed.len; i++)
|
for(var/i = 1; i < decomposed.len; i++)
|
||||||
|
|
||||||
//Sanitize sender
|
//Sanitize sender
|
||||||
var/clean_sender = sanitize(decomposed[i])
|
var/clean_sender = sanitize(decomposed[i])
|
||||||
if(!clean_sender)
|
if(!clean_sender)
|
||||||
to_chat(usr,"<span class='warning'>One part of your conversation was not able to be sanitized. It was the sender of the [(i+2)/3]\th message.</span>")
|
to_chat(usr,"<span class='warning'>One part of your conversation was not able to be sanitized. It was the sender of the [(i+2)/3]\th message.</span>")
|
||||||
return
|
return
|
||||||
decomposed[i] = clean_sender
|
decomposed[i] = clean_sender
|
||||||
|
|
||||||
//Sanitize message
|
//Sanitize message
|
||||||
var/clean_message = sanitize(decomposed[++i])
|
var/clean_message = sanitize(decomposed[++i])
|
||||||
if(!clean_message)
|
if(!clean_message)
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ var/list/admin_ranks = list() //list of all ranks with associated rights
|
|||||||
var/datum/admins/D = new /datum/admins(rank, rights, ckey)
|
var/datum/admins/D = new /datum/admins(rank, rights, ckey)
|
||||||
|
|
||||||
//find the client for a ckey if they are connected and associate them with the new admin datum
|
//find the client for a ckey if they are connected and associate them with the new admin datum
|
||||||
D.associate(directory[ckey])
|
D.associate(GLOB.directory[ckey])
|
||||||
|
|
||||||
else
|
else
|
||||||
//The current admin system uses SQL
|
//The current admin system uses SQL
|
||||||
@@ -125,7 +125,7 @@ var/list/admin_ranks = list() //list of all ranks with associated rights
|
|||||||
var/datum/admins/D = new /datum/admins(rank, rights, ckey)
|
var/datum/admins/D = new /datum/admins(rank, rights, ckey)
|
||||||
|
|
||||||
//find the client for a ckey if they are connected and associate them with the new admin datum
|
//find the client for a ckey if they are connected and associate them with the new admin datum
|
||||||
D.associate(directory[ckey])
|
D.associate(GLOB.directory[ckey])
|
||||||
if(!admin_datums)
|
if(!admin_datums)
|
||||||
error("The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system.")
|
error("The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system.")
|
||||||
log_misc("The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system.")
|
log_misc("The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system.")
|
||||||
|
|||||||
@@ -215,8 +215,11 @@ var/list/admin_verbs_debug = list(
|
|||||||
/client/proc/enable_debug_verbs,
|
/client/proc/enable_debug_verbs,
|
||||||
/client/proc/callproc,
|
/client/proc/callproc,
|
||||||
/client/proc/callproc_target,
|
/client/proc/callproc_target,
|
||||||
|
<<<<<<< HEAD
|
||||||
/client/proc/debug_process,
|
/client/proc/debug_process,
|
||||||
/client/proc/SDQL_query,
|
/client/proc/SDQL_query,
|
||||||
|
=======
|
||||||
|
>>>>>>> ae64d73... Upgrades SDQL2 and refactors it to a datum (#5793)
|
||||||
/client/proc/SDQL2_query,
|
/client/proc/SDQL2_query,
|
||||||
/client/proc/Jump,
|
/client/proc/Jump,
|
||||||
/client/proc/debug_rogueminer,
|
/client/proc/debug_rogueminer,
|
||||||
@@ -645,7 +648,7 @@ var/list/admin_verbs_event_manager = list(
|
|||||||
return
|
return
|
||||||
|
|
||||||
var/datum/preferences/D
|
var/datum/preferences/D
|
||||||
var/client/C = directory[warned_ckey]
|
var/client/C = GLOB.directory[warned_ckey]
|
||||||
if(C) D = C.prefs
|
if(C) D = C.prefs
|
||||||
else D = preferences_datums[warned_ckey]
|
else D = preferences_datums[warned_ckey]
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
if("Area or Turf")
|
if("Area or Turf")
|
||||||
target = input("Select target:", "Target", get_turf(usr)) as null|area|turf in world
|
target = input("Select target:", "Target", get_turf(usr)) as null|area|turf in world
|
||||||
if("Client")
|
if("Client")
|
||||||
target = input("Select target:", "Target", usr.client) as null|anything in clients
|
target = input("Select target:", "Target", usr.client) as null|anything in GLOB.clients
|
||||||
else
|
else
|
||||||
return
|
return
|
||||||
if(!target)
|
if(!target)
|
||||||
@@ -110,7 +110,7 @@
|
|||||||
if(isnull(current)) return
|
if(isnull(current)) return
|
||||||
|
|
||||||
if("client")
|
if("client")
|
||||||
current = input("Select client for [arguments.len+1]\th argument") as null|anything in clients
|
current = input("Select client for [arguments.len+1]\th argument") as null|anything in GLOB.clients
|
||||||
if(isnull(current)) return
|
if(isnull(current)) return
|
||||||
|
|
||||||
if("mob's area")
|
if("mob's area")
|
||||||
|
|||||||
@@ -175,7 +175,7 @@
|
|||||||
else
|
else
|
||||||
D = new /datum/admins(new_rank, rights, adm_ckey)
|
D = new /datum/admins(new_rank, rights, adm_ckey)
|
||||||
|
|
||||||
var/client/C = directory[adm_ckey] //find the client with the specified ckey (if they are logged in)
|
var/client/C = GLOB.directory[adm_ckey] //find the client with the specified ckey (if they are logged in)
|
||||||
D.associate(C) //link up with the client and add verbs
|
D.associate(C) //link up with the client and add verbs
|
||||||
|
|
||||||
message_admins("[key_name_admin(usr)] edited the admin rank of [adm_ckey] to [new_rank]")
|
message_admins("[key_name_admin(usr)] edited the admin rank of [adm_ckey] to [new_rank]")
|
||||||
|
|||||||
@@ -1,497 +0,0 @@
|
|||||||
|
|
||||||
//Structured Datum Query Language. Basically SQL meets BYOND objects.
|
|
||||||
|
|
||||||
//Note: For use in BS12, need text_starts_with proc, and to modify the action on select to use BS12's object edit command(s).
|
|
||||||
|
|
||||||
/client/proc/SDQL_query(query_text as message)
|
|
||||||
set category = "Admin"
|
|
||||||
if(!check_rights(R_DEBUG)) //Shouldn't happen... but just to be safe.
|
|
||||||
message_admins("<font color='red'>ERROR: Non-admin [usr.key] attempted to execute a SDQL query!</font>")
|
|
||||||
log_admin("Non-admin [usr.key] attempted to execute a SDQL query!")
|
|
||||||
|
|
||||||
var/list/query_list = SDQL_tokenize(query_text)
|
|
||||||
|
|
||||||
if(query_list.len < 2)
|
|
||||||
if(query_list.len > 0)
|
|
||||||
usr << "<font color='red'>SDQL: Too few discrete tokens in query \"[query_text]\". Please check your syntax and try again.</font>"
|
|
||||||
return
|
|
||||||
|
|
||||||
if(!(lowertext(query_list[1]) in list("select", "delete", "update")))
|
|
||||||
usr << "<font color='red'>SDQL: Unknown query type: \"[query_list[1]]\" in query \"[query_text]\". Please check your syntax and try again.</font>"
|
|
||||||
return
|
|
||||||
|
|
||||||
var/list/types = list()
|
|
||||||
|
|
||||||
var/i
|
|
||||||
for(i = 2; i <= query_list.len; i += 2)
|
|
||||||
types += query_list[i]
|
|
||||||
|
|
||||||
if(i + 1 >= query_list.len || query_list[i + 1] != ",")
|
|
||||||
break
|
|
||||||
|
|
||||||
i++
|
|
||||||
|
|
||||||
var/list/from = list()
|
|
||||||
|
|
||||||
if(i <= query_list.len)
|
|
||||||
if(lowertext(query_list[i]) in list("from", "in"))
|
|
||||||
for(i++; i <= query_list.len; i += 2)
|
|
||||||
from += query_list[i]
|
|
||||||
|
|
||||||
if(i + 1 >= query_list.len || query_list[i + 1] != ",")
|
|
||||||
break
|
|
||||||
|
|
||||||
i++
|
|
||||||
|
|
||||||
if(from.len < 1)
|
|
||||||
from += "world"
|
|
||||||
|
|
||||||
var/list/set_vars = list()
|
|
||||||
|
|
||||||
if(lowertext(query_list[1]) == "update")
|
|
||||||
if(i <= query_list.len && lowertext(query_list[i]) == "set")
|
|
||||||
for(i++; i <= query_list.len; i++)
|
|
||||||
if(i + 2 <= query_list.len && query_list[i + 1] == "=")
|
|
||||||
set_vars += query_list[i]
|
|
||||||
set_vars[query_list[i]] = query_list[i + 2]
|
|
||||||
|
|
||||||
else
|
|
||||||
usr << "<font color='red'>SDQL: Invalid set parameter in query \"[query_text]\". Please check your syntax and try again.</font>"
|
|
||||||
return
|
|
||||||
|
|
||||||
i += 3
|
|
||||||
|
|
||||||
if(i >= query_list.len || query_list[i] != ",")
|
|
||||||
break
|
|
||||||
|
|
||||||
if(set_vars.len < 1)
|
|
||||||
usr << "<font color='red'>SDQL: Invalid or missing set in query \"[query_text]\". Please check your syntax and try again.</font>"
|
|
||||||
return
|
|
||||||
|
|
||||||
var/list/where = list()
|
|
||||||
|
|
||||||
if(i <= query_list.len && lowertext(query_list[i]) == "where")
|
|
||||||
where = query_list.Copy(i + 1)
|
|
||||||
|
|
||||||
var/list/from_objs = list()
|
|
||||||
if("world" in from)
|
|
||||||
from_objs += world
|
|
||||||
else
|
|
||||||
for(var/f in from)
|
|
||||||
if(copytext(f, 1, 2) == "'" || copytext(f, 1, 2) == "\"")
|
|
||||||
from_objs += locate(copytext(f, 2, length(f)))
|
|
||||||
else if(copytext(f, 1, 2) != "/")
|
|
||||||
from_objs += locate(f)
|
|
||||||
else
|
|
||||||
var/f2 = text2path(f)
|
|
||||||
if(text_starts_with(f, "/mob"))
|
|
||||||
for(var/mob/m in mob_list)
|
|
||||||
if(istype(m, f2))
|
|
||||||
from_objs += m
|
|
||||||
|
|
||||||
else if(text_starts_with(f, "/turf/space"))
|
|
||||||
for(var/turf/space/m in turfs)
|
|
||||||
if(istype(m, f2))
|
|
||||||
from_objs += m
|
|
||||||
|
|
||||||
else if(text_starts_with(f, "/turf/simulated"))
|
|
||||||
for(var/turf/simulated/m in turfs)
|
|
||||||
if(istype(m, f2))
|
|
||||||
from_objs += m
|
|
||||||
|
|
||||||
else if(text_starts_with(f, "/turf/unsimulated"))
|
|
||||||
for(var/turf/unsimulated/m in turfs)
|
|
||||||
if(istype(m, f2))
|
|
||||||
from_objs += m
|
|
||||||
|
|
||||||
else if(text_starts_with(f, "/turf"))
|
|
||||||
for(var/turf/m in turfs)
|
|
||||||
if(istype(m, f2))
|
|
||||||
from_objs += m
|
|
||||||
|
|
||||||
else if(text_starts_with(f, "/area"))
|
|
||||||
for(var/area/m in all_areas)
|
|
||||||
if(istype(m, f2))
|
|
||||||
from_objs += m
|
|
||||||
|
|
||||||
else if(text_starts_with(f, "/obj/item"))
|
|
||||||
for(var/obj/item/m in world)
|
|
||||||
if(istype(m, f2))
|
|
||||||
from_objs += m
|
|
||||||
|
|
||||||
else if(text_starts_with(f, "/obj/machinery"))
|
|
||||||
for(var/obj/machinery/m in machines)
|
|
||||||
if(istype(m, f2))
|
|
||||||
from_objs += m
|
|
||||||
|
|
||||||
else if(text_starts_with(f, "/obj"))
|
|
||||||
for(var/obj/m in world)
|
|
||||||
if(istype(m, f2))
|
|
||||||
from_objs += m
|
|
||||||
|
|
||||||
else if(text_starts_with(f, "/atom"))
|
|
||||||
for(var/atom/m in world)
|
|
||||||
if(istype(m, f2))
|
|
||||||
from_objs += m
|
|
||||||
/*
|
|
||||||
else
|
|
||||||
for(var/datum/m in nope)
|
|
||||||
if(istype(m, f2))
|
|
||||||
from_objs += m
|
|
||||||
*/
|
|
||||||
|
|
||||||
var/list/objs = list()
|
|
||||||
|
|
||||||
for(var/from_obj in from_objs)
|
|
||||||
if("*" in types)
|
|
||||||
objs += from_obj:contents
|
|
||||||
else
|
|
||||||
for(var/f in types)
|
|
||||||
if(copytext(f, 1, 2) == "'" || copytext(f, 1, 2) == "\"")
|
|
||||||
objs += locate(copytext(f, 2, length(f))) in from_obj
|
|
||||||
else if(copytext(f, 1, 2) != "/")
|
|
||||||
objs += locate(f) in from_obj
|
|
||||||
else
|
|
||||||
var/f2 = text2path(f)
|
|
||||||
if(text_starts_with(f, "/mob"))
|
|
||||||
for(var/mob/m in from_obj)
|
|
||||||
if(istype(m, f2))
|
|
||||||
objs += m
|
|
||||||
|
|
||||||
else if(text_starts_with(f, "/turf/space"))
|
|
||||||
for(var/turf/space/m in from_obj)
|
|
||||||
if(istype(m, f2))
|
|
||||||
objs += m
|
|
||||||
|
|
||||||
else if(text_starts_with(f, "/turf/simulated"))
|
|
||||||
for(var/turf/simulated/m in from_obj)
|
|
||||||
if(istype(m, f2))
|
|
||||||
objs += m
|
|
||||||
|
|
||||||
else if(text_starts_with(f, "/turf/unsimulated"))
|
|
||||||
for(var/turf/unsimulated/m in from_obj)
|
|
||||||
if(istype(m, f2))
|
|
||||||
objs += m
|
|
||||||
|
|
||||||
else if(text_starts_with(f, "/turf"))
|
|
||||||
for(var/turf/m in from_obj)
|
|
||||||
if(istype(m, f2))
|
|
||||||
objs += m
|
|
||||||
|
|
||||||
else if(text_starts_with(f, "/area"))
|
|
||||||
for(var/area/m in from_obj)
|
|
||||||
if(istype(m, f2))
|
|
||||||
objs += m
|
|
||||||
|
|
||||||
else if(text_starts_with(f, "/obj/item"))
|
|
||||||
for(var/obj/item/m in from_obj)
|
|
||||||
if(istype(m, f2))
|
|
||||||
objs += m
|
|
||||||
|
|
||||||
else if(text_starts_with(f, "/obj/machinery"))
|
|
||||||
for(var/obj/machinery/m in from_obj)
|
|
||||||
if(istype(m, f2))
|
|
||||||
objs += m
|
|
||||||
|
|
||||||
else if(text_starts_with(f, "/obj"))
|
|
||||||
for(var/obj/m in from_obj)
|
|
||||||
if(istype(m, f2))
|
|
||||||
objs += m
|
|
||||||
|
|
||||||
else if(text_starts_with(f, "/atom"))
|
|
||||||
for(var/atom/m in from_obj)
|
|
||||||
if(istype(m, f2))
|
|
||||||
objs += m
|
|
||||||
|
|
||||||
else
|
|
||||||
for(var/datum/m in from_obj)
|
|
||||||
if(istype(m, f2))
|
|
||||||
objs += m
|
|
||||||
|
|
||||||
|
|
||||||
for(var/datum/t in objs)
|
|
||||||
var/currently_false = 0
|
|
||||||
for(i = 1, i - 1 < where.len, i++)
|
|
||||||
var/v = where[i++]
|
|
||||||
var/compare_op = where[i++]
|
|
||||||
if(!(compare_op in list("==", "=", "<>", "<", ">", "<=", ">=", "!=")))
|
|
||||||
usr << "<font color='red'>SDQL: Unknown comparison operator [compare_op] in where clause following [v] in query \"[query_text]\". Please check your syntax and try again.</font>"
|
|
||||||
return
|
|
||||||
|
|
||||||
var/j
|
|
||||||
for(j = i, j <= where.len, j++)
|
|
||||||
if(lowertext(where[j]) in list("and", "or", ";"))
|
|
||||||
break
|
|
||||||
|
|
||||||
if(!currently_false)
|
|
||||||
var/value = SDQL_text2value(t, v)
|
|
||||||
var/result = SDQL_evaluate(t, where.Copy(i, j))
|
|
||||||
|
|
||||||
switch(compare_op)
|
|
||||||
if("=", "==")
|
|
||||||
currently_false = !(value == result)
|
|
||||||
|
|
||||||
if("!=", "<>")
|
|
||||||
currently_false = !(value != result)
|
|
||||||
|
|
||||||
if("<")
|
|
||||||
currently_false = !(value < result)
|
|
||||||
|
|
||||||
if(">")
|
|
||||||
currently_false = !(value > result)
|
|
||||||
|
|
||||||
if("<=")
|
|
||||||
currently_false = !(value <= result)
|
|
||||||
|
|
||||||
if(">=")
|
|
||||||
currently_false = !(value >= result)
|
|
||||||
|
|
||||||
|
|
||||||
if(j > where.len || lowertext(where[j]) == ";")
|
|
||||||
break
|
|
||||||
else if(lowertext(where[j]) == "or")
|
|
||||||
if(currently_false)
|
|
||||||
currently_false = 0
|
|
||||||
else
|
|
||||||
break
|
|
||||||
|
|
||||||
i = j
|
|
||||||
|
|
||||||
if(currently_false)
|
|
||||||
objs -= t
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
usr << "<font color='blue'>SQDL Query: [query_text]</font>"
|
|
||||||
message_admins("[usr] executed SDQL query: \"[query_text]\".")
|
|
||||||
/*
|
|
||||||
for(var/t in types)
|
|
||||||
usr << "Type: [t]"
|
|
||||||
|
|
||||||
for(var/t in from)
|
|
||||||
usr << "From: [t]"
|
|
||||||
|
|
||||||
for(var/t in set_vars)
|
|
||||||
usr << "Set: [t] = [set_vars[t]]"
|
|
||||||
|
|
||||||
if(where.len)
|
|
||||||
var/where_str = ""
|
|
||||||
for(var/t in where)
|
|
||||||
where_str += "[t] "
|
|
||||||
|
|
||||||
usr << "Where: [where_str]"
|
|
||||||
|
|
||||||
usr << "From objects:"
|
|
||||||
for(var/datum/t in from_objs)
|
|
||||||
usr << t
|
|
||||||
|
|
||||||
usr << "Objects:"
|
|
||||||
for(var/datum/t in objs)
|
|
||||||
usr << t
|
|
||||||
*/
|
|
||||||
switch(lowertext(query_list[1]))
|
|
||||||
if("delete")
|
|
||||||
for(var/datum/t in objs)
|
|
||||||
qdel(t)
|
|
||||||
|
|
||||||
if("update")
|
|
||||||
for(var/datum/t in objs)
|
|
||||||
objs[t] = list()
|
|
||||||
for(var/v in set_vars)
|
|
||||||
if(v in t.vars)
|
|
||||||
objs[t][v] = SDQL_text2value(t, set_vars[v])
|
|
||||||
|
|
||||||
for(var/datum/t in objs)
|
|
||||||
for(var/v in objs[t])
|
|
||||||
t.vars[v] = objs[t][v]
|
|
||||||
|
|
||||||
if("select")
|
|
||||||
var/text = ""
|
|
||||||
for(var/datum/t in objs)
|
|
||||||
if(istype(t, /atom))
|
|
||||||
var/atom/a = t
|
|
||||||
|
|
||||||
if(a.x)
|
|
||||||
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t] at ([a.x], [a.y], [a.z])<br>"
|
|
||||||
|
|
||||||
else if(a.loc && a.loc.x)
|
|
||||||
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t] in [a.loc] at ([a.loc.x], [a.loc.y], [a.loc.z])<br>"
|
|
||||||
|
|
||||||
else
|
|
||||||
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t]<br>"
|
|
||||||
|
|
||||||
else
|
|
||||||
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t]<br>"
|
|
||||||
|
|
||||||
//text += "[t]<br>"
|
|
||||||
usr << browse(text, "window=sdql_result")
|
|
||||||
|
|
||||||
|
|
||||||
/client/Topic(href,href_list[],hsrc)
|
|
||||||
if(href_list["SDQL_select"])
|
|
||||||
debug_variables(locate(href_list["SDQL_select"]))
|
|
||||||
|
|
||||||
..()
|
|
||||||
|
|
||||||
|
|
||||||
/proc/SDQL_evaluate(datum/object, list/equation)
|
|
||||||
if(equation.len == 0)
|
|
||||||
return null
|
|
||||||
|
|
||||||
else if(equation.len == 1)
|
|
||||||
return SDQL_text2value(object, equation[1])
|
|
||||||
|
|
||||||
else if(equation[1] == "!")
|
|
||||||
return !SDQL_evaluate(object, equation.Copy(2))
|
|
||||||
|
|
||||||
else if(equation[1] == "-")
|
|
||||||
return -SDQL_evaluate(object, equation.Copy(2))
|
|
||||||
|
|
||||||
|
|
||||||
else
|
|
||||||
usr << "<font color='red'>SDQL: Sorry, equations not yet supported :(</font>"
|
|
||||||
return null
|
|
||||||
|
|
||||||
|
|
||||||
/proc/SDQL_text2value(datum/object, text)
|
|
||||||
if(text2num(text) != null)
|
|
||||||
return text2num(text)
|
|
||||||
else if(text == "null")
|
|
||||||
return null
|
|
||||||
else if(copytext(text, 1, 2) == "'" || copytext(text, 1, 2) == "\"" )
|
|
||||||
return copytext(text, 2, length(text))
|
|
||||||
else if(copytext(text, 1, 2) == "/")
|
|
||||||
return text2path(text)
|
|
||||||
else
|
|
||||||
if(findtext(text, "."))
|
|
||||||
var/split = findtext(text, ".")
|
|
||||||
var/v = copytext(text, 1, split)
|
|
||||||
|
|
||||||
if((v in object.vars) && istype(object.vars[v], /datum))
|
|
||||||
return SDQL_text2value(object.vars[v], copytext(text, split + 1))
|
|
||||||
else
|
|
||||||
return null
|
|
||||||
|
|
||||||
else
|
|
||||||
if(text in object.vars)
|
|
||||||
return object.vars[text]
|
|
||||||
else
|
|
||||||
return null
|
|
||||||
|
|
||||||
|
|
||||||
/proc/text_starts_with(text, start)
|
|
||||||
if(copytext(text, 1, length(start) + 1) == start)
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/proc/SDQL_tokenize(query_text)
|
|
||||||
|
|
||||||
var/list/whitespace = list(" ", "\n", "\t")
|
|
||||||
var/list/single = list("(", ")", ",", "+", "-")
|
|
||||||
var/list/multi = list(
|
|
||||||
"=" = list("", "="),
|
|
||||||
"<" = list("", "=", ">"),
|
|
||||||
">" = list("", "="),
|
|
||||||
"!" = list("", "="))
|
|
||||||
|
|
||||||
var/word = ""
|
|
||||||
var/list/query_list = list()
|
|
||||||
var/len = length(query_text)
|
|
||||||
|
|
||||||
for(var/i = 1, i <= len, i++)
|
|
||||||
var/char = copytext(query_text, i, i + 1)
|
|
||||||
|
|
||||||
if(char in whitespace)
|
|
||||||
if(word != "")
|
|
||||||
query_list += word
|
|
||||||
word = ""
|
|
||||||
|
|
||||||
else if(char in single)
|
|
||||||
if(word != "")
|
|
||||||
query_list += word
|
|
||||||
word = ""
|
|
||||||
|
|
||||||
query_list += char
|
|
||||||
|
|
||||||
else if(char in multi)
|
|
||||||
if(word != "")
|
|
||||||
query_list += word
|
|
||||||
word = ""
|
|
||||||
|
|
||||||
var/char2 = copytext(query_text, i + 1, i + 2)
|
|
||||||
|
|
||||||
if(char2 in multi[char])
|
|
||||||
query_list += "[char][char2]"
|
|
||||||
i++
|
|
||||||
|
|
||||||
else
|
|
||||||
query_list += char
|
|
||||||
|
|
||||||
else if(char == "'")
|
|
||||||
if(word != "")
|
|
||||||
usr << "<font color='red'>SDQL: You have an error in your SDQL syntax, unexpected ' in query:</font> \"<font color=gray>[query_text]</font>\" following \"<font color=gray>[word]</font>\". Please check your syntax, and try again."
|
|
||||||
return null
|
|
||||||
|
|
||||||
word = "'"
|
|
||||||
|
|
||||||
for(i++, i <= len, i++)
|
|
||||||
char = copytext(query_text, i, i + 1)
|
|
||||||
|
|
||||||
if(char == "'")
|
|
||||||
if(copytext(query_text, i + 1, i + 2) == "'")
|
|
||||||
word += "'"
|
|
||||||
i++
|
|
||||||
|
|
||||||
else
|
|
||||||
break
|
|
||||||
|
|
||||||
else
|
|
||||||
word += char
|
|
||||||
|
|
||||||
if(i > len)
|
|
||||||
usr << "<font color='red'>SDQL: You have an error in your SDQL syntax, unmatched ' in query: </font>\"<font color=gray>[query_text]</font>\". Please check your syntax, and try again."
|
|
||||||
return null
|
|
||||||
|
|
||||||
query_list += "[word]'"
|
|
||||||
word = ""
|
|
||||||
|
|
||||||
else if(char == "\"")
|
|
||||||
if(word != "")
|
|
||||||
usr << "<font color='red'>SDQL: You have an error in your SDQL syntax, unexpected \" in query: </font>\"<font color=gray>[query_text]</font>\" following \"<font color=gray>[word]</font>\". Please check your syntax, and try again."
|
|
||||||
return null
|
|
||||||
|
|
||||||
word = "\""
|
|
||||||
|
|
||||||
for(i++, i <= len, i++)
|
|
||||||
char = copytext(query_text, i, i + 1)
|
|
||||||
|
|
||||||
if(char == "\"")
|
|
||||||
if(copytext(query_text, i + 1, i + 2) == "'")
|
|
||||||
word += "\""
|
|
||||||
i++
|
|
||||||
|
|
||||||
else
|
|
||||||
break
|
|
||||||
|
|
||||||
else
|
|
||||||
word += char
|
|
||||||
|
|
||||||
if(i > len)
|
|
||||||
usr << "<font color='red'>SDQL: You have an error in your SDQL syntax, unmatched \" in query: </font>\"<font color=gray>[query_text]</font>\". Please check your syntax, and try again."
|
|
||||||
return null
|
|
||||||
|
|
||||||
query_list += "[word]\""
|
|
||||||
word = ""
|
|
||||||
|
|
||||||
else
|
|
||||||
word += char
|
|
||||||
|
|
||||||
if(word != "")
|
|
||||||
query_list += word
|
|
||||||
|
|
||||||
return query_list
|
|
||||||
1127
code/modules/admin/verbs/SDQL2/SDQL_2.dm
Normal file
1127
code/modules/admin/verbs/SDQL2/SDQL_2.dm
Normal file
File diff suppressed because it is too large
Load Diff
635
code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm
Normal file
635
code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm
Normal file
@@ -0,0 +1,635 @@
|
|||||||
|
|
||||||
|
//I'm pretty sure that this is a recursive [s]descent[/s] ascent parser.
|
||||||
|
|
||||||
|
|
||||||
|
//Spec
|
||||||
|
|
||||||
|
//////////
|
||||||
|
//
|
||||||
|
// query : select_query | delete_query | update_query | call_query | explain
|
||||||
|
// explain : 'EXPLAIN' query
|
||||||
|
// select_query : 'SELECT' object_selectors
|
||||||
|
// delete_query : 'DELETE' object_selectors
|
||||||
|
// update_query : 'UPDATE' object_selectors 'SET' assignments
|
||||||
|
// call_query : 'CALL' variable 'ON' object_selectors // Note here: 'variable' does function calls. This simplifies parsing.
|
||||||
|
//
|
||||||
|
// select_item : '*' | object_type
|
||||||
|
//
|
||||||
|
// object_selectors : select_item [('FROM' | 'IN') from_item] [modifier_list]
|
||||||
|
// modifier_list : ('WHERE' bool_expression | 'MAP' expression) [modifier_list]
|
||||||
|
//
|
||||||
|
// from_item : 'world' | expression
|
||||||
|
//
|
||||||
|
// call_function : <function name> '(' [arguments] ')'
|
||||||
|
// arguments : expression [',' arguments]
|
||||||
|
//
|
||||||
|
// object_type : <type path>
|
||||||
|
//
|
||||||
|
// assignments : assignment [',' assignments]
|
||||||
|
// assignment : <variable name> '=' expression
|
||||||
|
// variable : <variable name> | <variable name> '.' variable | '[' <hex number> ']' | '[' <hex number> ']' '.' variable
|
||||||
|
//
|
||||||
|
// bool_expression : expression comparitor expression [bool_operator bool_expression]
|
||||||
|
// expression : ( unary_expression | '(' expression ')' | value ) [binary_operator expression]
|
||||||
|
// unary_expression : unary_operator ( unary_expression | value | '(' expression ')' )
|
||||||
|
// comparitor : '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>='
|
||||||
|
// value : variable | string | number | 'null' | object_type
|
||||||
|
// unary_operator : '!' | '-' | '~'
|
||||||
|
// binary_operator : comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^' | '%'
|
||||||
|
// bool_operator : 'AND' | '&&' | 'OR' | '||'
|
||||||
|
//
|
||||||
|
// string : ''' <some text> ''' | '"' <some text > '"'
|
||||||
|
// number : <some digits>
|
||||||
|
//
|
||||||
|
//////////
|
||||||
|
|
||||||
|
/datum/SDQL_parser
|
||||||
|
var/query_type
|
||||||
|
var/error = 0
|
||||||
|
|
||||||
|
var/list/query
|
||||||
|
var/list/tree
|
||||||
|
|
||||||
|
var/list/boolean_operators = list("and", "or", "&&", "||")
|
||||||
|
var/list/unary_operators = list("!", "-", "~")
|
||||||
|
var/list/binary_operators = list("+", "-", "/", "*", "&", "|", "^", "%")
|
||||||
|
var/list/comparitors = list("=", "==", "!=", "<>", "<", "<=", ">", ">=")
|
||||||
|
|
||||||
|
/datum/SDQL_parser/New(query_list)
|
||||||
|
query = query_list
|
||||||
|
|
||||||
|
/datum/SDQL_parser/proc/parse_error(error_message)
|
||||||
|
error = 1
|
||||||
|
to_chat(usr, "<span class='warning'>SQDL2 Parsing Error: [error_message]</span>")
|
||||||
|
return query.len + 1
|
||||||
|
|
||||||
|
/datum/SDQL_parser/proc/parse()
|
||||||
|
tree = list()
|
||||||
|
query_options(1, tree)
|
||||||
|
|
||||||
|
if(error)
|
||||||
|
return list()
|
||||||
|
else
|
||||||
|
return tree
|
||||||
|
|
||||||
|
/datum/SDQL_parser/proc/token(i)
|
||||||
|
if(i <= query.len)
|
||||||
|
return query[i]
|
||||||
|
|
||||||
|
else
|
||||||
|
return null
|
||||||
|
|
||||||
|
/datum/SDQL_parser/proc/tokens(i, num)
|
||||||
|
if(i + num <= query.len)
|
||||||
|
return query.Copy(i, i + num)
|
||||||
|
|
||||||
|
else
|
||||||
|
return null
|
||||||
|
|
||||||
|
/datum/SDQL_parser/proc/tokenl(i)
|
||||||
|
return lowertext(token(i))
|
||||||
|
|
||||||
|
/datum/SDQL_parser/proc/query_options(i, list/node)
|
||||||
|
var/list/options = list()
|
||||||
|
if(tokenl(i) == "using")
|
||||||
|
i = option_assignments(i + 1, node, options)
|
||||||
|
query(i, node)
|
||||||
|
if(length(options))
|
||||||
|
node["options"] = options
|
||||||
|
|
||||||
|
//option_assignment: query_option '=' define
|
||||||
|
/datum/SDQL_parser/proc/option_assignment(i, list/node, list/assignment_list = list())
|
||||||
|
var/type = tokenl(i)
|
||||||
|
if(!(type in SDQL2_VALID_OPTION_TYPES))
|
||||||
|
parse_error("Invalid option type: [type]")
|
||||||
|
if(!(token(i + 1) == "="))
|
||||||
|
parse_error("Invalid option assignment symbol: [token(i + 1)]")
|
||||||
|
var/val = tokenl(i + 2)
|
||||||
|
if(!(val in SDQL2_VALID_OPTION_VALUES))
|
||||||
|
parse_error("Invalid optoin value: [val]")
|
||||||
|
assignment_list[type] = val
|
||||||
|
return (i + 3)
|
||||||
|
|
||||||
|
//option_assignments: option_assignment, [',' option_assignments]
|
||||||
|
/datum/SDQL_parser/proc/option_assignments(i, list/node, list/store)
|
||||||
|
i = option_assignment(i, node, store)
|
||||||
|
|
||||||
|
if(token(i) == ",")
|
||||||
|
i = option_assignments(i + 1, node, store)
|
||||||
|
|
||||||
|
return i
|
||||||
|
|
||||||
|
//query: select_query | delete_query | update_query
|
||||||
|
/datum/SDQL_parser/proc/query(i, list/node)
|
||||||
|
query_type = tokenl(i)
|
||||||
|
|
||||||
|
switch(query_type)
|
||||||
|
if("select")
|
||||||
|
select_query(i, node)
|
||||||
|
|
||||||
|
if("delete")
|
||||||
|
delete_query(i, node)
|
||||||
|
|
||||||
|
if("update")
|
||||||
|
update_query(i, node)
|
||||||
|
|
||||||
|
if("call")
|
||||||
|
call_query(i, node)
|
||||||
|
|
||||||
|
if("explain")
|
||||||
|
node += "explain"
|
||||||
|
node["explain"] = list()
|
||||||
|
query(i + 1, node["explain"])
|
||||||
|
|
||||||
|
|
||||||
|
// select_query: 'SELECT' object_selectors
|
||||||
|
/datum/SDQL_parser/proc/select_query(i, list/node)
|
||||||
|
var/list/select = list()
|
||||||
|
i = object_selectors(i + 1, select)
|
||||||
|
|
||||||
|
node["select"] = select
|
||||||
|
return i
|
||||||
|
|
||||||
|
|
||||||
|
//delete_query: 'DELETE' object_selectors
|
||||||
|
/datum/SDQL_parser/proc/delete_query(i, list/node)
|
||||||
|
var/list/select = list()
|
||||||
|
i = object_selectors(i + 1, select)
|
||||||
|
|
||||||
|
node["delete"] = select
|
||||||
|
|
||||||
|
return i
|
||||||
|
|
||||||
|
|
||||||
|
//update_query: 'UPDATE' object_selectors 'SET' assignments
|
||||||
|
/datum/SDQL_parser/proc/update_query(i, list/node)
|
||||||
|
var/list/select = list()
|
||||||
|
i = object_selectors(i + 1, select)
|
||||||
|
|
||||||
|
node["update"] = select
|
||||||
|
|
||||||
|
if(tokenl(i) != "set")
|
||||||
|
i = parse_error("UPDATE has misplaced SET")
|
||||||
|
|
||||||
|
var/list/set_assignments = list()
|
||||||
|
i = assignments(i + 1, set_assignments)
|
||||||
|
|
||||||
|
node["set"] = set_assignments
|
||||||
|
|
||||||
|
return i
|
||||||
|
|
||||||
|
|
||||||
|
//call_query: 'CALL' call_function ['ON' object_selectors]
|
||||||
|
/datum/SDQL_parser/proc/call_query(i, list/node)
|
||||||
|
var/list/func = list()
|
||||||
|
i = variable(i + 1, func) // Yes technically does anything variable() matches but I don't care, if admins fuck up this badly then they shouldn't be allowed near SDQL.
|
||||||
|
|
||||||
|
node["call"] = func
|
||||||
|
|
||||||
|
if(tokenl(i) != "on")
|
||||||
|
return parse_error("You need to specify what to call ON.")
|
||||||
|
|
||||||
|
var/list/select = list()
|
||||||
|
i = object_selectors(i + 1, select)
|
||||||
|
|
||||||
|
node["on"] = select
|
||||||
|
|
||||||
|
return i
|
||||||
|
|
||||||
|
// object_selectors: select_item [('FROM' | 'IN') from_item] [modifier_list]
|
||||||
|
/datum/SDQL_parser/proc/object_selectors(i, list/node)
|
||||||
|
i = select_item(i, node)
|
||||||
|
|
||||||
|
if (tokenl(i) == "from" || tokenl(i) == "in")
|
||||||
|
i++
|
||||||
|
var/list/from = list()
|
||||||
|
i = from_item(i, from)
|
||||||
|
node[++node.len] = from
|
||||||
|
|
||||||
|
else
|
||||||
|
node[++node.len] = list("world")
|
||||||
|
|
||||||
|
i = modifier_list(i, node)
|
||||||
|
return i
|
||||||
|
|
||||||
|
// modifier_list: ('WHERE' bool_expression | 'MAP' expression) [modifier_list]
|
||||||
|
/datum/SDQL_parser/proc/modifier_list(i, list/node)
|
||||||
|
while (TRUE)
|
||||||
|
if (tokenl(i) == "where")
|
||||||
|
i++
|
||||||
|
node += "where"
|
||||||
|
var/list/expr = list()
|
||||||
|
i = bool_expression(i, expr)
|
||||||
|
node[++node.len] = expr
|
||||||
|
|
||||||
|
else if (tokenl(i) == "map")
|
||||||
|
i++
|
||||||
|
node += "map"
|
||||||
|
var/list/expr = list()
|
||||||
|
i = expression(i, expr)
|
||||||
|
node[++node.len] = expr
|
||||||
|
|
||||||
|
else
|
||||||
|
return i
|
||||||
|
|
||||||
|
//select_list:select_item [',' select_list]
|
||||||
|
/datum/SDQL_parser/proc/select_list(i, list/node)
|
||||||
|
i = select_item(i, node)
|
||||||
|
|
||||||
|
if(token(i) == ",")
|
||||||
|
i = select_list(i + 1, node)
|
||||||
|
|
||||||
|
return i
|
||||||
|
|
||||||
|
//assignments: assignment, [',' assignments]
|
||||||
|
/datum/SDQL_parser/proc/assignments(i, list/node)
|
||||||
|
i = assignment(i, node)
|
||||||
|
|
||||||
|
if(token(i) == ",")
|
||||||
|
i = assignments(i + 1, node)
|
||||||
|
|
||||||
|
return i
|
||||||
|
|
||||||
|
|
||||||
|
//select_item: '*' | select_function | object_type
|
||||||
|
/datum/SDQL_parser/proc/select_item(i, list/node)
|
||||||
|
if (token(i) == "*")
|
||||||
|
node += "*"
|
||||||
|
i++
|
||||||
|
|
||||||
|
else if (copytext(token(i), 1, 2) == "/")
|
||||||
|
i = object_type(i, node)
|
||||||
|
|
||||||
|
else
|
||||||
|
i = parse_error("Expected '*' or type path for select item")
|
||||||
|
|
||||||
|
return i
|
||||||
|
|
||||||
|
// Standardized method for handling the IN/FROM and WHERE options.
|
||||||
|
/datum/SDQL_parser/proc/selectors(i, list/node)
|
||||||
|
while (token(i))
|
||||||
|
var/tok = tokenl(i)
|
||||||
|
if (tok in list("from", "in"))
|
||||||
|
var/list/from = list()
|
||||||
|
i = from_item(i + 1, from)
|
||||||
|
|
||||||
|
node["from"] = from
|
||||||
|
continue
|
||||||
|
|
||||||
|
if (tok == "where")
|
||||||
|
var/list/where = list()
|
||||||
|
i = bool_expression(i + 1, where)
|
||||||
|
|
||||||
|
node["where"] = where
|
||||||
|
continue
|
||||||
|
|
||||||
|
parse_error("Expected either FROM, IN or WHERE token, found [token(i)] instead.")
|
||||||
|
return i + 1
|
||||||
|
|
||||||
|
if (!node.Find("from"))
|
||||||
|
node["from"] = list("world")
|
||||||
|
|
||||||
|
return i
|
||||||
|
|
||||||
|
//from_item: 'world' | expression
|
||||||
|
/datum/SDQL_parser/proc/from_item(i, list/node)
|
||||||
|
if(token(i) == "world")
|
||||||
|
node += "world"
|
||||||
|
i++
|
||||||
|
|
||||||
|
else
|
||||||
|
i = expression(i, node)
|
||||||
|
|
||||||
|
return i
|
||||||
|
|
||||||
|
|
||||||
|
//bool_expression: expression [bool_operator bool_expression]
|
||||||
|
/datum/SDQL_parser/proc/bool_expression(i, list/node)
|
||||||
|
|
||||||
|
var/list/bool = list()
|
||||||
|
i = expression(i, bool)
|
||||||
|
|
||||||
|
node[++node.len] = bool
|
||||||
|
|
||||||
|
if(tokenl(i) in boolean_operators)
|
||||||
|
i = bool_operator(i, node)
|
||||||
|
i = bool_expression(i, node)
|
||||||
|
|
||||||
|
return i
|
||||||
|
|
||||||
|
|
||||||
|
//assignment: <variable name> '=' expression
|
||||||
|
/datum/SDQL_parser/proc/assignment(var/i, var/list/node, var/list/assignment_list = list())
|
||||||
|
assignment_list += token(i)
|
||||||
|
|
||||||
|
if(token(i + 1) == ".")
|
||||||
|
i = assignment(i + 2, node, assignment_list)
|
||||||
|
|
||||||
|
else if(token(i + 1) == "=")
|
||||||
|
var/exp_list = list()
|
||||||
|
node[assignment_list] = exp_list
|
||||||
|
|
||||||
|
i = expression(i + 2, exp_list)
|
||||||
|
|
||||||
|
else
|
||||||
|
parse_error("Assignment expected, but no = found")
|
||||||
|
|
||||||
|
return i
|
||||||
|
|
||||||
|
|
||||||
|
//variable: <variable name> | <variable name> '.' variable | '[' <hex number> ']' | '[' <hex number> ']' '.' variable
|
||||||
|
/datum/SDQL_parser/proc/variable(i, list/node)
|
||||||
|
var/list/L = list(token(i))
|
||||||
|
node[++node.len] = L
|
||||||
|
|
||||||
|
if(token(i) == "{")
|
||||||
|
L += token(i + 1)
|
||||||
|
i += 2
|
||||||
|
|
||||||
|
if(token(i) != "}")
|
||||||
|
parse_error("Missing } at end of pointer.")
|
||||||
|
|
||||||
|
if(token(i + 1) == ".")
|
||||||
|
L += "."
|
||||||
|
i = variable(i + 2, L)
|
||||||
|
|
||||||
|
else if (token(i + 1) == "(") // OH BOY PROC
|
||||||
|
var/list/arguments = list()
|
||||||
|
i = call_function(i, null, arguments)
|
||||||
|
L += ":"
|
||||||
|
L[++L.len] = arguments
|
||||||
|
|
||||||
|
else if (token(i + 1) == "\[")
|
||||||
|
var/list/expression = list()
|
||||||
|
i = expression(i + 2, expression)
|
||||||
|
if (token(i) != "]")
|
||||||
|
parse_error("Missing ] at the end of list access.")
|
||||||
|
|
||||||
|
L += "\["
|
||||||
|
L[++L.len] = expression
|
||||||
|
i++
|
||||||
|
|
||||||
|
else
|
||||||
|
i++
|
||||||
|
|
||||||
|
return i
|
||||||
|
|
||||||
|
|
||||||
|
//object_type: <type path>
|
||||||
|
/datum/SDQL_parser/proc/object_type(i, list/node)
|
||||||
|
|
||||||
|
if (copytext(token(i), 1, 2) != "/")
|
||||||
|
return parse_error("Expected type, but it didn't begin with /")
|
||||||
|
|
||||||
|
var/path = text2path(token(i))
|
||||||
|
if (path == null)
|
||||||
|
return parse_error("Nonexistant type path: [token(i)]")
|
||||||
|
|
||||||
|
node += path
|
||||||
|
|
||||||
|
return i + 1
|
||||||
|
|
||||||
|
|
||||||
|
//comparitor: '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>='
|
||||||
|
/datum/SDQL_parser/proc/comparitor(i, list/node)
|
||||||
|
|
||||||
|
if(token(i) in list("=", "==", "!=", "<>", "<", "<=", ">", ">="))
|
||||||
|
node += token(i)
|
||||||
|
|
||||||
|
else
|
||||||
|
parse_error("Unknown comparitor [token(i)]")
|
||||||
|
|
||||||
|
return i + 1
|
||||||
|
|
||||||
|
|
||||||
|
//bool_operator: 'AND' | '&&' | 'OR' | '||'
|
||||||
|
/datum/SDQL_parser/proc/bool_operator(i, list/node)
|
||||||
|
|
||||||
|
if(tokenl(i) in list("and", "or", "&&", "||"))
|
||||||
|
node += token(i)
|
||||||
|
|
||||||
|
else
|
||||||
|
parse_error("Unknown comparitor [token(i)]")
|
||||||
|
|
||||||
|
return i + 1
|
||||||
|
|
||||||
|
|
||||||
|
//string: ''' <some text> ''' | '"' <some text > '"'
|
||||||
|
/datum/SDQL_parser/proc/string(i, list/node)
|
||||||
|
|
||||||
|
if(copytext(token(i), 1, 2) in list("'", "\""))
|
||||||
|
node += token(i)
|
||||||
|
|
||||||
|
else
|
||||||
|
parse_error("Expected string but found '[token(i)]'")
|
||||||
|
|
||||||
|
return i + 1
|
||||||
|
|
||||||
|
//array: '[' expression, expression, ... ']'
|
||||||
|
/datum/SDQL_parser/proc/array(var/i, var/list/node)
|
||||||
|
// Arrays get turned into this: list("[", list(exp_1a = exp_1b, ...), ...), "[" is to mark the next node as an array.
|
||||||
|
if(copytext(token(i), 1, 2) != "\[")
|
||||||
|
parse_error("Expected an array but found '[token(i)]'")
|
||||||
|
return i + 1
|
||||||
|
|
||||||
|
node += token(i) // Add the "["
|
||||||
|
|
||||||
|
var/list/expression_list = list()
|
||||||
|
|
||||||
|
i++
|
||||||
|
if(token(i) != "]")
|
||||||
|
var/list/temp_expression_list = list()
|
||||||
|
var/tok
|
||||||
|
do
|
||||||
|
tok = token(i)
|
||||||
|
if (tok == "," || tok == ":")
|
||||||
|
if (temp_expression_list == null)
|
||||||
|
parse_error("Found ',' or ':' without expression in an array.")
|
||||||
|
return i + 1
|
||||||
|
|
||||||
|
expression_list[++expression_list.len] = temp_expression_list
|
||||||
|
temp_expression_list = null
|
||||||
|
if (tok == ":")
|
||||||
|
temp_expression_list = list()
|
||||||
|
i = expression(i + 1, temp_expression_list)
|
||||||
|
expression_list[expression_list[expression_list.len]] = temp_expression_list
|
||||||
|
temp_expression_list = null
|
||||||
|
tok = token(i)
|
||||||
|
if (tok != ",")
|
||||||
|
if (tok == "]")
|
||||||
|
break
|
||||||
|
|
||||||
|
parse_error("Expected ',' or ']' after array assoc value, but found '[token(i)]'")
|
||||||
|
return i
|
||||||
|
|
||||||
|
|
||||||
|
i++
|
||||||
|
continue
|
||||||
|
|
||||||
|
temp_expression_list = list()
|
||||||
|
i = expression(i, temp_expression_list)
|
||||||
|
|
||||||
|
// Ok, what the fuck BYOND?
|
||||||
|
// Not having these lines here causes the parser to die
|
||||||
|
// on an error saying that list/token() doesn't exist as a proc.
|
||||||
|
// These lines prevent that.
|
||||||
|
// I assume the compiler/VM is shitting itself and swapping out some variables internally?
|
||||||
|
// While throwing in debug logging it disappeared
|
||||||
|
// And these 3 lines prevent it from happening while being quiet.
|
||||||
|
// So.. it works.
|
||||||
|
// Don't touch it.
|
||||||
|
var/whatthefuck = i
|
||||||
|
whatthefuck = src.type
|
||||||
|
whatthefuck = whatthefuck
|
||||||
|
|
||||||
|
while(token(i) && token(i) != "]")
|
||||||
|
|
||||||
|
if (temp_expression_list)
|
||||||
|
expression_list[++expression_list.len] = temp_expression_list
|
||||||
|
|
||||||
|
node[++node.len] = expression_list
|
||||||
|
|
||||||
|
return i + 1
|
||||||
|
|
||||||
|
//call_function: <function name> ['(' [arguments] ')']
|
||||||
|
/datum/SDQL_parser/proc/call_function(i, list/node, list/arguments)
|
||||||
|
if(length(tokenl(i)))
|
||||||
|
var/procname = ""
|
||||||
|
if(tokenl(i) == "global" && token(i + 1) == ".") // Global proc.
|
||||||
|
i += 2
|
||||||
|
procname = "global."
|
||||||
|
node += procname + token(i++)
|
||||||
|
if(token(i) != "(")
|
||||||
|
parse_error("Expected ( but found '[token(i)]'")
|
||||||
|
|
||||||
|
else if(token(i + 1) != ")")
|
||||||
|
var/list/temp_expression_list = list()
|
||||||
|
do
|
||||||
|
i = expression(i + 1, temp_expression_list)
|
||||||
|
if(token(i) == ",")
|
||||||
|
arguments[++arguments.len] = temp_expression_list
|
||||||
|
temp_expression_list = list()
|
||||||
|
continue
|
||||||
|
|
||||||
|
while(token(i) && token(i) != ")")
|
||||||
|
|
||||||
|
arguments[++arguments.len] = temp_expression_list // The code this is copy pasted from won't be executed when it's the last param, this fixes that.
|
||||||
|
else
|
||||||
|
i++
|
||||||
|
else
|
||||||
|
parse_error("Expected a function but found nothing")
|
||||||
|
return i + 1
|
||||||
|
|
||||||
|
|
||||||
|
//expression: ( unary_expression | '(' expression ')' | value ) [binary_operator expression]
|
||||||
|
/datum/SDQL_parser/proc/expression(i, list/node)
|
||||||
|
|
||||||
|
if(token(i) in unary_operators)
|
||||||
|
i = unary_expression(i, node)
|
||||||
|
|
||||||
|
else if(token(i) == "(")
|
||||||
|
var/list/expr = list()
|
||||||
|
|
||||||
|
i = expression(i + 1, expr)
|
||||||
|
|
||||||
|
if(token(i) != ")")
|
||||||
|
parse_error("Missing ) at end of expression.")
|
||||||
|
|
||||||
|
else
|
||||||
|
i++
|
||||||
|
|
||||||
|
node[++node.len] = expr
|
||||||
|
|
||||||
|
else
|
||||||
|
i = value(i, node)
|
||||||
|
|
||||||
|
if(token(i) in binary_operators)
|
||||||
|
i = binary_operator(i, node)
|
||||||
|
i = expression(i, node)
|
||||||
|
|
||||||
|
else if(token(i) in comparitors)
|
||||||
|
i = binary_operator(i, node)
|
||||||
|
|
||||||
|
var/list/rhs = list()
|
||||||
|
i = expression(i, rhs)
|
||||||
|
|
||||||
|
node[++node.len] = rhs
|
||||||
|
|
||||||
|
|
||||||
|
return i
|
||||||
|
|
||||||
|
|
||||||
|
//unary_expression: unary_operator ( unary_expression | value | '(' expression ')' )
|
||||||
|
/datum/SDQL_parser/proc/unary_expression(i, list/node)
|
||||||
|
|
||||||
|
if(token(i) in unary_operators)
|
||||||
|
var/list/unary_exp = list()
|
||||||
|
|
||||||
|
unary_exp += token(i)
|
||||||
|
i++
|
||||||
|
|
||||||
|
if(token(i) in unary_operators)
|
||||||
|
i = unary_expression(i, unary_exp)
|
||||||
|
|
||||||
|
else if(token(i) == "(")
|
||||||
|
var/list/expr = list()
|
||||||
|
|
||||||
|
i = expression(i + 1, expr)
|
||||||
|
|
||||||
|
if(token(i) != ")")
|
||||||
|
parse_error("Missing ) at end of expression.")
|
||||||
|
|
||||||
|
else
|
||||||
|
i++
|
||||||
|
|
||||||
|
unary_exp[++unary_exp.len] = expr
|
||||||
|
|
||||||
|
else
|
||||||
|
i = value(i, unary_exp)
|
||||||
|
|
||||||
|
node[++node.len] = unary_exp
|
||||||
|
|
||||||
|
|
||||||
|
else
|
||||||
|
parse_error("Expected unary operator but found '[token(i)]'")
|
||||||
|
|
||||||
|
return i
|
||||||
|
|
||||||
|
|
||||||
|
//binary_operator: comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^' | '%'
|
||||||
|
/datum/SDQL_parser/proc/binary_operator(i, list/node)
|
||||||
|
|
||||||
|
if(token(i) in (binary_operators + comparitors))
|
||||||
|
node += token(i)
|
||||||
|
|
||||||
|
else
|
||||||
|
parse_error("Unknown binary operator [token(i)]")
|
||||||
|
|
||||||
|
return i + 1
|
||||||
|
|
||||||
|
|
||||||
|
//value: variable | string | number | 'null' | object_type
|
||||||
|
/datum/SDQL_parser/proc/value(i, list/node)
|
||||||
|
if(token(i) == "null")
|
||||||
|
node += "null"
|
||||||
|
i++
|
||||||
|
|
||||||
|
else if(lowertext(copytext(token(i), 1, 3)) == "0x" && isnum(hex2num(copytext(token(i), 3))))
|
||||||
|
node += hex2num(copytext(token(i), 3))
|
||||||
|
i++
|
||||||
|
|
||||||
|
else if(isnum(text2num(token(i))))
|
||||||
|
node += text2num(token(i))
|
||||||
|
i++
|
||||||
|
|
||||||
|
else if(copytext(token(i), 1, 2) in list("'", "\""))
|
||||||
|
i = string(i, node)
|
||||||
|
|
||||||
|
else if(copytext(token(i), 1, 2) == "\[") // Start a list.
|
||||||
|
i = array(i, node)
|
||||||
|
else if(copytext(token(i), 1, 2) == "/")
|
||||||
|
i = object_type(i, node)
|
||||||
|
else
|
||||||
|
i = variable(i, node)
|
||||||
|
|
||||||
|
return i
|
||||||
215
code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm
Normal file
215
code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
// Wrappers for BYOND default procs which can't directly be called by call().
|
||||||
|
|
||||||
|
/proc/_abs(A)
|
||||||
|
return abs(A)
|
||||||
|
|
||||||
|
/proc/_animate(atom/A, set_vars, time = 10, loop = 1, easing = LINEAR_EASING, flags = null)
|
||||||
|
var/mutable_appearance/MA = new()
|
||||||
|
for(var/v in set_vars)
|
||||||
|
MA.vars[v] = set_vars[v]
|
||||||
|
animate(A, appearance = MA, time, loop, easing, flags)
|
||||||
|
|
||||||
|
/proc/_acrccos(A)
|
||||||
|
return arccos(A)
|
||||||
|
|
||||||
|
/proc/_arcsin(A)
|
||||||
|
return arcsin(A)
|
||||||
|
|
||||||
|
/proc/_ascii2text(A)
|
||||||
|
return ascii2text(A)
|
||||||
|
|
||||||
|
/proc/_block(Start, End)
|
||||||
|
return block(Start, End)
|
||||||
|
|
||||||
|
/proc/_ckey(Key)
|
||||||
|
return ckey(Key)
|
||||||
|
|
||||||
|
/proc/_ckeyEx(Key)
|
||||||
|
return ckeyEx(Key)
|
||||||
|
|
||||||
|
/proc/_copytext(T, Start = 1, End = 0)
|
||||||
|
return copytext(T, Start, End)
|
||||||
|
|
||||||
|
/proc/_cos(X)
|
||||||
|
return cos(X)
|
||||||
|
|
||||||
|
/proc/_get_dir(Loc1, Loc2)
|
||||||
|
return get_dir(Loc1, Loc2)
|
||||||
|
|
||||||
|
/proc/_get_dist(Loc1, Loc2)
|
||||||
|
return get_dist(Loc1, Loc2)
|
||||||
|
|
||||||
|
/proc/_get_step(Ref, Dir)
|
||||||
|
return get_step(Ref, Dir)
|
||||||
|
|
||||||
|
/proc/_hearers(Depth = world.view, Center = usr)
|
||||||
|
return hearers(Depth, Center)
|
||||||
|
|
||||||
|
/proc/_image(icon, loc, icon_state, layer, dir)
|
||||||
|
return image(icon, loc, icon_state, layer, dir)
|
||||||
|
|
||||||
|
/proc/_istype(object, type)
|
||||||
|
return istype(object, type)
|
||||||
|
|
||||||
|
/proc/_ispath(path, type)
|
||||||
|
return ispath(path, type)
|
||||||
|
|
||||||
|
/proc/_length(E)
|
||||||
|
return length(E)
|
||||||
|
|
||||||
|
/proc/_link(thing, url)
|
||||||
|
thing << link(url)
|
||||||
|
|
||||||
|
/proc/_locate(X, Y, Z)
|
||||||
|
if (isnull(Y)) // Assuming that it's only a single-argument call.
|
||||||
|
return locate(X)
|
||||||
|
|
||||||
|
return locate(X, Y, Z)
|
||||||
|
|
||||||
|
/proc/_log(X, Y)
|
||||||
|
return log(X, Y)
|
||||||
|
|
||||||
|
/proc/_lowertext(T)
|
||||||
|
return lowertext(T)
|
||||||
|
|
||||||
|
/proc/_matrix(a, b, c, d, e, f)
|
||||||
|
return matrix(a, b, c, d, e, f)
|
||||||
|
|
||||||
|
/proc/_max(...)
|
||||||
|
return max(arglist(args))
|
||||||
|
|
||||||
|
/proc/_md5(T)
|
||||||
|
return md5(T)
|
||||||
|
|
||||||
|
/proc/_min(...)
|
||||||
|
return min(arglist(args))
|
||||||
|
|
||||||
|
/proc/_new(type, arguments)
|
||||||
|
return new type (arglist(arguments))
|
||||||
|
|
||||||
|
/proc/_num2text(N, SigFig = 6)
|
||||||
|
return num2text(N, SigFig)
|
||||||
|
|
||||||
|
/proc/_ohearers(Dist, Center = usr)
|
||||||
|
return ohearers(Dist, Center)
|
||||||
|
|
||||||
|
/proc/_orange(Dist, Center = usr)
|
||||||
|
return orange(Dist, Center)
|
||||||
|
|
||||||
|
/proc/_output(thing, msg, control)
|
||||||
|
thing << output(msg, control)
|
||||||
|
|
||||||
|
/proc/_oview(Dist, Center = usr)
|
||||||
|
return oview(Dist, Center)
|
||||||
|
|
||||||
|
/proc/_oviewers(Dist, Center = usr)
|
||||||
|
return oviewers(Dist, Center)
|
||||||
|
|
||||||
|
/proc/_params2list(Params)
|
||||||
|
return params2list(Params)
|
||||||
|
|
||||||
|
/proc/_pick(...)
|
||||||
|
return pick(arglist(args))
|
||||||
|
|
||||||
|
/proc/_prob(P)
|
||||||
|
return prob(P)
|
||||||
|
|
||||||
|
/proc/_rand(L = 0, H = 1)
|
||||||
|
return rand(L, H)
|
||||||
|
|
||||||
|
/proc/_range(Dist, Center = usr)
|
||||||
|
return range(Dist, Center)
|
||||||
|
|
||||||
|
/proc/_regex(pattern, flags)
|
||||||
|
return regex(pattern, flags)
|
||||||
|
|
||||||
|
/proc/_REGEX_QUOTE(text)
|
||||||
|
return REGEX_QUOTE(text)
|
||||||
|
|
||||||
|
/proc/_REGEX_QUOTE_REPLACEMENT(text)
|
||||||
|
return REGEX_QUOTE_REPLACEMENT(text)
|
||||||
|
|
||||||
|
/proc/_replacetext(Haystack, Needle, Replacement, Start = 1,End = 0)
|
||||||
|
return replacetext(Haystack, Needle, Replacement, Start, End)
|
||||||
|
|
||||||
|
/proc/_replacetextEx(Haystack, Needle, Replacement, Start = 1,End = 0)
|
||||||
|
return replacetextEx(Haystack, Needle, Replacement, Start, End)
|
||||||
|
|
||||||
|
/proc/_rgb(R, G, B)
|
||||||
|
return rgb(R, G, B)
|
||||||
|
|
||||||
|
/proc/_rgba(R, G, B, A)
|
||||||
|
return rgb(R, G, B, A)
|
||||||
|
|
||||||
|
/proc/_roll(dice)
|
||||||
|
return roll(dice)
|
||||||
|
|
||||||
|
/proc/_round(A, B = 1)
|
||||||
|
return round(A, B)
|
||||||
|
|
||||||
|
/proc/_sin(X)
|
||||||
|
return sin(X)
|
||||||
|
|
||||||
|
/proc/_list_add(list/L, ...)
|
||||||
|
if (args.len < 2)
|
||||||
|
return
|
||||||
|
L += args.Copy(2)
|
||||||
|
|
||||||
|
/proc/_list_copy(list/L, Start = 1, End = 0)
|
||||||
|
return L.Copy(Start, End)
|
||||||
|
|
||||||
|
/proc/_list_cut(list/L, Start = 1, End = 0)
|
||||||
|
L.Cut(Start, End)
|
||||||
|
|
||||||
|
/proc/_list_find(list/L, Elem, Start = 1, End = 0)
|
||||||
|
return L.Find(Elem, Start, End)
|
||||||
|
|
||||||
|
/proc/_list_insert(list/L, Index, Item)
|
||||||
|
return L.Insert(Index, Item)
|
||||||
|
|
||||||
|
/proc/_list_join(list/L, Glue, Start = 0, End = 1)
|
||||||
|
return L.Join(Glue, Start, End)
|
||||||
|
|
||||||
|
/proc/_list_remove(list/L, ...)
|
||||||
|
if (args.len < 2)
|
||||||
|
return
|
||||||
|
L -= args.Copy(2)
|
||||||
|
|
||||||
|
/proc/_list_set(list/L, key, value)
|
||||||
|
L[key] = value
|
||||||
|
|
||||||
|
/proc/_list_numerical_add(L, key, num)
|
||||||
|
L[key] += num
|
||||||
|
|
||||||
|
/proc/_list_swap(list/L, Index1, Index2)
|
||||||
|
L.Swap(Index1, Index2)
|
||||||
|
|
||||||
|
/proc/_walk(ref, dir, lag)
|
||||||
|
walk(ref, dir, lag)
|
||||||
|
|
||||||
|
/proc/_walk_towards(ref, trg, lag)
|
||||||
|
walk_towards(ref, trg, lag)
|
||||||
|
|
||||||
|
/proc/_walk_to(ref, trg, min, lag)
|
||||||
|
walk_to(ref, trg, min, lag)
|
||||||
|
|
||||||
|
/proc/_walk_away(ref, trg, max, lag)
|
||||||
|
walk_away(ref, trg, max, lag)
|
||||||
|
|
||||||
|
/proc/_walk_rand(ref, lag)
|
||||||
|
walk_rand(ref, lag)
|
||||||
|
|
||||||
|
/proc/_step(ref, dir)
|
||||||
|
step(ref, dir)
|
||||||
|
|
||||||
|
/proc/_step_rand(ref)
|
||||||
|
step_rand(ref)
|
||||||
|
|
||||||
|
/proc/_step_to(ref, trg, min)
|
||||||
|
step_to(ref, trg, min)
|
||||||
|
|
||||||
|
/proc/_step_towards(ref, trg)
|
||||||
|
step_towards(ref, trg)
|
||||||
|
|
||||||
|
/proc/_step_away(ref, trg, max)
|
||||||
|
step_away(ref, trg, max)
|
||||||
@@ -1,426 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
/client/proc/SDQL2_query(query_text as message)
|
|
||||||
set category = "Admin"
|
|
||||||
if(!check_rights(R_DEBUG)) //Shouldn't happen... but just to be safe.
|
|
||||||
message_admins("<font color='red'>ERROR: Non-admin [usr.key] attempted to execute a SDQL query!</font>")
|
|
||||||
log_admin("Non-admin [usr.key] attempted to execute a SDQL query!")
|
|
||||||
|
|
||||||
if(!query_text || length(query_text) < 1)
|
|
||||||
return
|
|
||||||
|
|
||||||
//world << query_text
|
|
||||||
|
|
||||||
var/list/query_list = SDQL2_tokenize(query_text)
|
|
||||||
|
|
||||||
if(!query_list || query_list.len < 1)
|
|
||||||
return
|
|
||||||
|
|
||||||
var/list/query_tree = SDQL_parse(query_list)
|
|
||||||
|
|
||||||
if(query_tree.len < 1)
|
|
||||||
return
|
|
||||||
|
|
||||||
var/list/from_objs = list()
|
|
||||||
var/list/select_types = list()
|
|
||||||
|
|
||||||
switch(query_tree[1])
|
|
||||||
if("explain")
|
|
||||||
SDQL_testout(query_tree["explain"])
|
|
||||||
return
|
|
||||||
|
|
||||||
if("call")
|
|
||||||
if("on" in query_tree)
|
|
||||||
select_types = query_tree["on"]
|
|
||||||
else
|
|
||||||
return
|
|
||||||
|
|
||||||
if("select", "delete", "update")
|
|
||||||
select_types = query_tree[query_tree[1]]
|
|
||||||
|
|
||||||
from_objs = SDQL_from_objs(query_tree["from"])
|
|
||||||
|
|
||||||
var/list/objs = list()
|
|
||||||
|
|
||||||
for(var/type in select_types)
|
|
||||||
var/char = copytext(type, 1, 2)
|
|
||||||
|
|
||||||
if(char == "/" || char == "*")
|
|
||||||
for(var/from in from_objs)
|
|
||||||
objs += SDQL_get_all(type, from)
|
|
||||||
|
|
||||||
else if(char == "'" || char == "\"")
|
|
||||||
objs += locate(copytext(type, 2, length(type)))
|
|
||||||
|
|
||||||
if("where" in query_tree)
|
|
||||||
var/objs_temp = objs
|
|
||||||
objs = list()
|
|
||||||
for(var/datum/d in objs_temp)
|
|
||||||
if(SDQL_expression(d, query_tree["where"]))
|
|
||||||
objs += d
|
|
||||||
|
|
||||||
//usr << "Query: [query_text]"
|
|
||||||
message_admins("[usr] executed SDQL query: \"[query_text]\".")
|
|
||||||
|
|
||||||
switch(query_tree[1])
|
|
||||||
if("delete")
|
|
||||||
for(var/datum/d in objs)
|
|
||||||
qdel(d)
|
|
||||||
|
|
||||||
if("select")
|
|
||||||
var/text = ""
|
|
||||||
for(var/datum/t in objs)
|
|
||||||
if(istype(t, /atom))
|
|
||||||
var/atom/a = t
|
|
||||||
|
|
||||||
if(a.x)
|
|
||||||
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t] at ([a.x], [a.y], [a.z])<br>"
|
|
||||||
|
|
||||||
else if(a.loc && a.loc.x)
|
|
||||||
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t] in [a.loc] at ([a.loc.x], [a.loc.y], [a.loc.z])<br>"
|
|
||||||
|
|
||||||
else
|
|
||||||
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t]<br>"
|
|
||||||
|
|
||||||
else
|
|
||||||
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t]<br>"
|
|
||||||
|
|
||||||
usr << browse(text, "window=SDQL-result")
|
|
||||||
|
|
||||||
if("update")
|
|
||||||
if("set" in query_tree)
|
|
||||||
var/list/set_list = query_tree["set"]
|
|
||||||
for(var/datum/d in objs)
|
|
||||||
var/list/vals = list()
|
|
||||||
for(var/v in set_list)
|
|
||||||
if(v in d.vars)
|
|
||||||
vals += v
|
|
||||||
vals[v] = SDQL_expression(d, set_list[v])
|
|
||||||
|
|
||||||
if(istype(d, /turf))
|
|
||||||
for(var/v in vals)
|
|
||||||
if(v == "x" || v == "y" || v == "z")
|
|
||||||
continue
|
|
||||||
|
|
||||||
d.vars[v] = vals[v]
|
|
||||||
|
|
||||||
else
|
|
||||||
for(var/v in vals)
|
|
||||||
d.vars[v] = vals[v]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/proc/SDQL_parse(list/query_list)
|
|
||||||
var/datum/SDQL_parser/parser = new(query_list)
|
|
||||||
var/list/query_tree = parser.parse()
|
|
||||||
|
|
||||||
qdel(parser)
|
|
||||||
|
|
||||||
return query_tree
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/proc/SDQL_testout(list/query_tree, indent = 0)
|
|
||||||
var/spaces = ""
|
|
||||||
for(var/s = 0, s < indent, s++)
|
|
||||||
spaces += " "
|
|
||||||
|
|
||||||
for(var/item in query_tree)
|
|
||||||
if(istype(item, /list))
|
|
||||||
world << "[spaces]("
|
|
||||||
SDQL_testout(item, indent + 1)
|
|
||||||
world << "[spaces])"
|
|
||||||
|
|
||||||
else
|
|
||||||
world << "[spaces][item]"
|
|
||||||
|
|
||||||
if(!isnum(item) && query_tree[item])
|
|
||||||
|
|
||||||
if(istype(query_tree[item], /list))
|
|
||||||
world << "[spaces] ("
|
|
||||||
SDQL_testout(query_tree[item], indent + 2)
|
|
||||||
world << "[spaces] )"
|
|
||||||
|
|
||||||
else
|
|
||||||
world << "[spaces] [query_tree[item]]"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/proc/SDQL_from_objs(list/tree)
|
|
||||||
if("world" in tree)
|
|
||||||
return list(world)
|
|
||||||
|
|
||||||
var/list/out = list()
|
|
||||||
|
|
||||||
for(var/type in tree)
|
|
||||||
var/char = copytext(type, 1, 2)
|
|
||||||
|
|
||||||
if(char == "/")
|
|
||||||
out += SDQL_get_all(type, world)
|
|
||||||
|
|
||||||
else if(char == "'" || char == "\"")
|
|
||||||
out += locate(copytext(type, 2, length(type)))
|
|
||||||
|
|
||||||
return out
|
|
||||||
|
|
||||||
|
|
||||||
/proc/SDQL_get_all(type, location)
|
|
||||||
var/list/out = list()
|
|
||||||
|
|
||||||
if(type == "*")
|
|
||||||
for(var/datum/d in location)
|
|
||||||
out += d
|
|
||||||
|
|
||||||
return out
|
|
||||||
|
|
||||||
type = text2path(type)
|
|
||||||
|
|
||||||
if(ispath(type, /mob))
|
|
||||||
for(var/mob/d in location)
|
|
||||||
if(istype(d, type))
|
|
||||||
out += d
|
|
||||||
|
|
||||||
else if(ispath(type, /turf))
|
|
||||||
for(var/turf/d in location)
|
|
||||||
if(istype(d, type))
|
|
||||||
out += d
|
|
||||||
|
|
||||||
else if(ispath(type, /obj))
|
|
||||||
for(var/obj/d in location)
|
|
||||||
if(istype(d, type))
|
|
||||||
out += d
|
|
||||||
|
|
||||||
else if(ispath(type, /area))
|
|
||||||
for(var/area/d in location)
|
|
||||||
if(istype(d, type))
|
|
||||||
out += d
|
|
||||||
|
|
||||||
else if(ispath(type, /atom))
|
|
||||||
for(var/atom/d in location)
|
|
||||||
if(istype(d, type))
|
|
||||||
out += d
|
|
||||||
|
|
||||||
else
|
|
||||||
for(var/datum/d in location)
|
|
||||||
if(istype(d, type))
|
|
||||||
out += d
|
|
||||||
|
|
||||||
return out
|
|
||||||
|
|
||||||
|
|
||||||
/proc/SDQL_expression(datum/object, list/expression, start = 1)
|
|
||||||
var/result = 0
|
|
||||||
var/val
|
|
||||||
|
|
||||||
for(var/i = start, i <= expression.len, i++)
|
|
||||||
var/op = ""
|
|
||||||
|
|
||||||
if(i > start)
|
|
||||||
op = expression[i]
|
|
||||||
i++
|
|
||||||
|
|
||||||
var/list/ret = SDQL_value(object, expression, i)
|
|
||||||
val = ret["val"]
|
|
||||||
i = ret["i"]
|
|
||||||
|
|
||||||
if(op != "")
|
|
||||||
switch(op)
|
|
||||||
if("+")
|
|
||||||
result += val
|
|
||||||
if("-")
|
|
||||||
result -= val
|
|
||||||
if("*")
|
|
||||||
result *= val
|
|
||||||
if("/")
|
|
||||||
result /= val
|
|
||||||
if("&")
|
|
||||||
result &= val
|
|
||||||
if("|")
|
|
||||||
result |= val
|
|
||||||
if("^")
|
|
||||||
result ^= val
|
|
||||||
if("=", "==")
|
|
||||||
result = (result == val)
|
|
||||||
if("!=", "<>")
|
|
||||||
result = (result != val)
|
|
||||||
if("<")
|
|
||||||
result = (result < val)
|
|
||||||
if("<=")
|
|
||||||
result = (result <= val)
|
|
||||||
if(">")
|
|
||||||
result = (result > val)
|
|
||||||
if(">=")
|
|
||||||
result = (result >= val)
|
|
||||||
if("and", "&&")
|
|
||||||
result = (result && val)
|
|
||||||
if("or", "||")
|
|
||||||
result = (result || val)
|
|
||||||
else
|
|
||||||
usr << "<font color='red'>SDQL2: Unknown op [op]</font>"
|
|
||||||
result = null
|
|
||||||
else
|
|
||||||
result = val
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
/proc/SDQL_value(datum/object, list/expression, start = 1)
|
|
||||||
var/i = start
|
|
||||||
var/val = null
|
|
||||||
|
|
||||||
if(i > expression.len)
|
|
||||||
return list("val" = null, "i" = i)
|
|
||||||
|
|
||||||
if(istype(expression[i], /list))
|
|
||||||
val = SDQL_expression(object, expression[i])
|
|
||||||
|
|
||||||
else if(expression[i] == "!")
|
|
||||||
var/list/ret = SDQL_value(object, expression, i + 1)
|
|
||||||
val = !ret["val"]
|
|
||||||
i = ret["i"]
|
|
||||||
|
|
||||||
else if(expression[i] == "~")
|
|
||||||
var/list/ret = SDQL_value(object, expression, i + 1)
|
|
||||||
val = ~ret["val"]
|
|
||||||
i = ret["i"]
|
|
||||||
|
|
||||||
else if(expression[i] == "-")
|
|
||||||
var/list/ret = SDQL_value(object, expression, i + 1)
|
|
||||||
val = -ret["val"]
|
|
||||||
i = ret["i"]
|
|
||||||
|
|
||||||
else if(expression[i] == "null")
|
|
||||||
val = null
|
|
||||||
|
|
||||||
else if(isnum(expression[i]))
|
|
||||||
val = expression[i]
|
|
||||||
|
|
||||||
else if(copytext(expression[i], 1, 2) in list("'", "\""))
|
|
||||||
val = copytext(expression[i], 2, length(expression[i]))
|
|
||||||
|
|
||||||
else
|
|
||||||
val = SDQL_var(object, expression, i)
|
|
||||||
i = expression.len
|
|
||||||
|
|
||||||
return list("val" = val, "i" = i)
|
|
||||||
|
|
||||||
/proc/SDQL_var(datum/object, list/expression, start = 1)
|
|
||||||
|
|
||||||
if(expression[start] in object.vars)
|
|
||||||
|
|
||||||
if(start < expression.len && expression[start + 1] == ".")
|
|
||||||
return SDQL_var(object.vars[expression[start]], expression[start + 2])
|
|
||||||
|
|
||||||
else
|
|
||||||
return object.vars[expression[start]]
|
|
||||||
|
|
||||||
else
|
|
||||||
return null
|
|
||||||
|
|
||||||
/proc/SDQL2_tokenize(query_text)
|
|
||||||
|
|
||||||
var/list/whitespace = list(" ", "\n", "\t")
|
|
||||||
var/list/single = list("(", ")", ",", "+", "-", ".")
|
|
||||||
var/list/multi = list(
|
|
||||||
"=" = list("", "="),
|
|
||||||
"<" = list("", "=", ">"),
|
|
||||||
">" = list("", "="),
|
|
||||||
"!" = list("", "="))
|
|
||||||
|
|
||||||
var/word = ""
|
|
||||||
var/list/query_list = list()
|
|
||||||
var/len = length(query_text)
|
|
||||||
|
|
||||||
for(var/i = 1, i <= len, i++)
|
|
||||||
var/char = copytext(query_text, i, i + 1)
|
|
||||||
|
|
||||||
if(char in whitespace)
|
|
||||||
if(word != "")
|
|
||||||
query_list += word
|
|
||||||
word = ""
|
|
||||||
|
|
||||||
else if(char in single)
|
|
||||||
if(word != "")
|
|
||||||
query_list += word
|
|
||||||
word = ""
|
|
||||||
|
|
||||||
query_list += char
|
|
||||||
|
|
||||||
else if(char in multi)
|
|
||||||
if(word != "")
|
|
||||||
query_list += word
|
|
||||||
word = ""
|
|
||||||
|
|
||||||
var/char2 = copytext(query_text, i + 1, i + 2)
|
|
||||||
|
|
||||||
if(char2 in multi[char])
|
|
||||||
query_list += "[char][char2]"
|
|
||||||
i++
|
|
||||||
|
|
||||||
else
|
|
||||||
query_list += char
|
|
||||||
|
|
||||||
else if(char == "'")
|
|
||||||
if(word != "")
|
|
||||||
usr << "<font color='red'>SDQL2: You have an error in your SDQL syntax, unexpected ' in query: \"<font color=gray>[query_text]</font>\" following \"<font color=gray>[word]</font>\". Please check your syntax, and try again.</font>"
|
|
||||||
return null
|
|
||||||
|
|
||||||
word = "'"
|
|
||||||
|
|
||||||
for(i++, i <= len, i++)
|
|
||||||
char = copytext(query_text, i, i + 1)
|
|
||||||
|
|
||||||
if(char == "'")
|
|
||||||
if(copytext(query_text, i + 1, i + 2) == "'")
|
|
||||||
word += "'"
|
|
||||||
i++
|
|
||||||
|
|
||||||
else
|
|
||||||
break
|
|
||||||
|
|
||||||
else
|
|
||||||
word += char
|
|
||||||
|
|
||||||
if(i > len)
|
|
||||||
usr << "<font color='red'>SDQL2: You have an error in your SDQL syntax, unmatched ' in query: \"<font color=gray>[query_text]</font>\". Please check your syntax, and try again.</font>"
|
|
||||||
return null
|
|
||||||
|
|
||||||
query_list += "[word]'"
|
|
||||||
word = ""
|
|
||||||
|
|
||||||
else if(char == "\"")
|
|
||||||
if(word != "")
|
|
||||||
usr << "<font color='red'>SDQL2: You have an error in your SDQL syntax, unexpected \" in query: \"<font color=gray>[query_text]</font>\" following \"<font color=gray>[word]</font>\". Please check your syntax, and try again.</font>"
|
|
||||||
return null
|
|
||||||
|
|
||||||
word = "\""
|
|
||||||
|
|
||||||
for(i++, i <= len, i++)
|
|
||||||
char = copytext(query_text, i, i + 1)
|
|
||||||
|
|
||||||
if(char == "\"")
|
|
||||||
if(copytext(query_text, i + 1, i + 2) == "'")
|
|
||||||
word += "\""
|
|
||||||
i++
|
|
||||||
|
|
||||||
else
|
|
||||||
break
|
|
||||||
|
|
||||||
else
|
|
||||||
word += char
|
|
||||||
|
|
||||||
if(i > len)
|
|
||||||
usr << "<font color='red'>SDQL2: You have an error in your SDQL syntax, unmatched \" in query: \"<font color=gray>[query_text]</font>\". Please check your syntax, and try again.</font>"
|
|
||||||
return null
|
|
||||||
|
|
||||||
query_list += "[word]\""
|
|
||||||
word = ""
|
|
||||||
|
|
||||||
else
|
|
||||||
word += char
|
|
||||||
|
|
||||||
if(word != "")
|
|
||||||
query_list += word
|
|
||||||
|
|
||||||
return query_list
|
|
||||||
@@ -1,531 +0,0 @@
|
|||||||
//I'm pretty sure that this is a recursive [s]descent[/s] ascent parser.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Spec
|
|
||||||
|
|
||||||
//////////
|
|
||||||
//
|
|
||||||
// query : select_query | delete_query | update_query | call_query | explain
|
|
||||||
// explain : 'EXPLAIN' query
|
|
||||||
//
|
|
||||||
// select_query : 'SELECT' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]
|
|
||||||
// delete_query : 'DELETE' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]
|
|
||||||
// update_query : 'UPDATE' select_list [('FROM' | 'IN') from_list] 'SET' assignments ['WHERE' bool_expression]
|
|
||||||
// call_query : 'CALL' call_function ['ON' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]]
|
|
||||||
//
|
|
||||||
// select_list : select_item [',' select_list]
|
|
||||||
// select_item : '*' | select_function | object_type
|
|
||||||
// select_function : count_function
|
|
||||||
// count_function : 'COUNT' '(' '*' ')' | 'COUNT' '(' object_types ')'
|
|
||||||
//
|
|
||||||
// from_list : from_item [',' from_list]
|
|
||||||
// from_item : 'world' | object_type
|
|
||||||
//
|
|
||||||
// call_function : <function name> ['(' [arguments] ')']
|
|
||||||
// arguments : expression [',' arguments]
|
|
||||||
//
|
|
||||||
// object_type : <type path> | string
|
|
||||||
//
|
|
||||||
// assignments : assignment, [',' assignments]
|
|
||||||
// assignment : <variable name> '=' expression
|
|
||||||
// variable : <variable name> | <variable name> '.' variable
|
|
||||||
//
|
|
||||||
// bool_expression : expression comparitor expression [bool_operator bool_expression]
|
|
||||||
// expression : ( unary_expression | '(' expression ')' | value ) [binary_operator expression]
|
|
||||||
// unary_expression : unary_operator ( unary_expression | value | '(' expression ')' )
|
|
||||||
// comparitor : '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>='
|
|
||||||
// value : variable | string | number | 'null'
|
|
||||||
// unary_operator : '!' | '-' | '~'
|
|
||||||
// binary_operator : comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^'
|
|
||||||
// bool_operator : 'AND' | '&&' | 'OR' | '||'
|
|
||||||
//
|
|
||||||
// string : ''' <some text> ''' | '"' <some text > '"'
|
|
||||||
// number : <some digits>
|
|
||||||
//
|
|
||||||
//////////
|
|
||||||
|
|
||||||
/datum/SDQL_parser
|
|
||||||
var/query_type
|
|
||||||
var/error = 0
|
|
||||||
|
|
||||||
var/list/query
|
|
||||||
var/list/tree
|
|
||||||
|
|
||||||
var/list/select_functions = list("count")
|
|
||||||
var/list/boolean_operators = list("and", "or", "&&", "||")
|
|
||||||
var/list/unary_operators = list("!", "-", "~")
|
|
||||||
var/list/binary_operators = list("+", "-", "/", "*", "&", "|", "^")
|
|
||||||
var/list/comparitors = list("=", "==", "!=", "<>", "<", "<=", ">", ">=")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/datum/SDQL_parser/New(query_list)
|
|
||||||
query = query_list
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/datum/SDQL_parser/proc/parse_error(error_message)
|
|
||||||
error = 1
|
|
||||||
usr << "<font color='red'>SQDL2 Parsing Error: [error_message]</font>"
|
|
||||||
return query.len + 1
|
|
||||||
|
|
||||||
/datum/SDQL_parser/proc/parse()
|
|
||||||
tree = list()
|
|
||||||
query(1, tree)
|
|
||||||
|
|
||||||
if(error)
|
|
||||||
return list()
|
|
||||||
else
|
|
||||||
return tree
|
|
||||||
|
|
||||||
/datum/SDQL_parser/proc/token(i)
|
|
||||||
if(i <= query.len)
|
|
||||||
return query[i]
|
|
||||||
|
|
||||||
else
|
|
||||||
return null
|
|
||||||
|
|
||||||
/datum/SDQL_parser/proc/tokens(i, num)
|
|
||||||
if(i + num <= query.len)
|
|
||||||
return query.Copy(i, i + num)
|
|
||||||
|
|
||||||
else
|
|
||||||
return null
|
|
||||||
|
|
||||||
/datum/SDQL_parser/proc/tokenl(i)
|
|
||||||
return lowertext(token(i))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/datum/SDQL_parser/proc
|
|
||||||
|
|
||||||
//query: select_query | delete_query | update_query
|
|
||||||
query(i, list/node)
|
|
||||||
query_type = tokenl(i)
|
|
||||||
|
|
||||||
switch(query_type)
|
|
||||||
if("select")
|
|
||||||
select_query(i, node)
|
|
||||||
|
|
||||||
if("delete")
|
|
||||||
delete_query(i, node)
|
|
||||||
|
|
||||||
if("update")
|
|
||||||
update_query(i, node)
|
|
||||||
|
|
||||||
if("call")
|
|
||||||
call_query(i, node)
|
|
||||||
|
|
||||||
if("explain")
|
|
||||||
node += "explain"
|
|
||||||
node["explain"] = list()
|
|
||||||
query(i + 1, node["explain"])
|
|
||||||
|
|
||||||
|
|
||||||
// select_query: 'SELECT' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]
|
|
||||||
select_query(i, list/node)
|
|
||||||
var/list/select = list()
|
|
||||||
i = select_list(i + 1, select)
|
|
||||||
|
|
||||||
node += "select"
|
|
||||||
node["select"] = select
|
|
||||||
|
|
||||||
var/list/from = list()
|
|
||||||
if(tokenl(i) in list("from", "in"))
|
|
||||||
i = from_list(i + 1, from)
|
|
||||||
else
|
|
||||||
from += "world"
|
|
||||||
|
|
||||||
node += "from"
|
|
||||||
node["from"] = from
|
|
||||||
|
|
||||||
if(tokenl(i) == "where")
|
|
||||||
var/list/where = list()
|
|
||||||
i = bool_expression(i + 1, where)
|
|
||||||
|
|
||||||
node += "where"
|
|
||||||
node["where"] = where
|
|
||||||
|
|
||||||
return i
|
|
||||||
|
|
||||||
|
|
||||||
//delete_query: 'DELETE' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]
|
|
||||||
delete_query(i, list/node)
|
|
||||||
var/list/select = list()
|
|
||||||
i = select_list(i + 1, select)
|
|
||||||
|
|
||||||
node += "delete"
|
|
||||||
node["delete"] = select
|
|
||||||
|
|
||||||
var/list/from = list()
|
|
||||||
if(tokenl(i) in list("from", "in"))
|
|
||||||
i = from_list(i + 1, from)
|
|
||||||
else
|
|
||||||
from += "world"
|
|
||||||
|
|
||||||
node += "from"
|
|
||||||
node["from"] = from
|
|
||||||
|
|
||||||
if(tokenl(i) == "where")
|
|
||||||
var/list/where = list()
|
|
||||||
i = bool_expression(i + 1, where)
|
|
||||||
|
|
||||||
node += "where"
|
|
||||||
node["where"] = where
|
|
||||||
|
|
||||||
return i
|
|
||||||
|
|
||||||
|
|
||||||
//update_query: 'UPDATE' select_list [('FROM' | 'IN') from_list] 'SET' assignments ['WHERE' bool_expression]
|
|
||||||
update_query(i, list/node)
|
|
||||||
var/list/select = list()
|
|
||||||
i = select_list(i + 1, select)
|
|
||||||
|
|
||||||
node += "update"
|
|
||||||
node["update"] = select
|
|
||||||
|
|
||||||
var/list/from = list()
|
|
||||||
if(tokenl(i) in list("from", "in"))
|
|
||||||
i = from_list(i + 1, from)
|
|
||||||
else
|
|
||||||
from += "world"
|
|
||||||
|
|
||||||
node += "from"
|
|
||||||
node["from"] = from
|
|
||||||
|
|
||||||
if(tokenl(i) != "set")
|
|
||||||
i = parse_error("UPDATE has misplaced SET")
|
|
||||||
|
|
||||||
var/list/set_assignments = list()
|
|
||||||
i = assignments(i + 1, set_assignments)
|
|
||||||
|
|
||||||
node += "set"
|
|
||||||
node["set"] = set_assignments
|
|
||||||
|
|
||||||
if(tokenl(i) == "where")
|
|
||||||
var/list/where = list()
|
|
||||||
i = bool_expression(i + 1, where)
|
|
||||||
|
|
||||||
node += "where"
|
|
||||||
node["where"] = where
|
|
||||||
|
|
||||||
return i
|
|
||||||
|
|
||||||
|
|
||||||
//call_query: 'CALL' call_function ['ON' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]]
|
|
||||||
call_query(i, list/node)
|
|
||||||
var/list/func = list()
|
|
||||||
i = call_function(i + 1, func)
|
|
||||||
|
|
||||||
node += "call"
|
|
||||||
node["call"] = func
|
|
||||||
|
|
||||||
if(tokenl(i) != "on")
|
|
||||||
return i
|
|
||||||
|
|
||||||
var/list/select = list()
|
|
||||||
i = select_list(i + 1, select)
|
|
||||||
|
|
||||||
node += "on"
|
|
||||||
node["on"] = select
|
|
||||||
|
|
||||||
var/list/from = list()
|
|
||||||
if(tokenl(i) in list("from", "in"))
|
|
||||||
i = from_list(i + 1, from)
|
|
||||||
else
|
|
||||||
from += "world"
|
|
||||||
|
|
||||||
node += "from"
|
|
||||||
node["from"] = from
|
|
||||||
|
|
||||||
if(tokenl(i) == "where")
|
|
||||||
var/list/where = list()
|
|
||||||
i = bool_expression(i + 1, where)
|
|
||||||
|
|
||||||
node += "where"
|
|
||||||
node["where"] = where
|
|
||||||
|
|
||||||
return i
|
|
||||||
|
|
||||||
|
|
||||||
//select_list: select_item [',' select_list]
|
|
||||||
select_list(i, list/node)
|
|
||||||
i = select_item(i, node)
|
|
||||||
|
|
||||||
if(token(i) == ",")
|
|
||||||
i = select_list(i + 1, node)
|
|
||||||
|
|
||||||
return i
|
|
||||||
|
|
||||||
|
|
||||||
//from_list: from_item [',' from_list]
|
|
||||||
from_list(i, list/node)
|
|
||||||
i = from_item(i, node)
|
|
||||||
|
|
||||||
if(token(i) == ",")
|
|
||||||
i = from_list(i + 1, node)
|
|
||||||
|
|
||||||
return i
|
|
||||||
|
|
||||||
|
|
||||||
//assignments: assignment, [',' assignments]
|
|
||||||
assignments(i, list/node)
|
|
||||||
i = assignment(i, node)
|
|
||||||
|
|
||||||
if(token(i) == ",")
|
|
||||||
i = assignments(i + 1, node)
|
|
||||||
|
|
||||||
return i
|
|
||||||
|
|
||||||
|
|
||||||
//select_item: '*' | select_function | object_type
|
|
||||||
select_item(i, list/node)
|
|
||||||
|
|
||||||
if(token(i) == "*")
|
|
||||||
node += "*"
|
|
||||||
i++
|
|
||||||
|
|
||||||
else if(tokenl(i) in select_functions)
|
|
||||||
i = select_function(i, node)
|
|
||||||
|
|
||||||
else
|
|
||||||
i = object_type(i, node)
|
|
||||||
|
|
||||||
return i
|
|
||||||
|
|
||||||
|
|
||||||
//from_item: 'world' | object_type
|
|
||||||
from_item(i, list/node)
|
|
||||||
|
|
||||||
if(token(i) == "world")
|
|
||||||
node += "world"
|
|
||||||
i++
|
|
||||||
|
|
||||||
else
|
|
||||||
i = object_type(i, node)
|
|
||||||
|
|
||||||
return i
|
|
||||||
|
|
||||||
|
|
||||||
//bool_expression: expression [bool_operator bool_expression]
|
|
||||||
bool_expression(i, list/node)
|
|
||||||
|
|
||||||
var/list/bool = list()
|
|
||||||
i = expression(i, bool)
|
|
||||||
|
|
||||||
node[++node.len] = bool
|
|
||||||
|
|
||||||
if(tokenl(i) in boolean_operators)
|
|
||||||
i = bool_operator(i, node)
|
|
||||||
i = bool_expression(i, node)
|
|
||||||
|
|
||||||
return i
|
|
||||||
|
|
||||||
|
|
||||||
//assignment: <variable name> '=' expression
|
|
||||||
assignment(i, list/node)
|
|
||||||
|
|
||||||
node += token(i)
|
|
||||||
|
|
||||||
if(token(i + 1) == "=")
|
|
||||||
var/varname = token(i)
|
|
||||||
node[varname] = list()
|
|
||||||
|
|
||||||
i = expression(i + 2, node[varname])
|
|
||||||
|
|
||||||
else
|
|
||||||
parse_error("Assignment expected, but no = found")
|
|
||||||
|
|
||||||
return i
|
|
||||||
|
|
||||||
|
|
||||||
//variable: <variable name> | <variable name> '.' variable
|
|
||||||
variable(i, list/node)
|
|
||||||
var/list/L = list(token(i))
|
|
||||||
node[++node.len] = L
|
|
||||||
|
|
||||||
if(token(i + 1) == ".")
|
|
||||||
L += "."
|
|
||||||
i = variable(i + 2, L)
|
|
||||||
|
|
||||||
else
|
|
||||||
i++
|
|
||||||
|
|
||||||
return i
|
|
||||||
|
|
||||||
|
|
||||||
//object_type: <type path> | string
|
|
||||||
object_type(i, list/node)
|
|
||||||
|
|
||||||
if(copytext(token(i), 1, 2) == "/")
|
|
||||||
node += token(i)
|
|
||||||
|
|
||||||
else
|
|
||||||
i = string(i, node)
|
|
||||||
|
|
||||||
return i + 1
|
|
||||||
|
|
||||||
|
|
||||||
//comparitor: '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>='
|
|
||||||
comparitor(i, list/node)
|
|
||||||
|
|
||||||
if(token(i) in list("=", "==", "!=", "<>", "<", "<=", ">", ">="))
|
|
||||||
node += token(i)
|
|
||||||
|
|
||||||
else
|
|
||||||
parse_error("Unknown comparitor [token(i)]")
|
|
||||||
|
|
||||||
return i + 1
|
|
||||||
|
|
||||||
|
|
||||||
//bool_operator: 'AND' | '&&' | 'OR' | '||'
|
|
||||||
bool_operator(i, list/node)
|
|
||||||
|
|
||||||
if(tokenl(i) in list("and", "or", "&&", "||"))
|
|
||||||
node += token(i)
|
|
||||||
|
|
||||||
else
|
|
||||||
parse_error("Unknown comparitor [token(i)]")
|
|
||||||
|
|
||||||
return i + 1
|
|
||||||
|
|
||||||
|
|
||||||
//string: ''' <some text> ''' | '"' <some text > '"'
|
|
||||||
string(i, list/node)
|
|
||||||
|
|
||||||
if(copytext(token(i), 1, 2) in list("'", "\""))
|
|
||||||
node += token(i)
|
|
||||||
|
|
||||||
else
|
|
||||||
parse_error("Expected string but found '[token(i)]'")
|
|
||||||
|
|
||||||
return i + 1
|
|
||||||
|
|
||||||
|
|
||||||
//call_function: <function name> ['(' [arguments] ')']
|
|
||||||
call_function(i, list/node)
|
|
||||||
|
|
||||||
parse_error("Sorry, function calls aren't available yet")
|
|
||||||
|
|
||||||
return i
|
|
||||||
|
|
||||||
|
|
||||||
//select_function: count_function
|
|
||||||
select_function(i, list/node)
|
|
||||||
|
|
||||||
parse_error("Sorry, function calls aren't available yet")
|
|
||||||
|
|
||||||
return i
|
|
||||||
|
|
||||||
|
|
||||||
//expression: ( unary_expression | '(' expression ')' | value ) [binary_operator expression]
|
|
||||||
expression(i, list/node)
|
|
||||||
|
|
||||||
if(token(i) in unary_operators)
|
|
||||||
i = unary_expression(i, node)
|
|
||||||
|
|
||||||
else if(token(i) == "(")
|
|
||||||
var/list/expr = list()
|
|
||||||
|
|
||||||
i = expression(i + 1, expr)
|
|
||||||
|
|
||||||
if(token(i) != ")")
|
|
||||||
parse_error("Missing ) at end of expression.")
|
|
||||||
|
|
||||||
else
|
|
||||||
i++
|
|
||||||
|
|
||||||
node[++node.len] = expr
|
|
||||||
|
|
||||||
else
|
|
||||||
i = value(i, node)
|
|
||||||
|
|
||||||
if(token(i) in binary_operators)
|
|
||||||
i = binary_operator(i, node)
|
|
||||||
i = expression(i, node)
|
|
||||||
|
|
||||||
else if(token(i) in comparitors)
|
|
||||||
i = binary_operator(i, node)
|
|
||||||
|
|
||||||
var/list/rhs = list()
|
|
||||||
i = expression(i, rhs)
|
|
||||||
|
|
||||||
node[++node.len] = rhs
|
|
||||||
|
|
||||||
|
|
||||||
return i
|
|
||||||
|
|
||||||
|
|
||||||
//unary_expression: unary_operator ( unary_expression | value | '(' expression ')' )
|
|
||||||
unary_expression(i, list/node)
|
|
||||||
|
|
||||||
if(token(i) in unary_operators)
|
|
||||||
var/list/unary_exp = list()
|
|
||||||
|
|
||||||
unary_exp += token(i)
|
|
||||||
i++
|
|
||||||
|
|
||||||
if(token(i) in unary_operators)
|
|
||||||
i = unary_expression(i, unary_exp)
|
|
||||||
|
|
||||||
else if(token(i) == "(")
|
|
||||||
var/list/expr = list()
|
|
||||||
|
|
||||||
i = expression(i + 1, expr)
|
|
||||||
|
|
||||||
if(token(i) != ")")
|
|
||||||
parse_error("Missing ) at end of expression.")
|
|
||||||
|
|
||||||
else
|
|
||||||
i++
|
|
||||||
|
|
||||||
unary_exp[++unary_exp.len] = expr
|
|
||||||
|
|
||||||
else
|
|
||||||
i = value(i, unary_exp)
|
|
||||||
|
|
||||||
node[++node.len] = unary_exp
|
|
||||||
|
|
||||||
|
|
||||||
else
|
|
||||||
parse_error("Expected unary operator but found '[token(i)]'")
|
|
||||||
|
|
||||||
return i
|
|
||||||
|
|
||||||
|
|
||||||
//binary_operator: comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^'
|
|
||||||
binary_operator(i, list/node)
|
|
||||||
|
|
||||||
if(token(i) in (binary_operators + comparitors))
|
|
||||||
node += token(i)
|
|
||||||
|
|
||||||
else
|
|
||||||
parse_error("Unknown binary operator [token(i)]")
|
|
||||||
|
|
||||||
return i + 1
|
|
||||||
|
|
||||||
|
|
||||||
//value: variable | string | number | 'null'
|
|
||||||
value(i, list/node)
|
|
||||||
|
|
||||||
if(token(i) == "null")
|
|
||||||
node += "null"
|
|
||||||
i++
|
|
||||||
|
|
||||||
else if(isnum(text2num(token(i))))
|
|
||||||
node += text2num(token(i))
|
|
||||||
i++
|
|
||||||
|
|
||||||
else if(copytext(token(i), 1, 2) in list("'", "\""))
|
|
||||||
i = string(i, node)
|
|
||||||
|
|
||||||
else
|
|
||||||
i = variable(i, node)
|
|
||||||
|
|
||||||
return i
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*EXPLAIN SELECT * WHERE 42 = 6 * 9 OR val = - 5 == 7*/
|
|
||||||
@@ -592,7 +592,7 @@
|
|||||||
if("Dead Mobs")
|
if("Dead Mobs")
|
||||||
usr << jointext(dead_mob_list,",")
|
usr << jointext(dead_mob_list,",")
|
||||||
if("Clients")
|
if("Clients")
|
||||||
usr << jointext(clients,",")
|
usr << jointext(GLOB.clients,",")
|
||||||
|
|
||||||
/client/proc/cmd_debug_using_map()
|
/client/proc/cmd_debug_using_map()
|
||||||
set category = "Debug"
|
set category = "Debug"
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
src << "<font color='red'>Only Admins may use this command.</font>"
|
src << "<font color='red'>Only Admins may use this command.</font>"
|
||||||
return
|
return
|
||||||
|
|
||||||
var/client/target = input(src,"Choose somebody to grant access to the server's runtime logs (permissions expire at the end of each round):","Grant Permissions",null) as null|anything in clients
|
var/client/target = input(src,"Choose somebody to grant access to the server's runtime logs (permissions expire at the end of each round):","Grant Permissions",null) as null|anything in GLOB.clients
|
||||||
if(!istype(target,/client))
|
if(!istype(target,/client))
|
||||||
src << "<font color='red'>Error: giveruntimelog(): Client not found.</font>"
|
src << "<font color='red'>Error: giveruntimelog(): Client not found.</font>"
|
||||||
return
|
return
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
set category = "Admin"
|
set category = "Admin"
|
||||||
set name = "Show Server Attack Log"
|
set name = "Show Server Attack Log"
|
||||||
set desc = "Shows today's server attack log."
|
set desc = "Shows today's server attack log."
|
||||||
|
|
||||||
to_chat(usr,"This verb doesn't actually do anything.")
|
to_chat(usr,"This verb doesn't actually do anything.")
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -113,4 +113,3 @@
|
|||||||
feedback_add_details("admin_verb","SSAL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
feedback_add_details("admin_verb","SSAL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||||
return
|
return
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
|
|
||||||
var/highlight_special_characters = 1
|
var/highlight_special_characters = 1
|
||||||
|
|
||||||
for(var/client/C in clients)
|
for(var/client/C in GLOB.clients)
|
||||||
if(C.player_age == "Requires database")
|
if(C.player_age == "Requires database")
|
||||||
missing_ages = 1
|
missing_ages = 1
|
||||||
continue
|
continue
|
||||||
@@ -363,7 +363,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
|||||||
return
|
return
|
||||||
|
|
||||||
//I frontload all the questions so we don't have a half-done process while you're reading.
|
//I frontload all the questions so we don't have a half-done process while you're reading.
|
||||||
var/client/picked_client = input(src, "Please specify which client's character to spawn.", "Client", "") as null|anything in clients
|
var/client/picked_client = input(src, "Please specify which client's character to spawn.", "Client", "") as null|anything in GLOB.clients
|
||||||
if(!picked_client)
|
if(!picked_client)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
//Admin PM
|
//Admin PM
|
||||||
if(href_list["priv_msg"])
|
if(href_list["priv_msg"])
|
||||||
var/client/C = locate(href_list["priv_msg"])
|
var/client/C = locate(href_list["priv_msg"])
|
||||||
if(ismob(C)) //Old stuff can feed-in mobs instead of clients
|
if(ismob(C)) //Old stuff can feed-in mobs instead ofGLOB.clients
|
||||||
var/mob/M = C
|
var/mob/M = C
|
||||||
C = M.client
|
C = M.client
|
||||||
cmd_admin_pm(C,null)
|
cmd_admin_pm(C,null)
|
||||||
@@ -108,8 +108,8 @@
|
|||||||
src << "<font color='red'>If the title screen is black, resources are still downloading. Please be patient until the title screen appears.</font>"
|
src << "<font color='red'>If the title screen is black, resources are still downloading. Please be patient until the title screen appears.</font>"
|
||||||
|
|
||||||
|
|
||||||
clients += src
|
GLOB.clients += src
|
||||||
directory[ckey] = src
|
GLOB.directory[ckey] = src
|
||||||
|
|
||||||
GLOB.ahelp_tickets.ClientLogin(src)
|
GLOB.ahelp_tickets.ClientLogin(src)
|
||||||
|
|
||||||
@@ -181,8 +181,8 @@
|
|||||||
holder.owner = null
|
holder.owner = null
|
||||||
admins -= src
|
admins -= src
|
||||||
GLOB.ahelp_tickets.ClientLogout(src)
|
GLOB.ahelp_tickets.ClientLogout(src)
|
||||||
directory -= ckey
|
GLOB.directory -= ckey
|
||||||
clients -= src
|
GLOB.clients -= src
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
/client/Destroy()
|
/client/Destroy()
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
return
|
return
|
||||||
|
|
||||||
if(!pai_key)
|
if(!pai_key)
|
||||||
var/client/C = input("Select client") as null|anything in clients
|
var/client/C = input("Select client") as null|anything in GLOB.clients
|
||||||
if(!C) return
|
if(!C) return
|
||||||
pai_key = C.key
|
pai_key = C.key
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/mob/Destroy()//This makes sure that mobs with clients/keys are not just deleted from the game.
|
/mob/Destroy()//This makes sure that mobs withGLOB.clients/keys are not just deleted from the game.
|
||||||
mob_list -= src
|
mob_list -= src
|
||||||
dead_mob_list -= src
|
dead_mob_list -= src
|
||||||
living_mob_list -= src
|
living_mob_list -= src
|
||||||
@@ -695,6 +695,10 @@
|
|||||||
stat("World Time:", world.time)
|
stat("World Time:", world.time)
|
||||||
stat("Real time of day:", REALTIMEOFDAY)
|
stat("Real time of day:", REALTIMEOFDAY)
|
||||||
stat(null)
|
stat(null)
|
||||||
|
if(GLOB)
|
||||||
|
GLOB.stat_entry()
|
||||||
|
else
|
||||||
|
stat("Globals:", "ERROR")
|
||||||
if(Master)
|
if(Master)
|
||||||
Master.stat_entry()
|
Master.stat_entry()
|
||||||
else
|
else
|
||||||
@@ -710,6 +714,14 @@
|
|||||||
|
|
||||||
if(statpanel("Tickets"))
|
if(statpanel("Tickets"))
|
||||||
GLOB.ahelp_tickets.stat_entry()
|
GLOB.ahelp_tickets.stat_entry()
|
||||||
|
|
||||||
|
|
||||||
|
if(length(GLOB.sdql2_queries))
|
||||||
|
if(statpanel("SDQL2"))
|
||||||
|
stat("Access Global SDQL2 List", GLOB.sdql2_vv_statobj)
|
||||||
|
for(var/i in GLOB.sdql2_queries)
|
||||||
|
var/datum/SDQL2_query/Q = i
|
||||||
|
Q.generate_stat()
|
||||||
|
|
||||||
if(listed_turf && client)
|
if(listed_turf && client)
|
||||||
if(!TurfAdjacent(listed_turf))
|
if(!TurfAdjacent(listed_turf))
|
||||||
|
|||||||
@@ -172,7 +172,7 @@
|
|||||||
spawned_mobs |= M
|
spawned_mobs |= M
|
||||||
else
|
else
|
||||||
var/list/candidates = list()
|
var/list/candidates = list()
|
||||||
for(var/client/player in clients)
|
for(var/client/player in GLOB.clients)
|
||||||
if(player.mob && istype(player.mob, /mob/observer/dead))
|
if(player.mob && istype(player.mob, /mob/observer/dead))
|
||||||
candidates |= player
|
candidates |= player
|
||||||
|
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ var/world_topic_spam_protect_time = world.timeofday
|
|||||||
var/list/players = list()
|
var/list/players = list()
|
||||||
var/list/admins = list()
|
var/list/admins = list()
|
||||||
|
|
||||||
for(var/client/C in clients)
|
for(var/client/C in GLOB.clients)
|
||||||
if(C.holder)
|
if(C.holder)
|
||||||
if(C.holder.fakekey)
|
if(C.holder.fakekey)
|
||||||
continue
|
continue
|
||||||
@@ -175,7 +175,7 @@ var/world_topic_spam_protect_time = world.timeofday
|
|||||||
var/n = 0
|
var/n = 0
|
||||||
var/admins = 0
|
var/admins = 0
|
||||||
|
|
||||||
for(var/client/C in clients)
|
for(var/client/C in GLOB.clients)
|
||||||
if(C.holder)
|
if(C.holder)
|
||||||
if(C.holder.fakekey)
|
if(C.holder.fakekey)
|
||||||
continue //so stealthmins aren't revealed by the hub
|
continue //so stealthmins aren't revealed by the hub
|
||||||
@@ -346,7 +346,7 @@ var/world_topic_spam_protect_time = world.timeofday
|
|||||||
var/client/C
|
var/client/C
|
||||||
var/req_ckey = ckey(input["adminmsg"])
|
var/req_ckey = ckey(input["adminmsg"])
|
||||||
|
|
||||||
for(var/client/K in clients)
|
for(var/client/K in GLOB.clients)
|
||||||
if(K.ckey == req_ckey)
|
if(K.ckey == req_ckey)
|
||||||
C = K
|
C = K
|
||||||
break
|
break
|
||||||
@@ -499,7 +499,7 @@ var/world_topic_spam_protect_time = world.timeofday
|
|||||||
|
|
||||||
var/ckey = copytext(line, 1, length(line)+1)
|
var/ckey = copytext(line, 1, length(line)+1)
|
||||||
var/datum/admins/D = new /datum/admins(title, rights, ckey)
|
var/datum/admins/D = new /datum/admins(title, rights, ckey)
|
||||||
D.associate(directory[ckey])
|
D.associate(GLOB.directory[ckey])
|
||||||
|
|
||||||
/world/proc/load_mentors()
|
/world/proc/load_mentors()
|
||||||
if(config.admin_legacy_system)
|
if(config.admin_legacy_system)
|
||||||
@@ -519,7 +519,7 @@ var/world_topic_spam_protect_time = world.timeofday
|
|||||||
|
|
||||||
var/ckey = copytext(line, 1, length(line)+1)
|
var/ckey = copytext(line, 1, length(line)+1)
|
||||||
var/datum/admins/D = new /datum/admins(title, rights, ckey)
|
var/datum/admins/D = new /datum/admins(title, rights, ckey)
|
||||||
D.associate(directory[ckey])
|
D.associate(GLOB.directory[ckey])
|
||||||
|
|
||||||
/world/proc/update_status()
|
/world/proc/update_status()
|
||||||
var/s = ""
|
var/s = ""
|
||||||
|
|||||||
@@ -248,6 +248,7 @@
|
|||||||
#include "code\datums\computerfiles.dm"
|
#include "code\datums\computerfiles.dm"
|
||||||
#include "code\datums\datacore.dm"
|
#include "code\datums\datacore.dm"
|
||||||
#include "code\datums\datum.dm"
|
#include "code\datums\datum.dm"
|
||||||
|
#include "code\datums\datumvars.dm"
|
||||||
#include "code\datums\EPv2.dm"
|
#include "code\datums\EPv2.dm"
|
||||||
#include "code\datums\ghost_query.dm"
|
#include "code\datums\ghost_query.dm"
|
||||||
#include "code\datums\hierarchy.dm"
|
#include "code\datums\hierarchy.dm"
|
||||||
@@ -1426,14 +1427,14 @@
|
|||||||
#include "code\modules\admin\verbs\possess.dm"
|
#include "code\modules\admin\verbs\possess.dm"
|
||||||
#include "code\modules\admin\verbs\pray.dm"
|
#include "code\modules\admin\verbs\pray.dm"
|
||||||
#include "code\modules\admin\verbs\randomverbs.dm"
|
#include "code\modules\admin\verbs\randomverbs.dm"
|
||||||
#include "code\modules\admin\verbs\SDQL.dm"
|
|
||||||
#include "code\modules\admin\verbs\SDQL_2.dm"
|
|
||||||
#include "code\modules\admin\verbs\SDQL_2_parser.dm"
|
|
||||||
#include "code\modules\admin\verbs\smite.dm"
|
#include "code\modules\admin\verbs\smite.dm"
|
||||||
#include "code\modules\admin\verbs\smite_vr.dm"
|
#include "code\modules\admin\verbs\smite_vr.dm"
|
||||||
#include "code\modules\admin\verbs\striketeam.dm"
|
#include "code\modules\admin\verbs\striketeam.dm"
|
||||||
#include "code\modules\admin\verbs\ticklag.dm"
|
#include "code\modules\admin\verbs\ticklag.dm"
|
||||||
#include "code\modules\admin\verbs\tripAI.dm"
|
#include "code\modules\admin\verbs\tripAI.dm"
|
||||||
|
#include "code\modules\admin\verbs\SDQL2\SDQL_2.dm"
|
||||||
|
#include "code\modules\admin\verbs\SDQL2\SDQL_2_parser.dm"
|
||||||
|
#include "code\modules\admin\verbs\SDQL2\SDQL_2_wrappers.dm"
|
||||||
#include "code\modules\admin\view_variables\helpers.dm"
|
#include "code\modules\admin\view_variables\helpers.dm"
|
||||||
#include "code\modules\admin\view_variables\topic.dm"
|
#include "code\modules\admin\view_variables\topic.dm"
|
||||||
#include "code\modules\admin\view_variables\view_variables.dm"
|
#include "code\modules\admin\view_variables\view_variables.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user