mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-22 03:27:05 +01:00
VV Refactor
Ports /tg/'s VV refactor. Most of this is just cleaning up and making it easier on the coders, but everyone else benefits too: - Mass mod no longer freezes the server (CHECK_TICK <3) - Attempting to change any of the step_* values or anything that will otherwise disable pixel movement will now prompt you and ask if you are sure you want to continue - You can actually enter |text| again in a box, rather than being forced to always use the multi-line input - Cookies! VV saves your search and scroll position for a given UID, rather convenient for debugging - The refresh button on /clients works finally - You can view lists in detail by clicking on them like any other reference, and edit them directly that way. This also means there is no hard limit on how many variables you can see in a list before it's truncated- it will just be hidden until you view the list in VV directly. - You can shuffle lists and clear duplicate/null entries. - Mildly reordered the stuff in the dropdown, inconvenient but necessary.
This commit is contained in:
+538
-345
@@ -1,441 +1,517 @@
|
||||
// reference: /client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0)
|
||||
|
||||
/datum
|
||||
var/var_edited = 0 //Warrenty void if seal is broken
|
||||
var/var_edited = FALSE //Warranty void if seal is broken
|
||||
|
||||
/datum/proc/on_varedit(modified_var) //called whenever a var is edited
|
||||
var_edited = 1
|
||||
/datum/proc/can_vv_get(var_name)
|
||||
return TRUE
|
||||
|
||||
/client/proc/can_vv_get(var_name)
|
||||
return TRUE
|
||||
|
||||
/datum/proc/vv_edit_var(var_name, var_value) //called whenever a var is edited
|
||||
switch(var_name)
|
||||
if("vars")
|
||||
return FALSE
|
||||
if("var_edited")
|
||||
return FALSE
|
||||
var_edited = TRUE
|
||||
vars[var_name] = var_value
|
||||
|
||||
/client/proc/vv_edit_var(var_name, var_value) //called whenever a var is edited
|
||||
switch(var_name)
|
||||
if("vars")
|
||||
return FALSE
|
||||
if("var_edited")
|
||||
return FALSE
|
||||
var_edited = TRUE
|
||||
vars[var_name] = var_value
|
||||
|
||||
/datum/proc/vv_get_var(var_name)
|
||||
switch(var_name)
|
||||
if("vars")
|
||||
return debug_variable(var_name, list(), 0, src)
|
||||
return debug_variable(var_name, vars[var_name], 0, src)
|
||||
|
||||
/client/proc/vv_get_var(var_name)
|
||||
switch(var_name)
|
||||
if("vars")
|
||||
return debug_variable(var_name, list(), 0, src)
|
||||
return debug_variable(var_name, vars[var_name], 0, src)
|
||||
|
||||
|
||||
//please call . = ..() first and append to the result, that way parent items are always at the top and child items are further down
|
||||
//add seperaters by doing . += "---"
|
||||
/datum/proc/vv_get_dropdown()
|
||||
. = list()
|
||||
. += "---"
|
||||
.["Call Proc"] = "?_src_=vars;proc_call=[UID()]"
|
||||
.["Mark Object"] = "?_src_=vars;mark_object=[UID()]"
|
||||
.["Jump to Object"] = "?_src_=vars;jump_to=[UID()]"
|
||||
.["Delete"] = "?_src_=vars;delete=[UID()]"
|
||||
. += "---"
|
||||
|
||||
/client/proc/vv_get_dropdown()
|
||||
. = list()
|
||||
. += "---"
|
||||
.["Call Proc"] = "?_src_=vars;proc_call=[UID()]"
|
||||
.["Mark Object"] = "?_src_=vars;mark_object=[UID()]"
|
||||
.["Delete"] = "?_src_=vars;delete=[UID()]"
|
||||
. += "---"
|
||||
|
||||
/client/proc/debug_variables(datum/D in world)
|
||||
set category = "Debug"
|
||||
set name = "View Variables"
|
||||
//set src in world
|
||||
|
||||
var/static/cookieoffset = rand(1, 9999) //to force cookies to reset after the round.
|
||||
|
||||
if(!is_admin(usr))
|
||||
to_chat(usr, "<span class='warning'>You need to be an administrator to access this.</span>")
|
||||
return
|
||||
|
||||
if(!D)
|
||||
return
|
||||
|
||||
|
||||
var/islist = islist(D)
|
||||
var/isclient = isclient(D)
|
||||
if(!islist && !isclient && !istype(D))
|
||||
return
|
||||
|
||||
var/title = ""
|
||||
var/list/body = list()
|
||||
var/icon/sprite
|
||||
var/hash
|
||||
var/refid
|
||||
|
||||
if(!D) return
|
||||
if(istype(D, /atom))
|
||||
var/atom/A = D
|
||||
title = "[A.name] (\ref[A]) = [A.type]"
|
||||
|
||||
#ifdef VARSICON
|
||||
if(A.icon)
|
||||
body += debug_variable("icon", new/icon(A.icon, A.icon_state, A.dir), 0)
|
||||
#endif
|
||||
|
||||
var/sprite
|
||||
|
||||
if(istype(D,/atom))
|
||||
var/atom/AT = D
|
||||
if(AT.icon && AT.icon_state)
|
||||
sprite = 1
|
||||
|
||||
title = "[D] (\ref[D]) = [D.type]"
|
||||
|
||||
body += {"<script type="text/javascript">
|
||||
|
||||
function updateSearch(){
|
||||
var filter_text = document.getElementById('filter');
|
||||
var filter = filter_text.value.toLowerCase();
|
||||
|
||||
if(event.keyCode == 13){ //Enter / return
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
for( var i = 0; i < lis.length; ++i )
|
||||
{
|
||||
try{
|
||||
var li = lis\[i\];
|
||||
if( li.style.backgroundColor == "#ffee88" )
|
||||
{
|
||||
alist = lis\[i\].getElementsByTagName("a")
|
||||
if(alist.length > 0){
|
||||
location.href=alist\[0\].href;
|
||||
}
|
||||
}
|
||||
}catch(err) { }
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if(event.keyCode == 38){ //Up arrow
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
for( var i = 0; i < lis.length; ++i )
|
||||
{
|
||||
try{
|
||||
var li = lis\[i\];
|
||||
if( li.style.backgroundColor == "#ffee88" )
|
||||
{
|
||||
if( (i-1) >= 0){
|
||||
var li_new = lis\[i-1\];
|
||||
li.style.backgroundColor = "white";
|
||||
li_new.style.backgroundColor = "#ffee88";
|
||||
return
|
||||
}
|
||||
}
|
||||
}catch(err) { }
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if(event.keyCode == 40){ //Down arrow
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
for( var i = 0; i < lis.length; ++i )
|
||||
{
|
||||
try{
|
||||
var li = lis\[i\];
|
||||
if( li.style.backgroundColor == "#ffee88" )
|
||||
{
|
||||
if( (i+1) < lis.length){
|
||||
var li_new = lis\[i+1\];
|
||||
li.style.backgroundColor = "white";
|
||||
li_new.style.backgroundColor = "#ffee88";
|
||||
return
|
||||
}
|
||||
}
|
||||
}catch(err) { }
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//This part here resets everything to how it was at the start so the filter is applied to the complete list. Screw efficiency, it's client-side anyway and it only looks through 200 or so variables at maximum anyway (mobs).
|
||||
if(complete_list != null && complete_list != ""){
|
||||
var vars_ol1 = document.getElementById("vars");
|
||||
vars_ol1.innerHTML = complete_list
|
||||
}
|
||||
|
||||
if(filter.value == ""){
|
||||
return;
|
||||
}else{
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
|
||||
for( var i = 0; i < lis.length; ++i )
|
||||
{
|
||||
try{
|
||||
var li = lis\[i\];
|
||||
if( li.innerText.toLowerCase().indexOf(filter) == -1 )
|
||||
{
|
||||
vars_ol.removeChild(li);
|
||||
i--;
|
||||
}
|
||||
}catch(err) { }
|
||||
}
|
||||
}
|
||||
var lis_new = vars_ol.getElementsByTagName("li");
|
||||
for( var j = 0; j < lis_new.length; ++j )
|
||||
{
|
||||
var li1 = lis\[j\];
|
||||
if(j == 0){
|
||||
li1.style.backgroundColor = "#ffee88";
|
||||
}else{
|
||||
li1.style.backgroundColor = "white";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function selectTextField(){
|
||||
var filter_text = document.getElementById('filter');
|
||||
filter_text.focus();
|
||||
filter_text.select();
|
||||
|
||||
}
|
||||
|
||||
function loadPage(list) {
|
||||
|
||||
if(list.options\[list.selectedIndex\].value == ""){
|
||||
return;
|
||||
}
|
||||
|
||||
location.href=list.options\[list.selectedIndex\].value;
|
||||
|
||||
}
|
||||
</script> "}
|
||||
|
||||
body += "<body onload='selectTextField(); updateSearch()' onkeyup='updateSearch()'>"
|
||||
|
||||
body += "<div align='center'><table width='100%'><tr><td width='50%'>"
|
||||
|
||||
if(sprite)
|
||||
body += "<table align='center' width='100%'><tr><td>[bicon(D, use_class=0)]</td><td>"
|
||||
if(!islist)
|
||||
refid = "[D.UID()]"
|
||||
else
|
||||
body += "<table align='center' width='100%'><tr><td>"
|
||||
refid = "\ref[D]"
|
||||
|
||||
body += "<div align='center'>"
|
||||
var/type = /list
|
||||
if(!islist)
|
||||
type = D.type
|
||||
|
||||
if(istype(D,/atom))
|
||||
if(isatom(D))
|
||||
var/atom/A = D
|
||||
if(A.icon && A.icon_state)
|
||||
sprite = new /icon(A.icon, A.icon_state)
|
||||
hash = md5(A.icon)
|
||||
hash = md5(hash + A.icon_state)
|
||||
usr << browse_rsc(sprite, "vv[hash].png")
|
||||
|
||||
|
||||
var/sprite_text
|
||||
if(sprite)
|
||||
sprite_text = "<img src='vv[hash].png'></td><td>"
|
||||
|
||||
|
||||
var/list/atomsnowflake = list()
|
||||
if(isatom(D))
|
||||
var/atom/A = D
|
||||
if(isliving(A))
|
||||
body += "<a href='?_src_=vars;rename=[D.UID()]'><b>[D]</b></a>"
|
||||
if(A.dir)
|
||||
body += "<br><font size='1'><a href='?_src_=vars;rotatedatum=[D.UID()];rotatedir=left'><<</a> <a href='?_src_=vars;datumedit=[D.UID()];varnameedit=dir'>[dir2text(A.dir)]</a> <a href='?_src_=vars;rotatedatum=[D.UID()];rotatedir=right'>>></a></font>"
|
||||
var/mob/living/M = A
|
||||
body += "<br><font size='1'><a href='?_src_=vars;datumedit=[D.UID()];varnameedit=ckey'>[M.ckey ? M.ckey : "No ckey"]</a> / <a href='?_src_=vars;datumedit=[D.UID()];varnameedit=real_name'>[M.real_name ? M.real_name : "No real name"]</a></font>"
|
||||
body += {"
|
||||
<br><font size='1'>
|
||||
BRUTE:<font size='1'><a href='?_src_=vars;mobToDamage=[D.UID()];adjustDamage=brute'>[M.getBruteLoss()]</a>
|
||||
FIRE:<font size='1'><a href='?_src_=vars;mobToDamage=[D.UID()];adjustDamage=fire'>[M.getFireLoss()]</a>
|
||||
TOXIN:<font size='1'><a href='?_src_=vars;mobToDamage=[D.UID()];adjustDamage=toxin'>[M.getToxLoss()]</a>
|
||||
OXY:<font size='1'><a href='?_src_=vars;mobToDamage=[D.UID()];adjustDamage=oxygen'>[M.getOxyLoss()]</a>
|
||||
CLONE:<font size='1'><a href='?_src_=vars;mobToDamage=[D.UID()];adjustDamage=clone'>[M.getCloneLoss()]</a>
|
||||
BRAIN:<font size='1'><a href='?_src_=vars;mobToDamage=[D.UID()];adjustDamage=brain'>[M.getBrainLoss()]</a>
|
||||
</font>
|
||||
|
||||
|
||||
var/mob/living/L = A
|
||||
atomsnowflake += "<a href='?_src_=vars;rename=[L.UID()]'><b>[L]</b></a>"
|
||||
if(L.dir)
|
||||
atomsnowflake += "<br><font size='1'><a href='?_src_=vars;rotatedatum=[L.UID()];rotatedir=left'><<</a> <a href='?_src_=vars;datumedit=[L.UID()];varnameedit=dir'>[dir2text(L.dir)]</a> <a href='?_src_=vars;rotatedatum=[L.UID()];rotatedir=right'>>></a></font>"
|
||||
atomsnowflake += {"
|
||||
<br><font size='1'><a href='?_src_=vars;datumedit=[L.UID()];varnameedit=ckey'>[L.ckey ? L.ckey : "No ckey"]</a> / <a href='?_src_=vars;datumedit=[L.UID()];varnameedit=real_name'>[L.real_name ? L.real_name : "No real name"]</a></font>
|
||||
<br><font size='1'>
|
||||
BRUTE:<font size='1'><a href='?_src_=vars;mobToDamage=[L.UID()];adjustDamage=brute'>[L.getBruteLoss()]</a>
|
||||
FIRE:<font size='1'><a href='?_src_=vars;mobToDamage=[L.UID()];adjustDamage=fire'>[L.getFireLoss()]</a>
|
||||
TOXIN:<font size='1'><a href='?_src_=vars;mobToDamage=[L.UID()];adjustDamage=toxin'>[L.getToxLoss()]</a>
|
||||
OXY:<font size='1'><a href='?_src_=vars;mobToDamage=[L.UID()];adjustDamage=oxygen'>[L.getOxyLoss()]</a>
|
||||
CLONE:<font size='1'><a href='?_src_=vars;mobToDamage=[L.UID()];adjustDamage=clone'>[L.getCloneLoss()]</a>
|
||||
BRAIN:<font size='1'><a href='?_src_=vars;mobToDamage=[L.UID()];adjustDamage=brain'>[L.getBrainLoss()]</a>
|
||||
STAMINA:<font size='1'><a href='?_src_=vars;mobToDamage=[L.UID()];adjustDamage=stamina'>[L.getStaminaLoss()]</a>
|
||||
</font>
|
||||
"}
|
||||
else
|
||||
body += "<a href='?_src_=vars;datumedit=[D.UID()];varnameedit=name'><b>[D]</b></a>"
|
||||
atomsnowflake += "<a href='?_src_=vars;datumedit=[A.UID()];varnameedit=name'><b>[A]</b></a>"
|
||||
if(A.dir)
|
||||
body += "<br><font size='1'><a href='?_src_=vars;rotatedatum=[D.UID()];rotatedir=left'><<</a> <a href='?_src_=vars;datumedit=[D.UID()];varnameedit=dir'>[dir2text(A.dir)]</a> <a href='?_src_=vars;rotatedatum=[D.UID()];rotatedir=right'>>></a></font>"
|
||||
atomsnowflake += "<br><font size='1'><a href='?_src_=vars;rotatedatum=[A.UID()];rotatedir=left'><<</a> <a href='?_src_=vars;datumedit=[A.UID()];varnameedit=dir'>[dir2text(A.dir)]</a> <a href='?_src_=vars;rotatedatum=[D.UID()];rotatedir=right'>>></a></font>"
|
||||
else
|
||||
body += "<b>[D]</b>"
|
||||
atomsnowflake += "<b>[D]</b>"
|
||||
|
||||
body += "</div>"
|
||||
|
||||
body += "</tr></td></table>"
|
||||
|
||||
var/formatted_type = text("[D.type]")
|
||||
var/formatted_type = "[type]"
|
||||
if(length(formatted_type) > 25)
|
||||
var/middle_point = length(formatted_type) / 2
|
||||
var/splitpoint = findtext(formatted_type,"/",middle_point)
|
||||
var/splitpoint = findtext(formatted_type, "/", middle_point)
|
||||
if(splitpoint)
|
||||
formatted_type = "[copytext(formatted_type,1,splitpoint)]<br>[copytext(formatted_type,splitpoint)]"
|
||||
formatted_type = "[copytext(formatted_type, 1, splitpoint)]<br>[copytext(formatted_type, splitpoint)]"
|
||||
else
|
||||
formatted_type = "Type too long" //No suitable splitpoint (/) found.
|
||||
|
||||
body += "<div align='center'><b><font size='1'>[formatted_type]</font></b>"
|
||||
|
||||
if(src.holder && src.holder.marked_datum && src.holder.marked_datum == D)
|
||||
body += "<br><font size='1' color='red'><b>Marked Object</b></font>"
|
||||
var/marked
|
||||
if(holder.marked_datum && holder.marked_datum == D)
|
||||
marked = "<br><font size='1' color='red'><b>Marked Object</b></font>"
|
||||
|
||||
if(D.var_edited)
|
||||
body += "<br><font size='1' color='red'><b>Var Edited</b></font>"
|
||||
|
||||
if(istype(D, /atom))
|
||||
var/varedited_line = ""
|
||||
if(isatom(D))
|
||||
var/atom/A = D
|
||||
if(A.admin_spawned)
|
||||
body += "<br><font size='1' color='red'><b>Admin Spawned</b></font>"
|
||||
|
||||
body += "</div>"
|
||||
|
||||
body += "</div></td>"
|
||||
|
||||
body += "<td width='50%'><div align='center'><a href='?_src_=vars;datumrefresh=[D.UID()]'>Refresh</a>"
|
||||
|
||||
body += {" <form>
|
||||
<select name="file" size="1"
|
||||
onchange="loadPage(this.form.elements\[0\])"
|
||||
target="_parent._top"
|
||||
onmouseclick="this.focus()"
|
||||
style="background-color:#ffffff">
|
||||
"}
|
||||
|
||||
body += {" <option value>Select option</option>
|
||||
<option value> </option>
|
||||
"}
|
||||
varedited_line += "<br><font size='1' color='red'><b>Admin Spawned</b></font>"
|
||||
|
||||
|
||||
body += "<option value='?_src_=vars;mark_object=[D.UID()]'>Mark Object</option>"
|
||||
body += "<option value='?_src_=vars;proc_call=[D.UID()]'>Call Proc</option>"
|
||||
body += "<option value='?_src_=vars;jump_to=[D.UID()]'>Jump to Object</option>"
|
||||
if(ismob(D))
|
||||
body += "<option value='?_src_=vars;mob_player_panel=[D.UID()]'>Show player panel</option>"
|
||||
if(!islist && D.var_edited)
|
||||
varedited_line += "<br><font size='1' color='red'><b>Var Edited</b></font>"
|
||||
|
||||
body += "<option value>---</option>"
|
||||
|
||||
if(ismob(D))
|
||||
body += "<option value='?_src_=vars;give_spell=[D.UID()]'>Give Spell</option>"
|
||||
body += "<option value='?_src_=vars;give_disease=[D.UID()]'>Give Disease</option>"
|
||||
body += "<option value='?_src_=vars;godmode=[D.UID()]'>Toggle Godmode</option>"
|
||||
body += "<option value='?_src_=vars;build_mode=[D.UID()]'>Toggle Build Mode</option>"
|
||||
var/dropdownoptions = list()
|
||||
if(islist)
|
||||
dropdownoptions = list(
|
||||
"---",
|
||||
"Add Item" = "?_src_=vars;listadd=[refid]",
|
||||
"Remove Nulls" = "?_src_=vars;listnulls=[refid]",
|
||||
"Remove Dupes" = "?_src_=vars;listdupes=[refid]",
|
||||
"Set len" = "?_src_=vars;listlen=[refid]",
|
||||
"Shuffle" = "?_src_=vars;listshuffle=[refid]"
|
||||
)
|
||||
else
|
||||
dropdownoptions = D.vv_get_dropdown()
|
||||
|
||||
body += "<option value='?_src_=vars;make_skeleton=[D.UID()]'>Make 2spooky</option>"
|
||||
|
||||
body += "<option value='?_src_=vars;direct_control=[D.UID()]'>Assume Direct Control</option>"
|
||||
body += "<option value='?_src_=vars;offer_control=[D.UID()]'>Offer Control to Ghosts</option>"
|
||||
body += "<option value='?_src_=vars;drop_everything=[D.UID()]'>Drop Everything</option>"
|
||||
var/list/dropdownoptions_html = list()
|
||||
for(var/name in dropdownoptions)
|
||||
var/link = dropdownoptions[name]
|
||||
if(link)
|
||||
dropdownoptions_html += "<option value='[link]'>[name]</option>"
|
||||
else
|
||||
dropdownoptions_html += "<option value>[name]</option>"
|
||||
|
||||
body += "<option value='?_src_=vars;regenerateicons=[D.UID()]'>Regenerate Icons</option>"
|
||||
body += "<option value='?_src_=vars;addlanguage=[D.UID()]'>Add Language</option>"
|
||||
body += "<option value='?_src_=vars;remlanguage=[D.UID()]'>Remove Language</option>"
|
||||
body += "<option value='?_src_=vars;addorgan=[D.UID()]'>Add Organ</option>"
|
||||
body += "<option value='?_src_=vars;remorgan=[D.UID()]'>Remove Organ</option>"
|
||||
|
||||
body += "<option value='?_src_=vars;fix_nano=[D.UID()]'>Fix NanoUI</option>"
|
||||
|
||||
body += "<option value='?_src_=vars;addverb=[D.UID()]'>Add Verb</option>"
|
||||
body += "<option value='?_src_=vars;remverb=[D.UID()]'>Remove Verb</option>"
|
||||
if(ishuman(D))
|
||||
body += "<option value>---</option>"
|
||||
body += "<option value='?_src_=vars;setspecies=[D.UID()]'>Set Species</option>"
|
||||
body += "<option value='?_src_=vars;makeai=[D.UID()]'>Make AI</option>"
|
||||
body += "<option value='?_src_=vars;makemask=[D.UID()]'>Make Mask of Nar'sie</option>"
|
||||
body += "<option value='?_src_=vars;makerobot=[D.UID()]'>Make cyborg</option>"
|
||||
body += "<option value='?_src_=vars;makemonkey=[D.UID()]'>Make monkey</option>"
|
||||
body += "<option value='?_src_=vars;makealien=[D.UID()]'>Make alien</option>"
|
||||
body += "<option value='?_src_=vars;makeslime=[D.UID()]'>Make slime</option>"
|
||||
body += "<option value='?_src_=vars;makesuper=[D.UID()]'>Make superhero</option>"
|
||||
body += "<option value>---</option>"
|
||||
body += "<option value='?_src_=vars;gib=[D.UID()]'>Gib</option>"
|
||||
if(isobj(D))
|
||||
body += "<option value='?_src_=vars;delall=[D.UID()]'>Delete all of type</option>"
|
||||
if(isobj(D) || ismob(D) || isturf(D))
|
||||
body += "<option value='?_src_=vars;addreagent=[D.UID()]'>Add reagent</option>"
|
||||
body += "<option value='?_src_=vars;explode=[D.UID()]'>Trigger explosion</option>"
|
||||
body += "<option value='?_src_=vars;emp=[D.UID()]'>Trigger EM pulse</option>"
|
||||
|
||||
body += "</select></form>"
|
||||
|
||||
body += "</div></td></tr></table></div><hr>"
|
||||
|
||||
body += "<font size='1'><b>E</b> - Edit, tries to determine the variable type by itself.<br>"
|
||||
body += "<b>C</b> - Change, asks you for the var type first.<br>"
|
||||
body += "<b>M</b> - Mass modify: changes this variable for all objects of this type.</font><br>"
|
||||
|
||||
body += "<hr><table width='100%'><tr><td width='20%'><div align='center'><b>Search:</b></div></td><td width='80%'><input type='text' id='filter' name='filter_text' value='' style='width:100%;'></td></tr></table><hr>"
|
||||
|
||||
body += "<ol id='vars'>"
|
||||
|
||||
var/list/names = list()
|
||||
for(var/V in D.vars)
|
||||
names += V
|
||||
if(!islist)
|
||||
for(var/V in D.vars)
|
||||
names += V
|
||||
|
||||
names = sortList(names)
|
||||
|
||||
for(var/V in names)
|
||||
body += debug_variable(V, D.vars[V], 0, D)
|
||||
sleep(1) // Without a sleep here, VV sometimes disconnects clients
|
||||
|
||||
body += "</ol>"
|
||||
|
||||
var/html = "<html><head>"
|
||||
if(title)
|
||||
html += "<title>[title]</title>"
|
||||
html += {"<style>
|
||||
body
|
||||
{
|
||||
font-family: Verdana, sans-serif;
|
||||
font-size: 9pt;
|
||||
}
|
||||
.value
|
||||
{
|
||||
font-family: "Courier New", monospace;
|
||||
font-size: 8pt;
|
||||
}
|
||||
</style>"}
|
||||
html += "</head><body>"
|
||||
html += body.Join("")
|
||||
var/list/variable_html = list()
|
||||
if(islist)
|
||||
var/list/L = D
|
||||
for(var/i in 1 to L.len)
|
||||
var/key = L[i]
|
||||
var/value
|
||||
if(IS_NORMAL_LIST(L) && !isnum(key))
|
||||
value = L[key]
|
||||
variable_html += debug_variable(i, value, 0, D)
|
||||
else
|
||||
names = sortList(names)
|
||||
for(var/V in names)
|
||||
if(D.can_vv_get(V))
|
||||
variable_html += D.vv_get_var(V)
|
||||
|
||||
html += {"
|
||||
var/html = {"
|
||||
<html>
|
||||
<head>
|
||||
<title>[title]</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Verdana, sans-serif;
|
||||
font-size: 9pt;
|
||||
}
|
||||
.value {
|
||||
font-family: "Courier New", monospace;
|
||||
font-size: 8pt;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload='selectTextField(); updateSearch()' onkeydown='return checkreload()' onkeyup='updateSearch()'>
|
||||
<script type="text/javascript">
|
||||
function checkreload() {
|
||||
if(event.keyCode == 116){ //F5 (to refresh properly)
|
||||
document.getElementById("refresh_link").click();
|
||||
event.preventDefault ? event.preventDefault() : (event.returnValue = false)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function updateSearch(){
|
||||
var filter_text = document.getElementById('filter');
|
||||
var filter = filter_text.value.toLowerCase();
|
||||
if(event.keyCode == 13){ //Enter / return
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
for ( var i = 0; i < lis.length; ++i )
|
||||
{
|
||||
try{
|
||||
var li = lis\[i\];
|
||||
if ( li.style.backgroundColor == "#ffee88" )
|
||||
{
|
||||
alist = lis\[i\].getElementsByTagName("a")
|
||||
if(alist.length > 0){
|
||||
location.href=alist\[0\].href;
|
||||
}
|
||||
}
|
||||
}catch(err) { }
|
||||
}
|
||||
return
|
||||
}
|
||||
if(event.keyCode == 38){ //Up arrow
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
for ( var i = 0; i < lis.length; ++i )
|
||||
{
|
||||
try{
|
||||
var li = lis\[i\];
|
||||
if ( li.style.backgroundColor == "#ffee88" )
|
||||
{
|
||||
if( (i-1) >= 0){
|
||||
var li_new = lis\[i-1\];
|
||||
li.style.backgroundColor = "white";
|
||||
li_new.style.backgroundColor = "#ffee88";
|
||||
return
|
||||
}
|
||||
}
|
||||
}catch(err) { }
|
||||
}
|
||||
return
|
||||
}
|
||||
if(event.keyCode == 40){ //Down arrow
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
for ( var i = 0; i < lis.length; ++i )
|
||||
{
|
||||
try{
|
||||
var li = lis\[i\];
|
||||
if ( li.style.backgroundColor == "#ffee88" )
|
||||
{
|
||||
if( (i+1) < lis.length){
|
||||
var li_new = lis\[i+1\];
|
||||
li.style.backgroundColor = "white";
|
||||
li_new.style.backgroundColor = "#ffee88";
|
||||
return
|
||||
}
|
||||
}
|
||||
}catch(err) { }
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//This part here resets everything to how it was at the start so the filter is applied to the complete list. Screw efficiency, it's client-side anyway and it only looks through 200 or so variables at maximum anyway (mobs).
|
||||
if(complete_list != null && complete_list != ""){
|
||||
var vars_ol1 = document.getElementById("vars");
|
||||
vars_ol1.innerHTML = complete_list
|
||||
}
|
||||
document.cookie="[refid][cookieoffset]search="+encodeURIComponent(filter);
|
||||
if(filter == ""){
|
||||
return;
|
||||
}else{
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
for ( var i = 0; i < lis.length; ++i )
|
||||
{
|
||||
try{
|
||||
var li = lis\[i\];
|
||||
if ( li.innerText.toLowerCase().indexOf(filter) == -1 )
|
||||
{
|
||||
vars_ol.removeChild(li);
|
||||
i--;
|
||||
}
|
||||
}catch(err) { }
|
||||
}
|
||||
}
|
||||
var lis_new = vars_ol.getElementsByTagName("li");
|
||||
for ( var j = 0; j < lis_new.length; ++j )
|
||||
{
|
||||
var li1 = lis\[j\];
|
||||
if (j == 0){
|
||||
li1.style.backgroundColor = "#ffee88";
|
||||
}else{
|
||||
li1.style.backgroundColor = "white";
|
||||
}
|
||||
}
|
||||
}
|
||||
function selectTextField() {
|
||||
var filter_text = document.getElementById('filter');
|
||||
filter_text.focus();
|
||||
filter_text.select();
|
||||
var lastsearch = getCookie("[refid][cookieoffset]search");
|
||||
if (lastsearch) {
|
||||
filter_text.value = lastsearch;
|
||||
updateSearch();
|
||||
}
|
||||
}
|
||||
function loadPage(list) {
|
||||
if(list.options\[list.selectedIndex\].value == ""){
|
||||
return;
|
||||
}
|
||||
location.href=list.options\[list.selectedIndex\].value;
|
||||
}
|
||||
function getCookie(cname) {
|
||||
var name = cname + "=";
|
||||
var ca = document.cookie.split(';');
|
||||
for(var i=0; i<ca.length; i++) {
|
||||
var c = ca\[i\];
|
||||
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
||||
if (c.indexOf(name)==0) return c.substring(name.length,c.length);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
</script>
|
||||
<div align='center'>
|
||||
<table width='100%'>
|
||||
<tr>
|
||||
<td width='50%'>
|
||||
<table align='center' width='100%'>
|
||||
<tr>
|
||||
<td>
|
||||
[sprite_text]
|
||||
<div align='center'>
|
||||
[atomsnowflake.Join()]
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div align='center'>
|
||||
<b><font size='1'>[formatted_type]</font></b>
|
||||
[marked]
|
||||
[varedited_line]
|
||||
</div>
|
||||
</td>
|
||||
<td width='50%'>
|
||||
<div align='center'>
|
||||
<a id='refresh_link' href='?_src_=vars;[islist ? "listrefresh=\ref[D]" : "datumrefresh=[D.UID()]"]'>Refresh</a>
|
||||
<form>
|
||||
<select name="file" size="1"
|
||||
onchange="loadPage(this.form.elements\[0\])"
|
||||
target="_parent._top"
|
||||
onmouseclick="this.focus()"
|
||||
style="background-color:#ffffff">
|
||||
<option value selected>Select option</option>
|
||||
[dropdownoptions_html.Join()]
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<hr>
|
||||
<font size='1'>
|
||||
<b>E</b> - Edit, tries to determine the variable type by itself.<br>
|
||||
<b>C</b> - Change, asks you for the var type first.<br>
|
||||
<b>M</b> - Mass modify: changes this variable for all objects of this type.<br>
|
||||
</font>
|
||||
<hr>
|
||||
<table width='100%'>
|
||||
<tr>
|
||||
<td width='20%'>
|
||||
<div align='center'>
|
||||
<b>Search:</b>
|
||||
</div>
|
||||
</td>
|
||||
<td width='80%'>
|
||||
<input type='text' id='filter' name='filter_text' value='' style='width:100%;'>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<ol id='vars'>
|
||||
[variable_html.Join()]
|
||||
</ol>
|
||||
<script type='text/javascript'>
|
||||
var vars_ol = document.getElementById("vars");
|
||||
var complete_list = vars_ol.innerHTML;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
|
||||
html += "</body></html>"
|
||||
|
||||
usr << browse(html, "window=variables[D.UID()];size=475x650")
|
||||
|
||||
return
|
||||
|
||||
/client/proc/debug_variable(name, value, level, var/datum/DA = null)
|
||||
var/list/html = list()
|
||||
usr << browse(html, "window=variables[refid];size=475x650")
|
||||
|
||||
#define VV_HTML_ENCODE(thing) ( sanitize ? html_encode(thing) : thing )
|
||||
/proc/debug_variable(name, value, level, var/datum/DA = null, sanitize = TRUE)
|
||||
var/header
|
||||
if(DA)
|
||||
html += "<li style='backgroundColor:white'>(<a href='?_src_=vars;datumedit=[DA.UID()];varnameedit=[name]'>E</a>) (<a href='?_src_=vars;datumchange=[DA.UID()];varnamechange=[name]'>C</a>) (<a href='?_src_=vars;datummass=[DA.UID()];varnamemass=[name]'>M</a>) "
|
||||
if(islist(DA))
|
||||
var/index = name
|
||||
if(value)
|
||||
name = DA[name] // name is really the index until this line
|
||||
else
|
||||
value = DA[name]
|
||||
header = "<li style='backgroundColor:white'>(<a href='?_src_=vars;listedit=\ref[DA];index=[index]'>E</a>) (<a href='?_src_=vars;listchange=\ref[DA];index=[index]'>C</a>) (<a href='?_src_=vars;listremove=\ref[DA];index=[index]'>-</a>) "
|
||||
else
|
||||
header = "<li style='backgroundColor:white'>(<a href='?_src_=vars;datumedit=[DA.UID()];varnameedit=[name]'>E</a>) (<a href='?_src_=vars;datumchange=[DA.UID()];varnamechange=[name]'>C</a>) (<a href='?_src_=vars;datummass=[DA.UID()];varnamemass=[name]'>M</a>) "
|
||||
else
|
||||
html += "<li>"
|
||||
header = "<li>"
|
||||
|
||||
var/item
|
||||
if(isnull(value))
|
||||
html += "[name] = <span class='value'>null</span>"
|
||||
item = "[VV_HTML_ENCODE(name)] = <span class='value'>null</span>"
|
||||
|
||||
else if(istext(value))
|
||||
html += "[name] = <span class='value'>\"[value]\"</span>"
|
||||
item = "[VV_HTML_ENCODE(name)] = <span class='value'>\"[VV_HTML_ENCODE(value)]\"</span>"
|
||||
|
||||
else if(isicon(value))
|
||||
#ifdef VARSICON
|
||||
html += "[name] = /icon (<span class='value'>[value]</span>) [bicon(value, use_class=0)]"
|
||||
item = "[name] = /icon (<span class='value'>[value]</span>) [bicon(value, use_class=0)]"
|
||||
#else
|
||||
html += "[name] = /icon (<span class='value'>[value]</span>)"
|
||||
item = "[name] = /icon (<span class='value'>[value]</span>)"
|
||||
#endif
|
||||
|
||||
|
||||
else if(istype(value, /image))
|
||||
var/image/I = value
|
||||
#ifdef VARSICON
|
||||
html += "<a href='?_src_=vars;Vars=[I.UID()]'>[name] \ref[value]</a> = /image (<span class='value'>[value]</span>) [bicon(value, use_class=0)]"
|
||||
item = "<a href='?_src_=vars;Vars=[I.UID()]'>[name] \ref[value]</a> = /image (<span class='value'>[value]</span>) [bicon(value, use_class=0)]"
|
||||
#else
|
||||
html += "<a href='?_src_=vars;Vars=[I.UID()]'>[name] \ref[value]</a> = /image (<span class='value'>[value]</span>)"
|
||||
#endif
|
||||
|
||||
item = "<a href='?_src_=vars;Vars=[I.UID()]'>[name] \ref[value]</a> = /image (<span class='value'>[value]</span>)"
|
||||
#endif
|
||||
|
||||
else if(isfile(value))
|
||||
html += "[name] = <span class='value'>'[value]'</span>"
|
||||
item = "[VV_HTML_ENCODE(name)] = <span class='value'>'[value]'</span>"
|
||||
|
||||
else if(istype(value, /datum))
|
||||
var/datum/D = value
|
||||
html += "<a href='?_src_=vars;Vars=[D.UID()]'>[name] \ref[value]</a> = [D.type]"
|
||||
item = "<a href='?_src_=vars;Vars=[D.UID()]'>[VV_HTML_ENCODE(name)] \ref[value]</a> = [D.type]"
|
||||
|
||||
else if(istype(value, /client))
|
||||
var/client/C = value
|
||||
html += "<a href='?_src_=vars;Vars=[C.UID()]'>[name] \ref[value]</a> = [C] [C.type]"
|
||||
item = "<a href='?_src_=vars;Vars=[C.UID()]'>[VV_HTML_ENCODE(name)] \ref[value]</a> = [C] [C.type]"
|
||||
//
|
||||
else if(istype(value, /list))
|
||||
else if(islist(value))
|
||||
var/list/L = value
|
||||
html += "[name] = /list ([L.len])"
|
||||
var/list/items = list()
|
||||
|
||||
if(L.len > 0 && !(name == "underlays" || name == "overlays" || name == "vars" || L.len > 500))
|
||||
// not sure if this is completely right...
|
||||
if(0) //(L.vars.len > 0)
|
||||
html += "<ol>"
|
||||
html += "</ol>"
|
||||
else
|
||||
html += "<ul>"
|
||||
var/index = 1
|
||||
for(var/entry in L)
|
||||
if(istext(entry))
|
||||
html += debug_variable(entry, L[entry], level + 1)
|
||||
else
|
||||
html += debug_variable(index, L[index], level + 1)
|
||||
index++
|
||||
html += "</ul>"
|
||||
if(L.len > 0 && !(name == "underlays" || name == "overlays" || name == "vars" || L.len > (IS_NORMAL_LIST(L) ? 50 : 150)))
|
||||
for(var/i in 1 to L.len)
|
||||
var/key = L[i]
|
||||
var/val
|
||||
if(IS_NORMAL_LIST(L) && !isnum(key))
|
||||
val = L[key]
|
||||
if(!val)
|
||||
val = key
|
||||
key = i
|
||||
|
||||
items += debug_variable(key, val, level + 1, sanitize = sanitize)
|
||||
|
||||
item = "<a href='?_src_=vars;VarsList=\ref[L]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a><ul>[items.Join()]</ul>"
|
||||
|
||||
else
|
||||
item = "<a href='?_src_=vars;VarsList=\ref[L]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a>"
|
||||
|
||||
else
|
||||
html += "[name] = <span class='value'>[value]</span>"
|
||||
/*
|
||||
// Bitfield stuff
|
||||
if(round(value)==value) // Require integers.
|
||||
var/idx=0
|
||||
var/bit=0
|
||||
var/bv=0
|
||||
html += "<div class='value binary'>"
|
||||
for(var/block=0;block<8;block++)
|
||||
html += " <span class='block'>"
|
||||
for(var/i=0;i<4;i++)
|
||||
idx=(block*4)+i
|
||||
to_chat(bit=1, idx)
|
||||
bv=value & bit
|
||||
html += "<a href='?_src_=vars;togbit=[idx];var=[name];subject=[DA.UID()]' title='bit [idx] ([bit])'>[bv?1:0]</a>"
|
||||
html += "</span>"
|
||||
html += "</div>"
|
||||
*/
|
||||
html += "</li>"
|
||||
item = "[VV_HTML_ENCODE(name)] = <span class='value'>[VV_HTML_ENCODE(value)]</span>"
|
||||
|
||||
return html.Join("")
|
||||
return "[header][item]</li>"
|
||||
|
||||
#undef VV_HTML_ENCODE
|
||||
|
||||
/client/proc/view_var_Topic(href, href_list, hsrc)
|
||||
//This should all be moved over to datum/admins/Topic() or something ~Carn
|
||||
if(!check_rights(R_ADMIN|R_MOD))
|
||||
return
|
||||
|
||||
if(view_var_Topic_list(href, href_list, hsrc)) // done because you can't use UIDs with lists and I don't want to snowflake into the below check to supress warnings
|
||||
return
|
||||
|
||||
// Correct and warn about any VV topic links that aren't using UIDs
|
||||
for(var/paramname in href_list)
|
||||
if(findtext(href_list[paramname], "]_"))
|
||||
@@ -516,6 +592,7 @@ body
|
||||
|
||||
cmd_mass_modify_object_variables(A, href_list["varnamemass"])
|
||||
|
||||
|
||||
else if(href_list["mob_player_panel"])
|
||||
if(!check_rights(R_ADMIN|R_MOD)) return
|
||||
|
||||
@@ -1099,6 +1176,7 @@ body
|
||||
if("oxygen")L.adjustOxyLoss(amount)
|
||||
if("brain") L.adjustBrainLoss(amount)
|
||||
if("clone") L.adjustCloneLoss(amount)
|
||||
if("stamina") L.adjustStaminaLoss(amount)
|
||||
else
|
||||
to_chat(usr, "You caused an error. DEBUG: Text:[Text] Mob:[L]")
|
||||
return
|
||||
@@ -1110,8 +1188,123 @@ body
|
||||
|
||||
if(href_list["datumrefresh"])
|
||||
var/datum/DAT = locateUID(href_list["datumrefresh"])
|
||||
if(!istype(DAT, /datum))
|
||||
if(!istype(DAT, /datum) && !isclient(DAT))
|
||||
return
|
||||
src.debug_variables(DAT)
|
||||
|
||||
return
|
||||
|
||||
/client/proc/view_var_Topic_list(href, href_list, hsrc)
|
||||
if(href_list["VarsList"])
|
||||
debug_variables(locate(href_list["VarsList"]))
|
||||
return TRUE
|
||||
|
||||
if(href_list["listedit"] && href_list["index"])
|
||||
var/index = text2num(href_list["index"])
|
||||
if(!index)
|
||||
return TRUE
|
||||
|
||||
var/list/L = locate(href_list["listedit"])
|
||||
if(!istype(L))
|
||||
to_chat(usr, "This can only be used on instances of type /list")
|
||||
return
|
||||
|
||||
mod_list(L, null, "list", "contents", index, autodetect_class = TRUE)
|
||||
return TRUE
|
||||
|
||||
if(href_list["listchange"] && href_list["index"])
|
||||
var/index = text2num(href_list["index"])
|
||||
if(!index)
|
||||
return TRUE
|
||||
|
||||
var/list/L = locate(href_list["listchange"])
|
||||
if(!istype(L))
|
||||
to_chat(usr, "This can only be used on instances of type /list")
|
||||
return
|
||||
|
||||
mod_list(L, null, "list", "contents", index, autodetect_class = FALSE)
|
||||
return TRUE
|
||||
|
||||
if(href_list["listremove"] && href_list["index"])
|
||||
var/index = text2num(href_list["index"])
|
||||
if(!index)
|
||||
return TRUE
|
||||
|
||||
var/list/L = locate(href_list["listremove"])
|
||||
if(!istype(L))
|
||||
to_chat(usr, "This can only be used on instances of type /list")
|
||||
return
|
||||
|
||||
var/variable = L[index]
|
||||
var/prompt = alert("Do you want to remove item number [index] from list?", "Confirm", "Yes", "No")
|
||||
if(prompt != "Yes")
|
||||
return
|
||||
L.Cut(index, index+1)
|
||||
log_to_dd("### ListVarEdit by [src]: /list's contents: REMOVED=[html_encode("[variable]")]")
|
||||
log_admin("[key_name(src)] modified list's contents: REMOVED=[variable]")
|
||||
message_admins("[key_name_admin(src)] modified list's contents: REMOVED=[variable]")
|
||||
return TRUE
|
||||
|
||||
if(href_list["listadd"])
|
||||
var/list/L = locate(href_list["listadd"])
|
||||
if(!istype(L))
|
||||
to_chat(usr, "This can only be used on instances of type /list")
|
||||
return TRUE
|
||||
|
||||
mod_list_add(L, null, "list", "contents")
|
||||
return TRUE
|
||||
|
||||
if(href_list["listdupes"])
|
||||
var/list/L = locate(href_list["listdupes"])
|
||||
if(!istype(L))
|
||||
to_chat(usr, "This can only be used on instances of type /list")
|
||||
return TRUE
|
||||
|
||||
uniqueList_inplace(L)
|
||||
log_to_dd("### ListVarEdit by [src]: /list contents: CLEAR DUPES")
|
||||
log_admin("[key_name(src)] modified list's contents: CLEAR DUPES")
|
||||
message_admins("[key_name_admin(src)] modified list's contents: CLEAR DUPES")
|
||||
return TRUE
|
||||
|
||||
if(href_list["listnulls"])
|
||||
var/list/L = locate(href_list["listnulls"])
|
||||
if(!istype(L))
|
||||
to_chat(usr, "This can only be used on instances of type /list")
|
||||
return TRUE
|
||||
|
||||
listclearnulls(L)
|
||||
log_to_dd("### ListVarEdit by [src]: /list contents: CLEAR NULLS")
|
||||
log_admin("[key_name(src)] modified list's contents: CLEAR NULLS")
|
||||
message_admins("[key_name_admin(src)] modified list's contents: CLEAR NULLS")
|
||||
return TRUE
|
||||
|
||||
if(href_list["listlen"])
|
||||
var/list/L = locate(href_list["listlen"])
|
||||
if(!istype(L))
|
||||
to_chat(usr, "This can only be used on instances of type /list")
|
||||
return TRUE
|
||||
var/value = vv_get_value(VV_NUM)
|
||||
if(value["class"] != VV_NUM)
|
||||
return TRUE
|
||||
|
||||
L.len = value["value"]
|
||||
log_to_dd("### ListVarEdit by [src]: /list len: [L.len]")
|
||||
log_admin("[key_name(src)] modified list's len: [L.len]")
|
||||
message_admins("[key_name_admin(src)] modified list's len: [L.len]")
|
||||
return TRUE
|
||||
|
||||
if(href_list["listshuffle"])
|
||||
var/list/L = locate(href_list["listshuffle"])
|
||||
if(!istype(L))
|
||||
to_chat(usr, "This can only be used on instances of type /list")
|
||||
return TRUE
|
||||
|
||||
shuffle_inplace(L)
|
||||
log_to_dd("### ListVarEdit by [src]: /list contents: SHUFFLE")
|
||||
log_admin("[key_name(src)] modified list's contents: SHUFFLE")
|
||||
message_admins("[key_name_admin(src)] modified list's contents: SHUFFLE")
|
||||
return TRUE
|
||||
|
||||
if(href_list["listrefresh"])
|
||||
debug_variables(locate(href_list["listrefresh"]))
|
||||
return TRUE
|
||||
Reference in New Issue
Block a user