395 lines
11 KiB
JavaScript
Executable File
395 lines
11 KiB
JavaScript
Executable File
// Heavily-modified version of the xash.html set-up script
|
|
// from Xash3d-Emscripten
|
|
|
|
var statusElement = document.getElementById('status');
|
|
var progressElement = document.getElementById('progress');
|
|
var asyncDialog = document.getElementById('asyncDialog');
|
|
var myerrorbuf = ''
|
|
var myerrordate = new Date();
|
|
var mounted = false;
|
|
var gamedir = 'valve';
|
|
var moduleCount = 0;
|
|
//var mem = 150;
|
|
var mfs;
|
|
var zipSize;
|
|
var modPackage;
|
|
|
|
// // make BrowserFS to work on ES5 browsers
|
|
// if (!ArrayBuffer['isView']) {
|
|
// ArrayBuffer.isView = function(a) {
|
|
// return a !== null && typeof(a) === "object" && a['buffer'] instanceof ArrayBuffer;
|
|
// };
|
|
|
|
// }
|
|
|
|
// showElement('optionsTitle', false);
|
|
|
|
// function prepareSelects()
|
|
// {
|
|
// var len = zipMods.length;
|
|
// var select = document.getElementById('selectZip');
|
|
// if( len )
|
|
// {
|
|
// showElement('zipHider', true);
|
|
|
|
// if(len > 1)
|
|
// {
|
|
// var links = '';
|
|
// for(var i = 0; i < len; i++)
|
|
// {
|
|
// select.options[i] = new Option(zipMods[i][1], zipMods[i][0]);
|
|
// links += '<br><a href="'+zipMods[i][0]+'">'+zipMods[i][1]+'</a>';
|
|
// }
|
|
// select.style.display = 'block';
|
|
// document.getElementById('linksPlaceholder').innerHTML += links;
|
|
// showElement('linksPlaceholder', true);
|
|
// }
|
|
// }
|
|
// else
|
|
// document.getElementById('rZip').checked = false;
|
|
// len = pkgMods.length;
|
|
// select = document.getElementById('selectPkg');
|
|
// if( len )
|
|
// {
|
|
// showElement('pkgHider', true);
|
|
|
|
// if(len > 1)
|
|
// {
|
|
// for(var i = 0; i < len; i++)
|
|
// select.options[i] = new Option(pkgMods[i][1], pkgMods[i][0]);
|
|
// select.style.display = 'block';
|
|
// }
|
|
// }
|
|
// else
|
|
// document.getElementById('rPackage').checked = false;
|
|
|
|
// if( !zipMods.length && !len )
|
|
// {
|
|
// document.getElementById('rLocalZip').checked = true;
|
|
// showElement('rLocalZip', false);
|
|
// }
|
|
// }
|
|
|
|
try{mem = Math.round(window.location.hash.substring(1));}catch(e){};
|
|
|
|
function wrapPrint(func) {
|
|
return (...args) => {
|
|
if(args.length > 0)
|
|
instance.console[func](...args)
|
|
}
|
|
}
|
|
|
|
var Module = {
|
|
TOTAL_MEMORY: mem * 1024 * 1024,
|
|
preRun: [],
|
|
postRun: [],
|
|
// print: (function() {
|
|
// var element = document.getElementById('output');
|
|
// if (element) element.value = ''; // clear browser cache
|
|
// return function(text) {
|
|
// if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
|
|
// // These replacements are necessary if you render to raw HTML
|
|
// //text = text.replace(/&/g, "&");
|
|
// //text = text.replace(/</g, "<");
|
|
// //text = text.replace(/>/g, ">");
|
|
// //text = text.replace('\n', '<br>', 'g');
|
|
// //console.log(text);
|
|
// if(text)
|
|
// myerrorbuf += text + '\n';
|
|
// if (element) {
|
|
// if(element.value.length > 65536)
|
|
// element.value = element.value.substring(512) + myerrorbuf;
|
|
// else
|
|
// element.value += myerrorbuf;
|
|
// element.scrollTop = element.scrollHeight; // focus on bottom
|
|
// }
|
|
// myerrorbuf = ''
|
|
// };
|
|
// })(),
|
|
print: wrapPrint('log'),
|
|
// printErr: function(text) {
|
|
// if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
|
|
// if (0) { // XXX disabled for safety typeof dump == 'function') {
|
|
// dump(text + '\n'); // fast, straight to the real console
|
|
// } else {
|
|
// if( myerrorbuf.length > 2048 )
|
|
// myerrorbuf = 'some lines skipped\n'+ myerrorbuf.substring(512);
|
|
// myerrorbuf += text + '\n';
|
|
// if( new Date() - myerrordate > 3000 )
|
|
// {
|
|
// myerrordate = new Date();
|
|
// Module.print();
|
|
// }
|
|
// }
|
|
// },
|
|
printErr: wrapPrint('error'),
|
|
canvas: (function() {
|
|
var canvas = document.getElementById('canvas');
|
|
|
|
// As a default initial behavior, pop up an alert when webgl context is lost. To make your
|
|
// application robust, you may want to override this behavior before shipping!
|
|
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
|
|
canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
|
|
|
|
return canvas;
|
|
})(),
|
|
setStatus: function(text) {
|
|
if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' };
|
|
if (text === Module.setStatus.text) return;
|
|
if( new Date() - myerrordate > 3000 )
|
|
{
|
|
myerrordate = new Date();
|
|
Module.print();
|
|
}
|
|
|
|
statusElement.innerHTML = text;
|
|
if( progressElement )
|
|
{
|
|
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
|
|
|
|
if(m)
|
|
{
|
|
var progress = Math.round(parseInt(m[2])*100/parseInt(m[4]));
|
|
progressElement.style.color = progress > 5?'#303030':'#aaa000';
|
|
progressElement.style.width = progressElement.innerHTML = ''+progress+'%';
|
|
}
|
|
showElement('progress1', !!m);
|
|
}
|
|
},
|
|
totalDependencies: 0,
|
|
monitorRunDependencies: function(left) {
|
|
this.totalDependencies = Math.max(this.totalDependencies, left);
|
|
if(left)
|
|
Module.setStatus('Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')');
|
|
},
|
|
// Added:
|
|
// This is needed for it to load the package's data from a URI
|
|
// https://emscripten.org/docs/porting/files/packaging_files.html#changing-the-data-file-location
|
|
locateFile(dataName) {
|
|
return instance.import[dataName] || modPackage.getURL(dataName)
|
|
}
|
|
//
|
|
};
|
|
|
|
function syncFS() {
|
|
FS.syncfs(false, function(err) {
|
|
instance.emulatedIDB.sync()
|
|
Module.print('Saving IDBFS' + err ? `: ${err}` : '')
|
|
})
|
|
}
|
|
|
|
window.onerror = function(event) {
|
|
if(mounted) {
|
|
// console.error('Errored: ', event)
|
|
syncFS()
|
|
} if( (''+event).indexOf('SimulateInfiniteLoop') > 0 )
|
|
return;
|
|
var text = 'Exception thrown: ' + event;
|
|
text = text.replace(/&/g, "&");
|
|
text = text.replace(/</g, "<");
|
|
text = text.replace(/>/g, ">");
|
|
text = text.replace('\n', '<br>', 'g');
|
|
Module.setStatus(text);
|
|
Module.print('Exception thrown: ' + event);
|
|
};
|
|
|
|
function haltRun()
|
|
{
|
|
}
|
|
|
|
var savedRun;
|
|
|
|
function radioChecked(id)
|
|
{
|
|
var r = document.getElementById('r'+id);
|
|
if(r) return r.checked;
|
|
return false;
|
|
}
|
|
|
|
function showElement(id, show)
|
|
{
|
|
var e = document.getElementById(id);
|
|
if(!e) return;
|
|
e.style.display=show?'block':'none';
|
|
}
|
|
|
|
Module.setStatus('Downloading...');
|
|
|
|
function startXash()
|
|
{
|
|
// showElement('loader1', false);
|
|
// showElement('optionsTitle', false);
|
|
// showElement('fSettings', false);
|
|
instance.package.then(data => {
|
|
modPackage = data
|
|
script.src = modPackage.getURL(modPackage.manifest.entry)
|
|
console.log('PAYLOAD: ', script.src)
|
|
|
|
setupFS();
|
|
})
|
|
|
|
Module.arguments = instance.arguments;
|
|
Module.run = run = savedRun;
|
|
// if( radioChecked('Zip') )
|
|
// fetchZIP(zipMods.length>1?document.getElementById('selectZip').value:zipMods[0][0], savedRun);
|
|
// else if( (!zipMods.length && !pkgMods.length) || radioChecked('LocalZip') )
|
|
// {
|
|
// var reader = new FileReader();
|
|
// reader.onload = function(){
|
|
// mountZIP(reader.result);
|
|
// Module.print("Loaded zip data");
|
|
// savedRun();
|
|
// };
|
|
// reader.readAsArrayBuffer(document.getElementById('iZipFile').files[0]);
|
|
// }
|
|
// else if( radioChecked('Package') )
|
|
// {
|
|
var script = document.createElement('script');
|
|
script.onload = savedRun;
|
|
document.body.appendChild(script);
|
|
// script.src = pkgMods.length>1?document.getElementById('selectPkg').value:pkgMods[0][0];
|
|
// }
|
|
|
|
|
|
showElement('canvas', true);
|
|
|
|
window.addEventListener("beforeunload", function (e) {
|
|
var confirmationMessage = 'Leave the game?';
|
|
|
|
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
|
|
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
|
|
});
|
|
|
|
// Added
|
|
document.addEventListener("onkeydown", function (e) {
|
|
e = e || window.event;//Get event
|
|
|
|
if (!e.ctrlKey) return;
|
|
|
|
var code = e.which || e.keyCode;//Get key code
|
|
|
|
switch (code) {
|
|
case 83://Block Ctrl+S
|
|
case 87://Block Ctrl+W -- Not work in Chrome and new Firefox
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
break;
|
|
}
|
|
})
|
|
|
|
if(instance.app.config.pauseOnLostFocus)
|
|
document.addEventListener('mouseleave', function(event) {
|
|
console.log('aaa')
|
|
canvas.dispatchEvent(new KeyboardEvent({ key: 'Esc' }))
|
|
})
|
|
}
|
|
|
|
// function mountZIP(data)
|
|
// {
|
|
// var Buffer = BrowserFS.BFSRequire('buffer').Buffer;
|
|
// mfs.mount('/zip', new BrowserFS.FileSystem.ZipFS(Buffer.from(data)));
|
|
// FS.mount(new BrowserFS.EmscriptenFS(), {root:'/zip'}, '/rodir');
|
|
// }
|
|
|
|
// function fetchZIP(packageName, cb)
|
|
// {
|
|
// var xhr = new XMLHttpRequest();
|
|
// xhr.open('GET', packageName, true);
|
|
// xhr.responseType = 'arraybuffer';
|
|
|
|
// xhr.onprogress = function(event) {
|
|
// var url = packageName;
|
|
// var size;
|
|
// if (event.total) size = event.total;
|
|
// else size = zipMods[document.getElementById('selectZip').selectedIndex][2];
|
|
// if (event.loaded) {
|
|
// var total = size;
|
|
// var loaded = event.loaded;
|
|
// var num = 0;
|
|
// if (Module['setStatus']) Module['setStatus']('Downloading data... (' + loaded + '/' + total + ')');
|
|
// } else if (!Module.dataFileDownloads) {
|
|
// if (Module['setStatus']) Module['setStatus']('Downloading data...');
|
|
// }
|
|
// };
|
|
// xhr.onerror = function(event) {
|
|
// throw new Error("NetworkError");
|
|
// }
|
|
// xhr.onload = function(event) {
|
|
// if (xhr.status == 200 || xhr.status == 304 || xhr.status == 206 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
|
|
// mountZIP(xhr.response);
|
|
// cb();
|
|
// } else {
|
|
// throw new Error(xhr.statusText + " : " + xhr.responseURL);
|
|
// }
|
|
// };
|
|
// xhr.send(null);
|
|
// }
|
|
|
|
let localForageOperations = []
|
|
|
|
function setupFS()
|
|
{
|
|
// TODO: Determined by the new "mod id"
|
|
let fsPath = '/' + modPackage.manifest.id
|
|
|
|
FS.mkdir('/rodir');
|
|
FS.mkdir(fsPath);
|
|
|
|
instance.emulatedIDB.patch(IDBFS)
|
|
|
|
FS.mount(IDBFS, {}, fsPath);
|
|
FS.syncfs(true, function(err) {
|
|
if(err)
|
|
Module.print('Loading IDBFS: ' + err)
|
|
})
|
|
mounted = true;
|
|
|
|
FS.chdir(fsPath);
|
|
}
|
|
|
|
function skipRun()
|
|
{
|
|
savedRun = run;
|
|
Module.run = haltRun;
|
|
run = haltRun;
|
|
|
|
Module.setStatus("Engine downloaded!");
|
|
// showElement('loader1', false);
|
|
// showElement('optionsTitle', true);
|
|
|
|
// if(window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB)
|
|
// showElement('idbHider', true);
|
|
// prepareSelects();
|
|
// showElement('fSettings',true);
|
|
|
|
ENV.XASH3D_GAMEDIR = gamedir;
|
|
ENV.XASH3D_RODIR = '/rodir'
|
|
|
|
function loadModule(name)
|
|
{
|
|
var script = document.createElement('script');
|
|
script.onload = function() {
|
|
moduleCount++
|
|
|
|
if(moduleCount == 3) {
|
|
Module.setStatus("Scripts downloaded!")
|
|
// We'll now wanna start xash right away
|
|
startXash()
|
|
}
|
|
}
|
|
document.body.appendChild(script);
|
|
// script.src = name + ".js";
|
|
script.src = instance.import[name + '.js']
|
|
}
|
|
|
|
loadModule("server");
|
|
loadModule("client");
|
|
loadModule("menu");
|
|
};
|
|
|
|
Module.preInit = [skipRun];
|
|
Module.websocket = [];
|
|
Module.websocket.url = 'wsproxy://the-swank.pp.ua:3000/'
|
|
ENV = [];
|
|
|
|
loadingDone() |