show.js
1 2 var g_sim_logs = ''; 3 var g_my_login = 0; 4 var g_rand_prev; 5 var g_rand_repl = []; 6 var g_eval_lvls; 7 8 9 function my_console_log(str) 10 { 11 // console.log(str); 12 } 13 14 15 function hash_login(login) 16 { 17 var seed = 0; 18 for (var i = 0; i < login.length; i ++) 19 { 20 if (i%2 == 0) 21 seed += 973 * (login.charCodeAt(i)+i); 22 else 23 seed += 5 * login.charCodeAt(i) * i; 24 } 25 // console.log("hash login : '"+login+"' -> "+seed); 26 return (seed); 27 } 28 29 30 function err(thetype, field) 31 { 32 my_console_log("Fatal error in "+thetype+", on field "+field); 33 throw ''; 34 } 35 36 37 function my_random(a, b) 38 { 39 if (g_my_login == '') 40 return (Math.round(parseInt(a) + (parseInt(b)-parseInt(a))*Math.random())); 41 var prev = g_rand_prev; 42 prev ^= prev << 13; 43 prev ^= prev >> 17; 44 prev ^= prev << 5; 45 g_rand_prev = prev; 46 prev = (prev & 0x7FFFFFFF) % (parseInt(b)-parseInt(a)+1); 47 return (Math.round(parseInt(a) + prev)); 48 } 49 50 function random_repl(str) 51 { 52 var regex = /\[(\d+)-(\d+)\]([a-z])/g; 53 var res; 54 var str2 = str; 55 while (res = regex.exec(str)) 56 { 57 my_console_log(res); 58 g_rand_repl[res[3]] = my_random(res[1], res[2]); 59 str2 = str2.replace(res[0], ""+g_rand_repl[res[3]]); 60 my_console_log(str2); 61 } 62 regex = /\[([a-z])\]/g; 63 while (res = regex.exec(str)) 64 { 65 my_console_log(res); 66 if (g_rand_repl[res[1]] != null) 67 { 68 str2 = str2.replace(res[0], ""+g_rand_repl[res[1]]); 69 my_console_log(str2); 70 } 71 else 72 return (null); 73 } 74 75 if (str2 == "default") return (str2); 76 // check if any non digital, non dot, non slash char, except previous line 77 regex = /[^\d\.\/]/g; 78 if (regex.exec(str2)) 79 return (null); 80 81 return (str2); 82 } 83 84 function show_host(root, h) 85 { 86 if (!h['id']) err("hosts", "id"); 87 if (!h['type']) err("hosts id "+h['id'], "type"); 88 if (!h['name']) err("hosts id "+h['id'], "name"); 89 if (!h['geometry']) err("hosts id "+h['id'], "geometry"); 90 if (!h['img']) err("hosts id "+h['id'], "img"); 91 92 var tab = h['geometry'].split(/[^0-9]+/); 93 if (tab.length != 4) err("hosts id "+h['id'], "geometry parsing"); 94 h['w'] = parseInt(tab[0]); 95 h['h'] = parseInt(tab[1]); 96 h['x'] = parseInt(tab[2]); 97 h['y'] = parseInt(tab[3]); 98 99 var newelem = document.createElement('div'); 100 newelem.className = 'host_div'; 101 newelem.style.position = "absolute"; 102 newelem.style.width = h['w']+'px'; 103 newelem.style.height = h['h']+'px'; 104 newelem.style.top = h['y'] + 'px'; 105 newelem.style.left = h['x'] + 'px'; 106 newelem.style.backgroundImage = 'url(img/'+h['img']+')'; 107 root.appendChild(newelem); 108 109 // label + routes 110 var tab = h['labelpos'].split(','); 111 if (tab.length != 2) err("host id "+h['id'], "labelpos parsing"); 112 h['lx'] = parseInt(tab[0]); 113 h['ly'] = parseInt(tab[1]); 114 115 var newelem = document.createElement('div'); 116 newelem.className = 'host_info_div'; 117 newelem.style.position = "absolute"; 118 newelem.style.top = (h['y']+h['ly'])+'px'; 119 newelem.style.left = (h['x']+h['lx'])+'px'; 120 var label = '<table><tr><td>'+h['type']+' '+h['id']+': <i>'+h['name']+'</id></td></tr>'; 121 var str = ''; 122 routes.forEach(r => {if (h['id'] == r['hid']) { str += '<tr><td>'+get_route_info(r)+'</td></tr>\n'; r['h'] = h;}}); 123 if (str != '') label += '<tr><td>Routes :</td></tr>\n'+str; 124 label += '</table>'; 125 newelem.innerHTML = label; 126 root.appendChild(newelem); 127 128 } 129 130 131 132 function get_route_info(r) 133 { 134 if (!r['rid']) err("route", "rid"); 135 if (!r['hid']) err("route id "+r['rid'], "hid"); 136 if (!r['route']) err("route id "+r['rid'], "route"); 137 if (!r['route_edit']) err("route id "+r['rid'], "route_edit"); 138 if (!r['gate']) err("route id "+r['rid'], "gate"); 139 if (!r['gate_edit']) err("route id "+r['rid'], "gate_edit"); 140 141 if ((r['route'] = random_repl(r['route'])) == null) err("route id "+r['rid'], "route ip random syntax"); 142 if ((r['gate'] = random_repl(r['gate'])) == null) err("route id "+r['rid'], "gate random syntax"); 143 144 if (r['route_edit'] == 'true') route_active = ''; else route_active = 'disabled'; 145 if (r['gate_edit'] == 'true') gate_active = ''; else gate_active = 'disabled'; 146 var routestr = '<input size=15 type=text id=route_'+r['rid']+' value="'+r['route']+'" '+route_active+'> => <input size=15 type=text id=gate_'+r['rid']+' value="'+r['gate']+'" '+gate_active+'>'; 147 // my_console_log("add label route : ##"+routestr); 148 return (routestr); 149 } 150 151 152 153 function show_ifs(root, itf) 154 { 155 if (!itf['if']) err("ifs", "if"); 156 if (!itf['hid']) err("ifs "+itf['if'], "hid"); 157 if (!itf['ip']) err("ifs "+itf['if'], "ip"); 158 if (!itf['mask']) err("ifs "+itf['if'], "mask"); 159 if (!itf['ip_edit']) err("ifs "+itf['if'], "ip_edit"); 160 if (!itf['mask_edit']) err("ifs "+itf['if'], "mask_edit"); 161 if (!itf['type']) err("ifs "+itf['if'], "type"); 162 if (!itf['pos']) err("ifs "+itf['if'], "pos"); 163 164 if ((itf['ip'] = random_repl(itf['ip'])) == null) err("ifs "+itf['if'], "ip random syntax"); 165 if ((itf['mask'] = random_repl(itf['mask'])) == null) err("ifs "+itf['if'], "mask random syntax"); 166 167 hosts.forEach(h => {if (itf['hid'] == h['id']) itf['h'] = h}); 168 169 var tab = itf['pos'].split(','); 170 if (tab.length != 2) err("ifs id "+itf['if'], "pos parsing"); 171 itf['dx'] = parseInt(tab[0]); 172 itf['dy'] = parseInt(tab[1]); 173 174 if (itf['type'] == 'std') 175 { 176 var newelem = document.createElement('div'); 177 newelem.className = 'itf_div'; 178 newelem.style.position = "absolute"; 179 newelem.style.top = (itf['h']['y']+itf['dy'])+'px'; 180 newelem.style.left = (itf['h']['x']+itf['dx'])+'px'; 181 if (itf['ip_edit'] == 'true') ip_active = ''; else ip_active = 'disabled'; 182 if (itf['mask_edit'] == 'true') mask_active = ''; else mask_active = 'disabled'; 183 newelem.innerHTML = 'Interface '+itf['if']+'<br />IP : <input size=15 type=text id=ip_'+itf['if']+' value="'+itf['ip']+'" '+ip_active+'><br />Mask : <input size=15 type=text id=mask_'+itf['if']+' value="'+itf['mask']+'" '+mask_active+'>'; 184 root.appendChild(newelem); 185 } 186 } 187 188 189 190 191 192 function draw_links(root, l) 193 { 194 if (!l['if1'] || !l['if2']) err("links", "id"); 195 196 ifs.forEach(i => {if (i['if'] == l['if1']) l['e1'] = i}); 197 ifs.forEach(i => {if (i['if'] == l['if2']) l['e2'] = i}); 198 199 hosts.forEach(h => {if (h['id'] == l['e1']['hid']) l['h1'] = h}); 200 hosts.forEach(h => {if (h['id'] == l['e2']['hid']) l['h2'] = h}); 201 202 var aLine = document.createElementNS('http://www.w3.org/2000/svg', 'line'); 203 aLine.setAttribute('id', 'link_'+l['if1']+'_'+l['if2']); 204 aLine.id = 'link_'+l['if1']+'_'+l['if2']; 205 aLine.setAttribute('x1', ""+(parseInt(l['h1']['x'])+parseInt(l['h1']['w'])/2)); 206 aLine.setAttribute('y1', ""+(parseInt(l['h1']['y'])+parseInt(l['h1']['h'])/2)); 207 aLine.setAttribute('x2', ""+(parseInt(l['h2']['x'])+parseInt(l['h2']['w'])/2)); 208 aLine.setAttribute('y2', ""+(parseInt(l['h2']['y'])+parseInt(l['h2']['h'])/2)); 209 aLine.setAttribute('stroke', "black"); 210 aLine.setAttribute('stroke-width', 3); 211 (document.getElementById('sl')).appendChild(aLine); 212 } 213 214 215 function prep_goals(g) 216 { 217 if (!g['id']) err("goals", "id"); 218 if (!g['type']) err("goals "+g['id'], "type"); 219 if (g['type'] == 'reach') 220 { 221 if (!g['id1']) err("goals "+g['id'], "id1"); 222 if (!g['id2']) err("goals "+g['id'], "id2"); 223 hosts.forEach(h => {if (h['id'] == g['id1']) g['h1'] = h}); 224 hosts.forEach(h => {if (h['id'] == g['id2']) g['h2'] = h}); 225 } 226 if (g['type'] == 'reach_if') 227 { 228 if (!g['if_id1']) err("goals "+g['id'], "if_id1"); 229 if (!g['if_id2']) err("goals "+g['id'], "if_id2"); 230 ifs.forEach(itf => {if (itf['if'] == g['if_id1']) { g['h1'] = itf['h']; g['if1'] = itf;}}); 231 ifs.forEach(itf => {if (itf['if'] == g['if_id2']) { g['h2'] = itf['h']; g['if2'] = itf;}}); 232 } 233 } 234 235 236 function next_eval() 237 { 238 if (g_eval_lvls.length >= 3) 239 return ('end.html'); 240 var lvl; 241 do { 242 lvl = Math.round(6 + 4*Math.random()); 243 } while (g_eval_lvls.includes(lvl)) 244 g_eval_lvls.push(lvl); 245 localStorage.setItem("g_my_eval", JSON.stringify(g_eval_lvls)); 246 return ('level'+lvl+'.html'); 247 } 248 249 250 function my_download(filename, text) 251 { 252 var element = document.createElement('a'); 253 element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); 254 element.setAttribute('download', filename); 255 256 element.style.display = 'none'; 257 document.body.appendChild(element); 258 259 element.click(); 260 261 document.body.removeChild(element); 262 } 263 264 function dl_config() 265 { 266 var infos = { 'routes':{}, 'ifs':{} }; 267 routes.forEach(elem => { infos['routes'][elem['rid']] = {}; 268 if (elem['route_edit'] == 'true') infos['routes'][elem['rid']]['route'] = document.getElementById('route_'+elem['rid']).value; 269 if (elem['gate_edit'] == 'true') infos['routes'][elem['rid']]['gate'] = document.getElementById('gate_'+elem['rid']).value; 270 }); 271 ifs.forEach(elem => { infos['ifs'][elem['if']] = {}; 272 if (elem['ip_edit'] == 'true') infos['ifs'][elem['if']]['ip'] = document.getElementById('ip_'+elem['if']).value; 273 if (elem['mask_edit'] == 'true') infos['ifs'][elem['if']]['mask'] = document.getElementById('mask_'+elem['if']).value; 274 }); 275 my_download('level'+level+'.json', JSON.stringify(infos)); 276 } 277 278 279 function show_goals(g) 280 { 281 g_sim_logs += '******* Goal ID '+g['id']+' ********\n'; 282 var div = document.getElementById("goals_id"); 283 div.innerHTML += 'Goal '+g['id']+' : '; 284 if (g['type'] == 'reach') 285 { 286 var obj = sim_goal(g); 287 div.innerHTML += '<i>'+g['h1']['name']+'</i> need to communicate with <i>'+g['h2']['name']+'</i> - Status : '+obj.text; 288 } 289 if (g['type'] == 'reach_if') 290 { 291 var obj = sim_goal(g); 292 div.innerHTML += 'Interface <i>'+g['if1']['if']+'</i> need to communicate with interface <i>'+g['if2']['if']+'</i> - Status : '+obj.text; 293 } 294 div.innerHTML += '<br />\n'; 295 return (obj.status); 296 } 297 298 299 function all_goals() 300 { 301 if (g_my_login != '') 302 g_sim_logs = '** generated for login "'+g_my_login+'" **\n'; 303 else 304 g_sim_logs = '** evaluation mode round '+g_eval_lvls.length+'**\n'; 305 document.getElementById("goals_id").innerHTML = '<h2>Level '+level+' : </h2>\n'; 306 var nb = 0; 307 goals.forEach(elem => nb += show_goals(elem)); 308 document.getElementById("goals_id").innerHTML += '<input type=button value="Check again" onclick="all_goals();"> <input type=button value="Get my config" onclick="dl_config();">'; 309 if (nb == goals.length) 310 { 311 if (g_my_login != '') 312 { 313 if (level < 10) 314 document.getElementById("goals_id").innerHTML += " <input type=button value='Next level' onclick='window.location=\"level"+(level+1)+".html\";'>"; 315 else 316 document.getElementById("goals_id").innerHTML += " <input type=button value='Complete !' onclick='window.location=\"end.html\";'>"; 317 } 318 else 319 { // defense case 320 document.getElementById("goals_id").innerHTML += " <input type=button value='Next' onclick='window.location=next_eval();'>"; 321 } 322 } 323 document.getElementById("logs_id").innerHTML = g_sim_logs.replace(/\n/g, '<br />'); 324 } 325 326 327 function load_board() 328 { 329 if (!(g_my_login = localStorage.getItem("g_my_login"))) 330 g_my_login = ''; // will means evaluation & full random 331 g_rand_prev = level + hash_login(g_my_login); // initialize replayable pseudo random generator 332 if (g_my_login == '') 333 g_eval_lvls = JSON.parse(localStorage.getItem("g_my_eval")); 334 335 var root = document.getElementById("root_id"); 336 337 hosts.forEach(elem => show_host(root, elem)); 338 339 ifs.forEach(elem => show_ifs(root, elem)); 340 341 links.forEach(elem => draw_links(root, elem)); 342 343 goals.forEach(elem => prep_goals(elem)); 344 all_goals(); 345 // only for very first time : don't show any log 346 document.getElementById("logs_id").innerHTML = 'Logs will be displayed here'; 347 }