2022-03-19 16:11:24 -07:00
|
|
|
<!DOCTYPE html>
|
|
|
|
<html lang="en">
|
|
|
|
<head>
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
<title>Map vote plugin configuration generator</title>
|
|
|
|
<style>
|
|
|
|
*
|
|
|
|
{
|
|
|
|
background-color: lightgray;
|
|
|
|
}
|
|
|
|
|
|
|
|
div#main
|
|
|
|
{
|
|
|
|
display: flex;
|
|
|
|
justify-content: space-around;
|
|
|
|
margin: auto;
|
|
|
|
}
|
|
|
|
|
|
|
|
div.pannel
|
|
|
|
{
|
|
|
|
border: black;
|
|
|
|
border-radius: 15px;
|
|
|
|
border-style: solid;
|
|
|
|
padding: 10px;
|
|
|
|
padding-bottom: 30px;
|
|
|
|
}
|
|
|
|
|
|
|
|
li.rule
|
|
|
|
{
|
|
|
|
border: 1px solid black;
|
|
|
|
border-radius: 10px;
|
|
|
|
padding: 5px;
|
|
|
|
margin: 2px;
|
|
|
|
}
|
|
|
|
|
|
|
|
ul.rules
|
|
|
|
{
|
|
|
|
margin: 5px;
|
|
|
|
padding: 2px;
|
|
|
|
overflow: clip;
|
|
|
|
overflow-y: scroll;
|
|
|
|
width: 82ch;
|
|
|
|
height: 100ch;
|
|
|
|
border: solid black;
|
|
|
|
}
|
|
|
|
|
|
|
|
ul.nomination_list
|
|
|
|
{
|
|
|
|
list-style-type: none;
|
|
|
|
padding: 2px;
|
|
|
|
margin-top: 2px;
|
|
|
|
margin-bottom: 2px;
|
|
|
|
width: 75ch;
|
|
|
|
min-height: 5ch;
|
|
|
|
border: solid black;
|
|
|
|
}
|
|
|
|
|
|
|
|
ul.border_list
|
|
|
|
{
|
|
|
|
list-style-type: none;
|
|
|
|
margin: 5px;
|
|
|
|
padding: 2px;
|
|
|
|
overflow: clip;
|
|
|
|
overflow-y: scroll;
|
|
|
|
width: 75ch;
|
|
|
|
height: 10ch;
|
|
|
|
border: solid black;
|
|
|
|
}
|
|
|
|
|
|
|
|
li.selected
|
|
|
|
{
|
|
|
|
background-color: cadetblue;
|
|
|
|
}
|
|
|
|
|
|
|
|
div#info
|
|
|
|
{
|
|
|
|
margin: 2%;
|
|
|
|
}
|
|
|
|
|
|
|
|
li.nomination
|
|
|
|
{
|
|
|
|
border: 1px solid black;
|
|
|
|
margin: 5px;
|
|
|
|
padding: 5px;
|
|
|
|
}
|
|
|
|
|
|
|
|
input.short_input
|
|
|
|
{
|
|
|
|
width: 10ch;
|
|
|
|
}
|
|
|
|
|
|
|
|
input.rule_input
|
|
|
|
{
|
|
|
|
width: 30ch;
|
|
|
|
}
|
2022-03-22 12:53:21 -07:00
|
|
|
|
|
|
|
.graph_container
|
|
|
|
{
|
|
|
|
overflow: hidden;
|
|
|
|
}
|
2022-03-19 16:11:24 -07:00
|
|
|
</style>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div id="main">
|
|
|
|
<div id="left" class="pannel">
|
|
|
|
<div id="controls">
|
|
|
|
<button id="save">save</button>
|
|
|
|
<input type="file" id="load" accept=".json">
|
|
|
|
</div>
|
|
|
|
<div id="rules_pannel">
|
|
|
|
<h3>vote rules:</h3>
|
|
|
|
<button id="add_rule">add rule</button>
|
|
|
|
<ul id="rules_list" class="rules"></ul>
|
|
|
|
</div>
|
|
|
|
<div id="modes">
|
|
|
|
<h3>mode strings (case sensitive):</h3>
|
|
|
|
<ul id="modes_list" class="border_list"></ul>
|
|
|
|
<input type="text" id="mode_input">
|
|
|
|
<button id="add_mode">add</button>
|
|
|
|
<button id="remove_mode">remove</button>
|
|
|
|
</div>
|
|
|
|
<div id="addons">
|
|
|
|
<h3>addon layer strings:</h3>
|
|
|
|
(not currently implemented)
|
|
|
|
<ul id="addons_list"></ul>
|
|
|
|
<input type="text">
|
|
|
|
<button>add</button>
|
|
|
|
<button>remove</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div id="info">
|
|
|
|
<h3>info:</h3>
|
|
|
|
tool by maskedmonkyman <br>
|
|
|
|
version 1.0 <br>
|
|
|
|
<h4>warning:</h4>
|
|
|
|
<p>
|
|
|
|
this tool is a thin wrapper around
|
|
|
|
the Squad JS pluggin config schemea. This tool
|
|
|
|
does <b>NO INPUT VALIDATION</b> and is just a graphical utility.
|
|
|
|
It is very possible to create broken configs using
|
|
|
|
this tool. Be sure to check your inputs.
|
|
|
|
</p>
|
|
|
|
|
|
|
|
<h4>notes:</h4>
|
|
|
|
<ol>
|
|
|
|
<li>
|
|
|
|
be sure to always have a "defualt" vote rule.
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
the Any option for modes, will select modes from the
|
|
|
|
mode strings section so be sure to fill it out.
|
|
|
|
</li>
|
|
|
|
</ol>
|
|
|
|
</p>
|
2022-03-22 12:53:21 -07:00
|
|
|
<button onclick="render_graph()">render graph</button>
|
|
|
|
<div class="pannel" style="width: 95%;">
|
|
|
|
<div id="graph_container" class="graph_container"></div>
|
|
|
|
</div>
|
2022-03-19 16:11:24 -07:00
|
|
|
</div>
|
|
|
|
</div>
|
2022-03-22 12:53:21 -07:00
|
|
|
<script src="./config_scripts/viz.js"></script>
|
|
|
|
<script src="./config_scripts/full.render.js"></script>
|
|
|
|
<script src="./config_scripts/svg-pan-zoom.min.js" type="text/javascript" charset="utf-8"></script>
|
2022-03-19 16:11:24 -07:00
|
|
|
<script>
|
|
|
|
"use strict";
|
|
|
|
//TODO addon layers
|
|
|
|
const save_button = document.getElementById("save");
|
|
|
|
const load_button = document.getElementById("load");
|
|
|
|
//rules
|
|
|
|
const add_rule_button = document.getElementById("add_rule");
|
|
|
|
const remove_rule_button = document.getElementById("remove_rule");
|
|
|
|
const rules_list = document.getElementById("rules_list");
|
|
|
|
let selected_rule = null;
|
|
|
|
//mode
|
|
|
|
const add_mode_button = document.getElementById("add_mode");
|
|
|
|
const remove_mode_button = document.getElementById("remove_mode");
|
|
|
|
const mode_input = document.getElementById("mode_input");
|
|
|
|
const modes_list = document.getElementById("modes_list");
|
|
|
|
let selected_mode = null;
|
|
|
|
|
2022-03-22 12:53:21 -07:00
|
|
|
let svg_element = null;
|
|
|
|
|
|
|
|
function fetch_layer_strings()
|
|
|
|
{
|
|
|
|
const wiki_url = "https://raw.githubusercontent.com/Squad-Wiki-Editorial/squad-wiki-pipeline-map-data/master/completed_output/_Current%20Version/finished.json";
|
|
|
|
let layer_strings = [];
|
|
|
|
|
|
|
|
fetch(wiki_url).then(response=>response.json()).then(function(response){
|
|
|
|
for(const layer of response.Maps)
|
|
|
|
layer_strings.push(layer.rawName);
|
|
|
|
});
|
|
|
|
|
|
|
|
return layer_strings;
|
|
|
|
}
|
|
|
|
|
|
|
|
function render_graph()
|
|
|
|
{
|
|
|
|
const graph = build_graph_string(build_vote_rules());
|
|
|
|
//let layer_strings = fetch_layer_strings();
|
|
|
|
var viz = new Viz();
|
|
|
|
|
|
|
|
if (svg_element)
|
|
|
|
svg_element.parentNode.removeChild(svg_element);
|
|
|
|
|
|
|
|
viz.renderSVGElement(graph, {"engine" : "circo"})
|
|
|
|
.then(function(element) {
|
|
|
|
svg_element = element;
|
|
|
|
|
|
|
|
//set svg to the size of it's container
|
|
|
|
svg_element.setAttribute("width", "100%");
|
|
|
|
//remove height initially to auto scale
|
|
|
|
svg_element.removeAttribute("height");
|
|
|
|
|
|
|
|
document.getElementById("graph_container").appendChild(svg_element);
|
|
|
|
let panZoom = svgPanZoom(svg_element, {
|
|
|
|
zoomEnabled: true,
|
|
|
|
controlIconsEnabled: true,
|
|
|
|
fit: false,
|
|
|
|
center: true
|
|
|
|
});
|
|
|
|
|
|
|
|
//hacky work around for pan zoom so it scale properly
|
|
|
|
svg_element.setAttribute("height", `${panZoom.getSizes().height}px`)
|
|
|
|
})
|
|
|
|
.catch(error => {
|
|
|
|
// Create a new Viz instance (@see Caveats page for more info)
|
|
|
|
viz = new Viz();
|
|
|
|
|
|
|
|
// Possibly display the error
|
|
|
|
console.error(error);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function build_graph_string(vote_rules)
|
|
|
|
{
|
|
|
|
let graph = "digraph G \n";
|
|
|
|
graph += "\{";
|
|
|
|
let rules = vote_rules.rules;
|
|
|
|
for(const rule in rules)
|
|
|
|
{
|
|
|
|
const nomination = rules[rule];
|
|
|
|
|
|
|
|
for (const layer of nomination)
|
|
|
|
{
|
|
|
|
graph += `${rule} -> ${layer.map}\n`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
graph += "\}";
|
|
|
|
return graph;
|
|
|
|
}
|
|
|
|
|
2022-03-21 17:35:36 -07:00
|
|
|
function build_vote_rules()
|
|
|
|
{
|
|
|
|
let vote_rules = {
|
|
|
|
"modes": [],
|
|
|
|
"rules": {},
|
|
|
|
"addon_map_layer_strings": []
|
|
|
|
};
|
|
|
|
|
|
|
|
for(let mode of modes_list.children)
|
|
|
|
{
|
|
|
|
vote_rules.modes.push(mode.innerHTML.trim());
|
|
|
|
}
|
|
|
|
|
|
|
|
for(let rule_element of rules_list.children)
|
|
|
|
{
|
|
|
|
let rule = {
|
|
|
|
"name": rule_element.rule_string_input.value,
|
|
|
|
"nominations": []
|
|
|
|
};
|
|
|
|
for (let nomination of rule_element.nomination_list.children)
|
|
|
|
{
|
|
|
|
rule.nominations.push({
|
|
|
|
"map": nomination.map_input.value.trim(),
|
|
|
|
"modes": nomination.mode_input.value.trim().split(',').map(e => e.trim()),
|
|
|
|
"versions": nomination.verison_input.value.trim().split(',').map(e => e.trim())
|
|
|
|
});
|
|
|
|
}
|
|
|
|
vote_rules.rules[rule.name] = rule.nominations;
|
|
|
|
}
|
|
|
|
|
|
|
|
return vote_rules;
|
|
|
|
}
|
|
|
|
|
2022-03-19 16:11:24 -07:00
|
|
|
add_rule_button.onclick = ()=>{
|
|
|
|
let rule = build_rule_element();
|
|
|
|
rules_list.appendChild(rule);
|
|
|
|
};
|
|
|
|
|
|
|
|
add_mode_button.onclick = () => {
|
|
|
|
if (mode_input.value == "")
|
|
|
|
return;
|
|
|
|
add_mode(mode_input.value);
|
|
|
|
};
|
|
|
|
|
|
|
|
function add_mode(mode_string)
|
|
|
|
{
|
|
|
|
let mode = document.createElement("li");
|
|
|
|
mode.innerHTML = mode_string;
|
|
|
|
modes_list.appendChild(mode);
|
|
|
|
mode.onclick = () => {
|
|
|
|
if (selected_mode)
|
|
|
|
{
|
|
|
|
selected_mode.classList.remove("selected");
|
|
|
|
}
|
|
|
|
selected_mode = mode;
|
|
|
|
selected_mode.classList.add("selected");
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
remove_mode_button.onclick = () => {
|
|
|
|
if (selected_mode)
|
|
|
|
{
|
|
|
|
selected_mode.parentNode.removeChild(selected_mode);
|
|
|
|
selected_mode = null;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
save_button.onclick = () => {
|
2022-03-21 17:35:36 -07:00
|
|
|
let vote_rules = build_vote_rules();
|
2022-03-19 16:11:24 -07:00
|
|
|
var a = document.createElement("a");
|
|
|
|
a.href = window.URL.createObjectURL(new Blob([JSON.stringify(vote_rules)], {type: "text/plain"}));
|
|
|
|
a.download = "vote_rules.json";
|
|
|
|
a.click();
|
|
|
|
};
|
|
|
|
|
|
|
|
load_button.onchange = () => {
|
|
|
|
let reader = new FileReader();
|
2022-03-22 13:07:42 -07:00
|
|
|
rules_list.innerHTML = "";
|
|
|
|
modes_list.innerHTML = "";
|
2022-03-19 16:11:24 -07:00
|
|
|
reader.addEventListener("load", (event) => {
|
|
|
|
let vote_rules = JSON.parse(event.target.result);
|
2022-03-22 13:11:37 -07:00
|
|
|
|
2022-03-19 16:11:24 -07:00
|
|
|
for (let mode of vote_rules.modes)
|
|
|
|
add_mode(mode);
|
2022-03-22 13:11:37 -07:00
|
|
|
|
2022-03-22 13:15:32 -07:00
|
|
|
let rules = Object.keys(vote_rules.rules).sort();
|
2022-03-22 13:11:37 -07:00
|
|
|
|
|
|
|
for (let rule of rules)
|
2022-03-19 16:11:24 -07:00
|
|
|
{
|
|
|
|
let rule_element = build_rule_element();
|
|
|
|
rule_element.rule_string_input.value = rule;
|
|
|
|
rules_list.appendChild(rule_element);
|
|
|
|
for(let nomination of vote_rules.rules[rule])
|
|
|
|
{
|
|
|
|
let nomination_element = build_nomination_element(nomination.map, nomination.modes, nomination.versions);
|
|
|
|
rule_element.nomination_list.appendChild(nomination_element);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
reader.readAsText(load_button.files[0]);
|
|
|
|
};
|
|
|
|
|
|
|
|
function build_rule_element()
|
|
|
|
{
|
|
|
|
let rule = document.createElement("li");
|
|
|
|
rule.classList.add("rule");
|
|
|
|
let label = document.createElement("label");
|
|
|
|
label.innerHTML = "Rule string: ";
|
|
|
|
let input = document.createElement("input");
|
|
|
|
input.setAttribute("type", "text");
|
|
|
|
input.classList.add("rule_input");
|
|
|
|
label.appendChild(input);
|
|
|
|
rule.appendChild(label);
|
|
|
|
rule["rule_string_input"] = input;
|
|
|
|
|
|
|
|
let add_nomination_button = document.createElement("button");
|
|
|
|
add_nomination_button.innerHTML = "add nomination";
|
|
|
|
rule.appendChild(add_nomination_button);
|
|
|
|
|
|
|
|
let nominations_list = document.createElement("ul");
|
|
|
|
nominations_list.classList.add("nomination_list");
|
|
|
|
rule.appendChild(nominations_list);
|
|
|
|
rule["nomination_list"] = nominations_list;
|
|
|
|
|
|
|
|
let delete_button = document.createElement("button");
|
|
|
|
delete_button.innerHTML = "delete";
|
|
|
|
rule.appendChild(delete_button);
|
|
|
|
|
|
|
|
add_nomination_button.onclick = () => {
|
|
|
|
nominations_list.appendChild(build_nomination_element());
|
|
|
|
};
|
|
|
|
|
|
|
|
delete_button.onclick = () => {
|
|
|
|
rule.parentNode.removeChild(rule);
|
|
|
|
}
|
|
|
|
return rule;
|
|
|
|
}
|
|
|
|
|
|
|
|
function build_nomination_element(map_string = "", mode_string = "Any", version_string = "Any")
|
|
|
|
{
|
|
|
|
let nomination = document.createElement("li");
|
|
|
|
nomination.classList.add("nomination");
|
|
|
|
|
|
|
|
//map field
|
|
|
|
let map_label = document.createElement("label");
|
|
|
|
map_label.innerHTML = "Map:";
|
|
|
|
nomination.appendChild(map_label);
|
|
|
|
let map_input = document.createElement("input");
|
|
|
|
map_input.setAttribute("type", "text");
|
|
|
|
map_input.value = map_string;
|
|
|
|
map_label.appendChild(map_input);
|
|
|
|
nomination["map_input"] = map_input;
|
|
|
|
|
|
|
|
//mode field
|
|
|
|
let mode_label = document.createElement("label");
|
|
|
|
mode_label.innerHTML = "Mode(s):";
|
|
|
|
nomination.appendChild(mode_label);
|
|
|
|
let mode_input = document.createElement("input");
|
|
|
|
mode_input.setAttribute("type", "text");
|
|
|
|
mode_input.classList.add("short_input");
|
|
|
|
mode_input.value = mode_string;
|
|
|
|
mode_label.appendChild(mode_input);
|
|
|
|
nomination["mode_input"] = mode_input;
|
|
|
|
|
|
|
|
//version feild
|
|
|
|
let version = document.createElement("label");
|
|
|
|
version.innerHTML = "Version(s):";
|
|
|
|
nomination.appendChild(version);
|
|
|
|
let verison_input = document.createElement("input");
|
|
|
|
verison_input.setAttribute("type", "text");
|
|
|
|
verison_input.classList.add("short_input");
|
|
|
|
verison_input.value = version_string;
|
|
|
|
version.appendChild(verison_input);
|
|
|
|
nomination["verison_input"] = verison_input;
|
|
|
|
|
|
|
|
//delete button
|
|
|
|
let delete_button = document.createElement("button");
|
|
|
|
delete_button.innerHTML = "delete";
|
|
|
|
delete_button.onclick = () => {
|
|
|
|
nomination.parentNode.removeChild(nomination);
|
|
|
|
};
|
|
|
|
nomination.appendChild(delete_button);
|
|
|
|
|
|
|
|
return nomination;
|
|
|
|
}
|
|
|
|
|
|
|
|
function main()
|
|
|
|
{
|
|
|
|
console.log("hello world");
|
|
|
|
}
|
|
|
|
|
|
|
|
document.addEventListener("DOMContentLoaded", main);
|
|
|
|
</script>
|
|
|
|
</body>
|
|
|
|
</html>
|