diff options
Diffstat (limited to 'build/server.js')
| -rw-r--r-- | build/server.js | 539 |
1 files changed, 311 insertions, 228 deletions
diff --git a/build/server.js b/build/server.js index 2592fe8..8dd9077 100644 --- a/build/server.js +++ b/build/server.js @@ -1,4 +1,4 @@ -// Generated by Haxe 4.3.6 +// Generated by Haxe 4.3.7 (function ($global) { "use strict"; var $estr = function() { return js_Boot.__string_rec(this,''); },$hxEnums = $hxEnums || {},$_; function $extend(from, fields) { @@ -4089,7 +4089,7 @@ server_HttpServer.prototype = { } }); stream.on("error",function(err) { - haxe_Log.trace(err,{ fileName : "src/server/HttpServer.hx", lineNumber : 225, className : "server.HttpServer", methodName : "uploadFile"}); + haxe_Log.trace(err,{ fileName : "src/server/HttpServer.hx", lineNumber : 227, className : "server.HttpServer", methodName : "uploadFile"}); tools_HttpServerTools.json(tools_HttpServerTools.status(res,500),{ info : "File write stream error."}); var _this = _gthis.uploadingFilesSizes; if(Object.prototype.hasOwnProperty.call(_this.h,filePath)) { @@ -4102,7 +4102,7 @@ server_HttpServer.prototype = { _gthis.cache.remove(name); }); req.on("error",function(err) { - haxe_Log.trace("Request Error:",{ fileName : "src/server/HttpServer.hx", lineNumber : 232, className : "server.HttpServer", methodName : "uploadFile", customParams : [err]}); + haxe_Log.trace("Request Error:",{ fileName : "src/server/HttpServer.hx", lineNumber : 234, className : "server.HttpServer", methodName : "uploadFile", customParams : [err]}); stream.destroy(); tools_HttpServerTools.json(tools_HttpServerTools.status(res,500),{ info : "File request error."}); var _this = _gthis.uploadingFilesSizes; @@ -4131,7 +4131,7 @@ server_HttpServer.prototype = { var jsonParser = new JsonParser_$f3c29c0813c93ee49a61ccf072b8a177(); var jsonData = jsonParser.fromJson(body); if(jsonParser.errors.length > 0) { - haxe_Log.trace(json2object_ErrorUtils.convertErrorArray(jsonParser.errors),{ fileName : "src/server/HttpServer.hx", lineNumber : 258, className : "server.HttpServer", methodName : "finishSetup"}); + haxe_Log.trace(json2object_ErrorUtils.convertErrorArray(jsonParser.errors),{ fileName : "src/server/HttpServer.hx", lineNumber : 260, className : "server.HttpServer", methodName : "finishSetup"}); tools_HttpServerTools.json(tools_HttpServerTools.status(res,400),{ success : false, errors : []}); return; } @@ -4232,15 +4232,17 @@ server_HttpServer.prototype = { end = start + this.CHUNK_SIZE; } if(server_Utils.isOutOfRange(end,start,videoSize - 1)) { - end = videoSize - 1; + var a = videoSize - 1; + end = a < 0 ? 0 : a; } return { start : start, end : end}; } ,isMediaExtension: function(ext) { - if(!(ext == "mp4" || ext == "webm" || ext == "mp3")) { - return ext == "wav"; - } else { + switch(ext) { + case "mp3":case "mp4":case "ogg":case "wav":case "webm": return true; + default: + return false; } } ,localizeHtml: function(data,lang) { @@ -4490,7 +4492,7 @@ var server_Main = function(opts) { preparePort = function() { server_Utils.isPortFree(_gthis.port,function(isFree) { if(!isFree && attempts > 0) { - haxe_Log.trace("Warning: port " + _gthis.port + " is already in use. Changed to " + (_gthis.port + 1),{ fileName : "src/server/Main.hx", lineNumber : 140, className : "server.Main", methodName : "new"}); + haxe_Log.trace("Warning: port " + _gthis.port + " is already in use. Changed to " + (_gthis.port + 1),{ fileName : "src/server/Main.hx", lineNumber : 142, className : "server.Main", methodName : "new"}); attempts -= 1; _gthis.port++; preparePort(); @@ -4517,16 +4519,16 @@ server_Main.jsonFilterNulls = function(key,value) { server_Main.prototype = { runServer: function() { var _gthis = this; - haxe_Log.trace("Local: http://" + this.localIp + ":" + this.port,{ fileName : "src/server/Main.hx", lineNumber : 153, className : "server.Main", methodName : "runServer"}); + haxe_Log.trace("Local: http://" + this.localIp + ":" + this.port,{ fileName : "src/server/Main.hx", lineNumber : 155, className : "server.Main", methodName : "runServer"}); if(this.config.localNetworkOnly) { - haxe_Log.trace("Global network is disabled in config",{ fileName : "src/server/Main.hx", lineNumber : 155, className : "server.Main", methodName : "runServer"}); + haxe_Log.trace("Global network is disabled in config",{ fileName : "src/server/Main.hx", lineNumber : 157, className : "server.Main", methodName : "runServer"}); } else if(!this.isNoState) { server_Utils.getGlobalIp(function(ip) { if(ip.indexOf(":") != -1) { ip = "[" + ip + "]"; } _gthis.globalIp = ip; - haxe_Log.trace("Global: http://" + _gthis.globalIp + ":" + _gthis.port,{ fileName : "src/server/Main.hx", lineNumber : 161, className : "server.Main", methodName : "runServer"}); + haxe_Log.trace("Global: http://" + _gthis.globalIp + ":" + _gthis.port,{ fileName : "src/server/Main.hx", lineNumber : 163, className : "server.Main", methodName : "runServer"}); }); } var dir = "" + this.rootDir + "/res"; @@ -4611,7 +4613,7 @@ server_Main.prototype = { var field = _g1[_g]; ++_g; if(Reflect.field(config,field) == null) { - haxe_Log.trace("Warning: config field \"" + field + "\" is unknown",{ fileName : "src/server/Main.hx", lineNumber : 235, className : "server.Main", methodName : "getUserConfig"}); + haxe_Log.trace("Warning: config field \"" + field + "\" is unknown",{ fileName : "src/server/Main.hx", lineNumber : 237, className : "server.Main", methodName : "getUserConfig"}); } config[field] = Reflect.field(customConfig,field); } @@ -4622,14 +4624,14 @@ server_Main.prototype = { var emote = _g1[_g]; ++_g; if(emoteCopies_h[emote.name]) { - haxe_Log.trace("Warning: emote name \"" + emote.name + "\" has copy",{ fileName : "src/server/Main.hx", lineNumber : 241, className : "server.Main", methodName : "getUserConfig"}); + haxe_Log.trace("Warning: emote name \"" + emote.name + "\" has copy",{ fileName : "src/server/Main.hx", lineNumber : 243, className : "server.Main", methodName : "getUserConfig"}); } emoteCopies_h[emote.name] = true; if(!this.verbose) { continue; } if(emoteCopies_h[emote.image]) { - haxe_Log.trace("Warning: emote url of name \"" + emote.name + "\" has copy",{ fileName : "src/server/Main.hx", lineNumber : 245, className : "server.Main", methodName : "getUserConfig"}); + haxe_Log.trace("Warning: emote url of name \"" + emote.name + "\" has copy",{ fileName : "src/server/Main.hx", lineNumber : 247, className : "server.Main", methodName : "getUserConfig"}); } emoteCopies_h[emote.image] = true; } @@ -4666,7 +4668,7 @@ server_Main.prototype = { js_node_Fs.writeFileSync("" + this.userDir + "/users.json",JSON.stringify({ admins : users1, bans : _g, salt : users.salt},null,"\t")); } ,saveState: function() { - haxe_Log.trace("Saving state...",{ fileName : "src/server/Main.hx", lineNumber : 283, className : "server.Main", methodName : "saveState"}); + haxe_Log.trace("Saving state...",{ fileName : "src/server/Main.hx", lineNumber : 285, className : "server.Main", methodName : "saveState"}); var json = JSON.stringify(this.getCurrentState(),null,"\t"); js_node_Fs.writeFileSync(this.statePath,json); this.writeUsers(this.userList); @@ -4681,7 +4683,7 @@ server_Main.prototype = { if(!sys_FileSystem.exists(this.statePath)) { return; } - haxe_Log.trace("Loading state...",{ fileName : "src/server/Main.hx", lineNumber : 307, className : "server.Main", methodName : "loadState"}); + haxe_Log.trace("Loading state...",{ fileName : "src/server/Main.hx", lineNumber : 309, className : "server.Main", methodName : "loadState"}); var state = JSON.parse(js_node_Fs.readFileSync(this.statePath,{ encoding : "utf8"})); state.flashbacks = state.flashbacks != null ? state.flashbacks : []; state.cachedFiles = state.cachedFiles != null ? state.cachedFiles : []; @@ -4703,7 +4705,7 @@ server_Main.prototype = { } ,logError: function(type,data) { this.cache.removeOlderCache(1048576); - haxe_Log.trace(type,{ fileName : "src/server/Main.hx", lineNumber : 331, className : "server.Main", methodName : "logError", customParams : [data]}); + haxe_Log.trace(type,{ fileName : "src/server/Main.hx", lineNumber : 333, className : "server.Main", methodName : "logError", customParams : [data]}); var crashesFolder = "" + this.userDir + "/crashes"; server_Utils.ensureDir(crashesFolder); var name = DateTools.format(new Date(),"%Y-%m-%d_%H_%M_%S") + "-" + type; @@ -4725,7 +4727,7 @@ server_Main.prototype = { if(_gthis.clients.length == 0) { return; } - haxe_Log.trace("Ping " + url,{ fileName : "src/server/Main.hx", lineNumber : 344, className : "server.Main", methodName : "initIntergationHandlers"}); + haxe_Log.trace("Ping " + url,{ fileName : "src/server/Main.hx", lineNumber : 346, className : "server.Main", methodName : "initIntergationHandlers"}); js_node_Http.get(url,null,function(r) { }); }; @@ -4744,13 +4746,13 @@ server_Main.prototype = { password += this.config.salt; var hash = haxe_crypto_Sha256.encode(password); this.userList.admins.push({ name : name, hash : hash}); - haxe_Log.trace("Admin " + name + " added.",{ fileName : "src/server/Main.hx", lineNumber : 365, className : "server.Main", methodName : "addAdmin"}); + haxe_Log.trace("Admin " + name + " added.",{ fileName : "src/server/Main.hx", lineNumber : 367, className : "server.Main", methodName : "addAdmin"}); } ,removeAdmin: function(name) { HxOverrides.remove(this.userList.admins,Lambda.find(this.userList.admins,function(item) { return item.name == name; })); - haxe_Log.trace("Admin " + name + " removed.",{ fileName : "src/server/Main.hx", lineNumber : 372, className : "server.Main", methodName : "removeAdmin"}); + haxe_Log.trace("Admin " + name + " removed.",{ fileName : "src/server/Main.hx", lineNumber : 374, className : "server.Main", methodName : "removeAdmin"}); } ,hasAdmins: function() { return this.userList.admins.length > 0; @@ -4820,7 +4822,7 @@ server_Main.prototype = { var ip = this.clientIp(req); var id = this.freeIds.length > 0 ? this.freeIds.shift() : this.clients.length; var name = "Guest " + (id + 1); - haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 435, className : "server.Main", methodName : "onConnect", customParams : ["" + name + " connected (" + ip + ")"]}); + haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 437, className : "server.Main", methodName : "onConnect", customParams : ["" + name + " connected (" + ip + ")"]}); var isAdmin = this.config.localAdmins && req.socket.localAddress == ip; var client = new Client(ws,req,id,name,0); client.uuid = uuid; @@ -4834,7 +4836,7 @@ server_Main.prototype = { var obj = _gthis.wsEventParser.fromJson(data.toString()); if(_gthis.wsEventParser.errors.length > 0 || _gthis.noTypeObj(obj)) { var errors = "" + ("Wrong request for type \"" + obj.type + "\":") + "\n" + json2object_ErrorUtils.convertErrorArray(_gthis.wsEventParser.errors); - haxe_Log.trace(errors,{ fileName : "src/server/Main.hx", lineNumber : 452, className : "server.Main", methodName : "onConnect"}); + haxe_Log.trace(errors,{ fileName : "src/server/Main.hx", lineNumber : 454, className : "server.Main", methodName : "onConnect"}); _gthis.serverMessage(client,errors); return; } @@ -5029,7 +5031,7 @@ server_Main.prototype = { if(!internal) { return; } - haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 517, className : "server.Main", methodName : "onMessage", customParams : ["Client " + client.name + " disconnected"]}); + haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 519, className : "server.Main", methodName : "onMessage", customParams : ["Client " + client.name + " disconnected"]}); server_Utils.sortedPush(this.freeIds,client.id); HxOverrides.remove(this.clients,client); this.sendClientList(); @@ -5080,6 +5082,7 @@ server_Main.prototype = { } var json = server_Main.jsonStringify({ state : data1, clients : result, logs : this.logger.getLogs()},"\t"); this.serverMessage(client,"Free space: " + tools_MathTools.toFixed(this.cache.getFreeSpace() / 1024) + "KiB"); + this.serverMessage(client,"Memory usage: " + Std.string(process.memoryUsage())); this.send(client,{ type : "Dump", dump : { data : json}}); break; case "Flashback": @@ -5169,7 +5172,7 @@ server_Main.prototype = { this.send(client,{ type : "LoginError"}); return; } - haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 608, className : "server.Main", methodName : "onMessage", customParams : ["Client " + client.name + " logged as " + name]}); + haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 610, className : "server.Main", methodName : "onMessage", customParams : ["Client " + client.name + " logged as " + name]}); client.name = name; client.setGroupFlag(ClientGroup.User,true); this.checkBan(client); @@ -5182,7 +5185,7 @@ server_Main.prototype = { var oldName = client.name; client.name = "Guest " + (this.clients.indexOf(client) + 1); client.setGroupFlag(ClientGroup.User,false); - haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 629, className : "server.Main", methodName : "onMessage", customParams : ["Client " + oldName + " logout to " + client.name]}); + haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 631, className : "server.Main", methodName : "onMessage", customParams : ["Client " + oldName + " logout to " + client.name]}); this.send(client,{ type : data.type, logout : { oldClientName : oldName, clientName : client.name, clients : this.clientList()}}); this.sendClientListExcept(client); break; @@ -5445,6 +5448,13 @@ server_Main.prototype = { ,send: function(client,data) { client.ws.send(server_Main.jsonStringify(data),null); } + ,sendByName: function(clientName,data) { + var tmp = ClientTools.getByName(this.clients,clientName); + if(tmp == null) { + return; + } + tmp.ws.send(server_Main.jsonStringify(data),null); + } ,broadcast: function(data) { var json = server_Main.jsonStringify(data); var _g = 0; @@ -5512,7 +5522,7 @@ server_Main.prototype = { client.setGroupFlag(ClientGroup.Banned,!isOutdated); if(isOutdated) { HxOverrides.remove(this.userList.bans,ban); - haxe_Log.trace("" + client.name + " ban removed",{ fileName : "src/server/Main.hx", lineNumber : 1070, className : "server.Main", methodName : "checkBan"}); + haxe_Log.trace("" + client.name + " ban removed",{ fileName : "src/server/Main.hx", lineNumber : 1078, className : "server.Main", methodName : "checkBan"}); this.sendClientList(); } break; @@ -5851,6 +5861,9 @@ server_cache_Cache.prototype = { this.cachedFiles.length = 0; var _g = 0; while(_g < names.length) this.cachedFiles.push(names[_g++]); + this.removeUntrackedFiles(); + } + ,removeUntrackedFiles: function() { var names = js_node_Fs.readdirSync(this.cacheDir); var _g = 0; while(_g < names.length) { @@ -5865,13 +5878,42 @@ server_cache_Cache.prototype = { if(this.cachedFiles.indexOf(name) != -1) { continue; } - haxe_Log.trace("Remove non-tracked cache " + name,{ fileName : "src/server/cache/Cache.hx", lineNumber : 47, className : "server.cache.Cache", methodName : "setCachedFiles"}); + haxe_Log.trace("Remove untracked cache " + name,{ fileName : "src/server/cache/Cache.hx", lineNumber : 51, className : "server.cache.Cache", methodName : "removeUntrackedFiles"}); this.remove(name); } } ,log: function(client,msg) { + haxe_Log.trace(msg,{ fileName : "src/server/cache/Cache.hx", lineNumber : 57, className : "server.cache.Cache", methodName : "log"}); this.main.serverMessage(client,msg); - haxe_Log.trace(msg,{ fileName : "src/server/cache/Cache.hx", lineNumber : 54, className : "server.cache.Cache", methodName : "log"}); + } + ,logByName: function(clientName,msg) { + haxe_Log.trace(msg,{ fileName : "src/server/cache/Cache.hx", lineNumber : 62, className : "server.cache.Cache", methodName : "logByName"}); + var tmp = ClientTools.getByName(this.main.clients,clientName); + if(tmp == null) { + return; + } + this.main.serverMessage(tmp,msg); + } + ,logWithAdmins: function(client,msg) { + this.log(client,msg); + var _this = this.main.clients; + var _g = []; + var _g1 = 0; + while(_g1 < _this.length) { + var v = _this[_g1]; + ++_g1; + if((v.group & 8) != 0) { + _g.push(v); + } + } + var _g1 = 0; + while(_g1 < _g.length) { + var admin = _g[_g1]; + ++_g1; + if(client != admin) { + this.main.serverMessage(admin,msg); + } + } } ,cacheYoutubeVideo: function(client,url,callback) { this.youtubeCache.cacheYoutubeVideo(client,url,callback); @@ -5900,13 +5942,13 @@ server_cache_Cache.prototype = { var _gthis = this; var tmp = js_node_Fs.statfs; if(tmp == null) { - haxe_Log.trace("Warning: no fs.statfs support in current nodejs version (needs v18+)",{ fileName : "src/server/cache/Cache.hx", lineNumber : 83, className : "server.cache.Cache", methodName : "getFreeDiskSpace"}); + haxe_Log.trace("Warning: no fs.statfs support in current nodejs version (needs v18+)",{ fileName : "src/server/cache/Cache.hx", lineNumber : 101, className : "server.cache.Cache", methodName : "getFreeDiskSpace"}); callback(this.storageLimit); return; } tmp("/",function(err,stats) { if(err != null) { - haxe_Log.trace(err,{ fileName : "src/server/cache/Cache.hx", lineNumber : 89, className : "server.cache.Cache", methodName : "getFreeDiskSpace"}); + haxe_Log.trace(err,{ fileName : "src/server/cache/Cache.hx", lineNumber : 107, className : "server.cache.Cache", methodName : "getFreeDiskSpace"}); callback(_gthis.storageLimit); return; } @@ -5979,6 +6021,18 @@ server_cache_Cache.prototype = { ,isFileExists: function(name) { return sys_FileSystem.exists(this.getFilePath(name)); } + ,findFile: function(callback) { + var names = js_node_Fs.readdirSync(this.cacheDir); + var _g = 0; + while(_g < names.length) { + var name = names[_g]; + ++_g; + if(callback(name)) { + return name; + } + } + return null; + } ,getFreeSpace: function() { return this.storageLimit - this.getUsedSpace(); } @@ -6034,31 +6088,33 @@ server_cache_RawCache.prototype = { } ,handleMp4: function(client,url,outName,callback) { var _gthis = this; + var clientName = client.name; this.downloadFile(client,url,outName,function(downloaded,total) { var v = downloaded / total; - _gthis.main.send(client,{ type : "Progress", progress : { type : "Downloading", ratio : v < 0 ? 0 : v > 1 ? 1 : v}}); + _gthis.main.sendByName(clientName,{ type : "Progress", progress : { type : "Downloading", ratio : tools_MathTools.toFixed(v < 0 ? 0 : v > 1 ? 1 : v,4)}}); },function() { _gthis.cache.add(outName); callback(outName); },function(err) { - _gthis.log(client,"Mp4 download failed: " + err); - _gthis.cancelProgress(client); + _gthis.log(clientName,"Mp4 download failed: " + err); + _gthis.cancelProgress(clientName); }); } ,handleM3u8: function(client,url,outName,callback) { var _gthis = this; + var clientName = client.name; var useProxy = true; this.downloadM3u8Playlist(client,url,useProxy,function(playlist,totalSize,segments) { if(useProxy) { totalSize = playlist.length; } if(!_gthis.cache.removeOlderCache(totalSize + _gthis.cache.freeSpaceBlock)) { - _gthis.log(client,_gthis.cache.notEnoughSpaceErrorText); - _gthis.cancelProgress(client); + _gthis.log(clientName,_gthis.cache.notEnoughSpaceErrorText); + _gthis.cancelProgress(clientName); return; } if(useProxy) { - _gthis.main.send(client,{ type : "Progress", progress : { type : "Caching", ratio : 1, data : outName}}); + _gthis.main.sendByName(clientName,{ type : "Progress", progress : { type : "Caching", ratio : 1, data : outName}}); js_node_Fs.writeFileSync("" + _gthis.cache.cacheDir + "/" + outName,playlist); _gthis.cache.add(outName); callback(outName); @@ -6081,7 +6137,7 @@ server_cache_RawCache.prototype = { } segment[0].started = true; activeDownloads += 1; - haxe_Log.trace("download segment",{ fileName : "src/server/cache/RawCache.hx", lineNumber : 118, className : "server.cache.RawCache", methodName : "handleM3u8", customParams : [segment[0].i]}); + haxe_Log.trace("download segment",{ fileName : "src/server/cache/RawCache.hx", lineNumber : 120, className : "server.cache.RawCache", methodName : "handleM3u8", customParams : [segment[0].i]}); _gthis.downloadFile(client,segment[0].url,segment[0].name,(function() { return function(downloadedBytes,totalBytes) { }; @@ -6091,9 +6147,9 @@ server_cache_RawCache.prototype = { segment[0].completed = true; downloaded += 1; var progress = downloaded / segments.length; - _gthis.main.send(client,{ type : "Progress", progress : { type : "Downloading", ratio : progress < 0 ? 0 : progress > 1 ? 1 : progress}}); + _gthis.main.sendByName(clientName,{ type : "Progress", progress : { type : "Downloading", ratio : progress < 0 ? 0 : progress > 1 ? 1 : progress}}); if(downloaded == segments.length) { - haxe_Log.trace("All " + downloaded + "/" + segments.length + " segments downloaded",{ fileName : "src/server/cache/RawCache.hx", lineNumber : 138, className : "server.cache.RawCache", methodName : "handleM3u8"}); + haxe_Log.trace("All " + downloaded + "/" + segments.length + " segments downloaded",{ fileName : "src/server/cache/RawCache.hx", lineNumber : 140, className : "server.cache.RawCache", methodName : "handleM3u8"}); js_node_Fs.writeFileSync("" + _gthis.cache.cacheDir + "/" + outName,playlist); _gthis.cache.add(outName); callback(outName); @@ -6105,8 +6161,8 @@ server_cache_RawCache.prototype = { return function(err) { activeDownloads -= 1; downloaded += 1; - _gthis.log(client,"TS segment " + segment[0].i + " download failed: " + err); - _gthis.cancelProgress(client); + _gthis.log(clientName,"TS segment " + segment[0].i + " download failed: " + err); + _gthis.cancelProgress(clientName); var _gthis1 = _gthis; var result = new Array(segments.length); var _g = 0; @@ -6122,8 +6178,8 @@ server_cache_RawCache.prototype = { }; downloadNextBatch(); },function(err) { - _gthis.log(client,"M3U8 processing failed: " + err); - _gthis.cancelProgress(client); + _gthis.log(clientName,"M3U8 processing failed: " + err); + _gthis.cancelProgress(clientName); }); } ,request: function(url,options,callback) { @@ -6250,11 +6306,11 @@ server_cache_RawCache.prototype = { } } } - ,log: function(client,msg) { - this.cache.log(client,msg); + ,log: function(clientName,msg) { + this.cache.logByName(clientName,msg); } - ,cancelProgress: function(client) { - this.main.send(client,{ type : "Progress", progress : { type : "Canceled", ratio : 0}}); + ,cancelProgress: function(clientName) { + this.main.sendByName(clientName,{ type : "Progress", progress : { type : "Canceled", ratio : 0}}); } ,__class__: server_cache_RawCache }; @@ -6265,26 +6321,24 @@ var server_cache_YoutubeCache = function(main,cache) { server_cache_YoutubeCache.__name__ = true; server_cache_YoutubeCache.prototype = { checkYtDeps: function() { - var ytdl; - try { - ytdl = require("@distube/ytdl-core"); - } catch( _g ) { - return false; - } try { - js_node_ChildProcess.execSync("ffmpeg -version",{ stdio : "ignore", timeout : 3000}); + js_node_ChildProcess.execSync("ffmpeg -version",{ stdio : "ignore", timeout : 5000}); + this.ytDlp = new (require('ytdlp-nodejs')).YtDlp(); return true; } catch( _g ) { return false; } } - ,cleanYtInputFiles: function() { + ,cleanYtInputFiles: function(prefix) { + if(prefix == null) { + prefix = "__tmp"; + } var names = js_node_Fs.readdirSync(this.cache.cacheDir); var _g = 0; while(_g < names.length) { var name = names[_g]; ++_g; - if(!StringTools.startsWith(name,"__tmp")) { + if(!StringTools.startsWith(name,prefix)) { continue; } this.cache.remove(name); @@ -6293,12 +6347,13 @@ server_cache_YoutubeCache.prototype = { ,cacheYoutubeVideo: function(client,url,callback) { var _gthis = this; if(!this.cache.isYtReady) { - haxe_Log.trace("Do `npm i @distube/ytdl-core@latest` to use cache feature (you also need to install `ffmpeg` to build mp4 from downloaded audio/video tracks).",{ fileName : "src/server/cache/YoutubeCache.hx", lineNumber : 46, className : "server.cache.YoutubeCache", methodName : "cacheYoutubeVideo"}); + haxe_Log.trace("Do `npm i https://github.com/RblSb/ytdlp-nodejs` to use cache feature (you also need to install `ffmpeg` to build mp4 from downloaded audio/video tracks).",{ fileName : "src/server/cache/YoutubeCache.hx", lineNumber : 42, className : "server.cache.YoutubeCache", methodName : "cacheYoutubeVideo"}); return; } + var clientName = client.name; var videoId = utils_YoutubeUtils.extractVideoId(url); if(videoId == "") { - this.log(client,"Error: youtube video id not found in url: " + url); + this.log(clientName,"Error: youtube video id not found in url: " + url); return; } var outName = videoId + ".mp4"; @@ -6307,221 +6362,247 @@ server_cache_YoutubeCache.prototype = { return; } var inVideoName = "__tmp-video-" + videoId; - var inAudioName = "__tmp-audio-" + videoId; if(this.cache.isFileExists(inVideoName)) { - this.log(client,"Caching " + outName + " already in progress"); + this.log(clientName,"Caching " + outName + " already in progress"); return; } - var ytdl = require("@distube/ytdl-core"); - haxe_Log.trace("Caching " + url + " to " + outName + "...",{ fileName : "src/server/cache/YoutubeCache.hx", lineNumber : 80, className : "server.cache.YoutubeCache", methodName : "cacheYoutubeVideo"}); - this.main.send(client,{ type : "Progress", progress : { type : "Caching", ratio : 0, data : outName}}); - var agent = null; - var cookiesPath = "" + this.main.userDir + "/cookies.json"; - if(sys_FileSystem.exists(cookiesPath)) { - agent = ytdl.createAgent(JSON.parse(js_node_Fs.readFileSync(cookiesPath,{ encoding : "utf8"}))); - } - var promise = ytdl.getInfo(url,{ agent : agent}); - promise.then(function(info) { - haxe_Log.trace("Get info with " + info.formats.length + " formats",{ fileName : "src/server/cache/YoutubeCache.hx", lineNumber : 98, className : "server.cache.YoutubeCache", methodName : "cacheYoutubeVideo"}); - var audioFormat; - try { - var ytdl1 = ytdl.chooseFormat; + haxe_Log.trace("Caching " + url + " to " + outName + "...",{ fileName : "src/server/cache/YoutubeCache.hx", lineNumber : 74, className : "server.cache.YoutubeCache", methodName : "cacheYoutubeVideo"}); + this.main.sendByName(clientName,{ type : "Progress", progress : { type : "Caching", ratio : 0, data : outName}}); + var useCookies = false; + var onGetInfo = function(info) { + haxe_Log.trace("Get info with " + info.formats.length + " formats",{ fileName : "src/server/cache/YoutubeCache.hx", lineNumber : 87, className : "server.cache.YoutubeCache", methodName : "cacheYoutubeVideo"}); + var _this = info.formats; + var _g = []; + var _g1 = 0; + while(_g1 < _this.length) { + var v = _this[_g1]; + ++_g1; + if(v.vcodec == "none") { + _g.push(v); + } + } + var aformats = _g; + if(_g.length == 0) { + var _this = info.formats; var _g = []; var _g1 = 0; - var _g2 = info.formats; - while(_g1 < _g2.length) { - var v = _g2[_g1]; + while(_g1 < _this.length) { + var v = _this[_g1]; ++_g1; - var tmp = v.audioCodec; - if(tmp != null ? StringTools.startsWith(tmp,"mp4a") : null) { + if(v.acodec != "none") { _g.push(v); } } - audioFormat = ytdl1(_g,{ quality : "highestaudio"}); - } catch( _g ) { - var e = haxe_Exception.caught(_g); - _gthis.log(client,"Error: audio format not found"); - haxe_Log.trace(e,{ fileName : "src/server/cache/YoutubeCache.hx", lineNumber : 105, className : "server.cache.YoutubeCache", methodName : "cacheYoutubeVideo"}); - var _g1 = []; - var _g2 = 0; - var _g3 = info.formats; - while(_g2 < _g3.length) { - var v = _g3[_g2]; - ++_g2; - if(v.hasAudio) { - _g1.push(v); - } + aformats = _g; + } + aformats.sort(function(a,b) { + var tmp = a != null ? a.filesize : null; + var tmp1 = b != null ? b.filesize : null; + if((tmp != null ? tmp : 0) < (tmp1 != null ? tmp1 : 0)) { + return 1; + } else { + return -1; } - haxe_Log.trace(_g1,{ fileName : "src/server/cache/YoutubeCache.hx", lineNumber : 106, className : "server.cache.YoutubeCache", methodName : "cacheYoutubeVideo"}); + }); + var tmp = aformats[0]; + if(tmp == null) { + _gthis.log(clientName,"Error: format with audio not found"); + var _g = 0; + var _g1 = info.formats; + while(_g < _g1.length) haxe_Log.trace(_g1[_g++],{ fileName : "src/server/cache/YoutubeCache.hx", lineNumber : 95, className : "server.cache.YoutubeCache", methodName : "cacheYoutubeVideo"}); return; } + var _this = info.formats; + var _g = []; + var _g1 = 0; + while(_g1 < _this.length) { + var v = _this[_g1]; + ++_g1; + if(v.vcodec != "none") { + _g.push(v); + } + } + _g.sort(function(a,b) { + var tmp = a != null ? a.filesize : null; + var tmp1 = b != null ? b.filesize : null; + if((tmp != null ? tmp : 0) < (tmp1 != null ? tmp1 : 0)) { + return 1; + } else { + return -1; + } + }); var videoFormat; - var tmp = _gthis.getBestYoutubeVideoFormat(info.formats); - if(tmp != null) { - videoFormat = tmp; + var tmp1 = _gthis.getBestYoutubeVideoFormat(_g); + if(tmp1 != null) { + videoFormat = tmp1; } else { - _gthis.log(client,"Error: video format not found"); - var _g = []; + _gthis.log(clientName,"Error: video format not found"); var _g1 = 0; var _g2 = info.formats; - while(_g1 < _g2.length) { - var v = _g2[_g1]; - ++_g1; - if(v.hasVideo) { - _g.push(v); - } - } - haxe_Log.trace(_g,{ fileName : "src/server/cache/YoutubeCache.hx", lineNumber : 111, className : "server.cache.YoutubeCache", methodName : "cacheYoutubeVideo"}); + while(_g1 < _g2.length) haxe_Log.trace(_g2[_g1++],{ fileName : "src/server/cache/YoutubeCache.hx", lineNumber : 102, className : "server.cache.YoutubeCache", methodName : "cacheYoutubeVideo"}); return; } - var tmp = Std.parseInt(videoFormat.contentLength); - var videoSize = tmp != null ? tmp : 0; - var tmp = Std.parseInt(audioFormat.contentLength); - var audioSize = tmp != null ? tmp : 0; - var hasSpace = _gthis.cache.removeOlderCache((videoSize + audioSize) * 2 + _gthis.cache.freeSpaceBlock); - if(!hasSpace) { - videoFormat = _gthis.getBestYoutubeVideoFormat(info.formats,videoFormat.qualityLabel); - var tmp = Std.parseInt(videoFormat.contentLength); - var videoSize = tmp != null ? tmp : 0; - var tmp = Std.parseInt(audioFormat.contentLength); - var audioSize = tmp != null ? tmp : 0; - var hasSpace = _gthis.cache.removeOlderCache((videoSize + audioSize) * 2 + _gthis.cache.freeSpaceBlock); - if(!hasSpace) { - _gthis.cache.remove(inVideoName); - _gthis.cache.remove(inAudioName); - _gthis.cancelProgress(client); - _gthis.log(client,_gthis.cache.notEnoughSpaceErrorText); + var ignoreQualities = []; + var _g1 = 0; + while(_g1 < 3) { + ++_g1; + var tmp1 = videoFormat.filesize; + var tmp2 = tmp.filesize; + if(_gthis.cache.removeOlderCache(((tmp1 != null ? tmp1 : 0) + (tmp2 != null ? tmp2 : 0)) * 2 + _gthis.cache.freeSpaceBlock)) { + break; } - if(!hasSpace) { - return; + var tmp3 = videoFormat.height; + ignoreQualities.push((tmp3 != null ? tmp3 : 0) | 0); + var tmp4 = _gthis.getBestYoutubeVideoFormat(_g,ignoreQualities); + if(tmp4 != null) { + videoFormat = tmp4; + } else { + break; } } - var dlVideo = ytdl(url,{ format : videoFormat, agent : agent}); - dlVideo.pipe(js_node_Fs.createWriteStream("" + _gthis.cache.cacheDir + "/" + inVideoName)); - dlVideo.on("error",function(err) { - _gthis.log(client,"Error during video download: " + err); - _gthis.cache.remove(inVideoName); - _gthis.cache.remove(inAudioName); - _gthis.cancelProgress(client); - }); - var dlAudio = ytdl(url,{ format : audioFormat, agent : agent}); - dlAudio.pipe(js_node_Fs.createWriteStream("" + _gthis.cache.cacheDir + "/" + inAudioName)); - dlAudio.on("error",function(err) { - _gthis.log(client,"Error during audio download: " + err); - _gthis.cache.remove(inVideoName); - _gthis.cache.remove(inAudioName); - _gthis.cancelProgress(client); - }); - var count = 0; - var onComplete = function(type) { - count += 1; - haxe_Log.trace("" + type + " track downloaded (" + count + "/2)",{ fileName : "src/server/cache/YoutubeCache.hx", lineNumber : 153, className : "server.cache.YoutubeCache", methodName : "cacheYoutubeVideo"}); - if(count < 2) { - return; - } - if(!_gthis.cache.isFileExists(inVideoName) || !_gthis.cache.isFileExists(inAudioName)) { - _gthis.log(client,"Input files not found for making final video"); - _gthis.cache.remove(inVideoName); - _gthis.cache.remove(inAudioName); - _gthis.cancelProgress(client); - return; + var tmp1 = videoFormat.filesize; + var tmp2 = tmp.filesize; + var hasSpace = _gthis.cache.removeOlderCache(((tmp1 != null ? tmp1 : 0) + (tmp2 != null ? tmp2 : 0)) * 2 + _gthis.cache.freeSpaceBlock); + if(!hasSpace) { + _gthis.cleanYtInputFiles(inVideoName); + _gthis.cancelProgress(clientName); + _gthis.log(clientName,_gthis.cache.notEnoughSpaceErrorText); + } + if(!hasSpace) { + return; + } + var tmp1 = videoFormat.filesize; + var tmp2 = tmp.filesize; + var a = (tmp1 != null ? tmp1 : 0) + (tmp2 != null ? tmp2 : 0); + var totalSize = a < 10 ? 10 : a; + var tmp1 = videoFormat.filesize; + var a = tmp1 != null ? tmp1 : 0; + var videoSizeRatio = (a < 8 ? 8 : a) / totalSize; + var tmp1 = tmp.filesize; + var a = tmp1 != null ? tmp1 : 0; + var audioSizeRatio = (a < 2 ? 2 : a) / totalSize; + var isVideoFormatDownloading = true; + var dlVideo = _gthis.ytDlp.downloadAsync(url,{ format : videoFormat.format_id == tmp.format_id ? videoFormat.format_id : "" + videoFormat.format_id + "+" + tmp.format_id, output : "" + _gthis.cache.cacheDir + "/" + inVideoName, remuxVideo : "mp4", cookies : useCookies ? _gthis.getCookiesPathOrNull() : null, onProgress : function(p) { + var isFinished = p.status == "finished"; + var ratio; + if(isFinished) { + ratio = 1; + } else { + var v = p.downloaded / p.total; + ratio = v < 0 ? 0 : v > 1 ? 1 : v; } - var size = js_node_Fs.statSync("" + _gthis.cache.cacheDir + "/" + inVideoName).size; - size += js_node_Fs.statSync("" + _gthis.cache.cacheDir + "/" + inAudioName).size; - var hasSpace = _gthis.cache.removeOlderCache(size + _gthis.cache.freeSpaceBlock); - if(!hasSpace) { - _gthis.cache.remove(inVideoName); - _gthis.cache.remove(inAudioName); - _gthis.cancelProgress(client); - _gthis.log(client,_gthis.cache.notEnoughSpaceErrorText); + if(isVideoFormatDownloading) { + ratio *= videoSizeRatio; + } else { + ratio = videoSizeRatio + ratio * audioSizeRatio; } - if(!hasSpace) { - return; + if(isFinished) { + isVideoFormatDownloading = false; } - var args = ("-y -i ./" + inVideoName + " -i ./" + inAudioName + " -c copy -map 0:v -map 1:a ./" + outName).split(" "); - var $process = js_node_ChildProcess.spawn("ffmpeg",args,{ cwd : _gthis.cache.cacheDir}); - var outputData = []; - $process.stderr.on("data",function(data) { - return outputData.push(data); - }); - $process.on("close",function(code) { - _gthis.cache.remove(inVideoName); - _gthis.cache.remove(inAudioName); - if(code != 0) { - _gthis.cancelProgress(client); - var errCodeMsg = "Error: ffmpeg closed with code " + code; - var _g = []; - var _g1 = 0; - var _g2 = _gthis.main.clients; - while(_g1 < _g2.length) { - var v = _g2[_g1]; - ++_g1; - if((v.group & 1 << ClientGroup.Admin._hx_index) != 0) { - _g.push(v); - } - } - var admins = _g; - var _g = 0; - while(_g < admins.length) { - var client1 = admins[_g]; - ++_g; - _gthis.log(client1,js_node_buffer_Buffer.concat(outputData).toString()); - _gthis.log(client1,errCodeMsg); - } - if(admins.indexOf(client) == -1) { - _gthis.log(client,errCodeMsg); - } - return; + _gthis.main.sendByName(clientName,{ type : "Progress", progress : { type : "Downloading", ratio : tools_MathTools.toFixed(ratio,4)}}); + }}).catch(function(err) { + _gthis.cache.logWithAdmins(client,"Error during video download: " + err); + _gthis.cleanYtInputFiles(inVideoName); + _gthis.cancelProgress(clientName); + }); + dlVideo.then(function(v) { + var tmp = _gthis.cache.findFile(function(n) { + if(StringTools.startsWith(n,inVideoName)) { + return StringTools.endsWith(n,".mp4"); + } else { + return false; } - _gthis.cache.add(outName); - callback(outName); }); - }; - dlVideo.on("finish",function() { - onComplete("Video"); - }); - dlAudio.on("finish",function() { - onComplete("Audio"); + if(tmp == null) { + _gthis.cache.logWithAdmins(client,"Error: cannot find downloaded file with prefix " + inVideoName); + return; + } + js_node_Fs.renameSync("" + _gthis.cache.cacheDir + "/" + tmp,"" + _gthis.cache.cacheDir + "/" + outName); + _gthis.cleanYtInputFiles(inVideoName); + _gthis.cache.add(outName); + callback(outName); }); - dlVideo.on("progress",function(chunkLength,downloaded,contentLength) { - var v = downloaded / contentLength; - var ratio = v < 0 ? 0 : v > 1 ? 1 : v; - _gthis.main.send(client,{ type : "Progress", progress : { type : "Downloading", ratio : ratio}}); + }; + this.getInfoAsync(url,useCookies).then(onGetInfo).catch(function(err) { + haxe_Log.trace(err,{ fileName : "src/server/cache/YoutubeCache.hx", lineNumber : 178, className : "server.cache.YoutubeCache", methodName : "cacheYoutubeVideo"}); + useCookies = true; + return _gthis.getInfoAsync(url,useCookies).then(onGetInfo).catch(function(err) { + _gthis.cleanYtInputFiles(inVideoName); + _gthis.cancelProgress(clientName); + _gthis.log(clientName,"" + err); }); - }).catch(function(err) { - _gthis.cache.remove(inVideoName); - _gthis.cache.remove(inAudioName); - _gthis.cancelProgress(client); - _gthis.log(client,"" + err); }); } - ,getBestYoutubeVideoFormat: function(formats,ignoreQuality) { + ,getInfoAsync: function(url,useCookies) { + if(useCookies == null) { + useCookies = false; + } + return this.ytDlp.execAsync(url,{ dumpSingleJson : true, quiet : true, cookies : useCookies ? this.getCookiesPathOrNull() : null}).then(function(data) { + return JSON.parse(data); + }); + } + ,getCookiesPathOrNull: function() { + var cookiesPath = "" + this.main.userDir + "/cookies.txt"; + if(sys_FileSystem.exists(cookiesPath)) { + return cookiesPath; + } else { + return null; + } + } + ,getBestYoutubeVideoFormat: function(formats,ignoreQualities) { var qPriority = [1080,720,480,360,240,144]; + if(ignoreQualities != null) { + var _g = 0; + while(_g < ignoreQualities.length) HxOverrides.remove(qPriority,ignoreQualities[_g++]); + } + var format60 = this.findFormat(formats,qPriority,true); + if(format60 != null) { + return format60; + } else { + return this.findFormat(formats,qPriority,false); + } + } + ,findFormat: function(formats,qPriority,is60fps) { var _g = 0; while(_g < qPriority.length) { - var quality = "" + qPriority[_g++] + "p"; - if(quality == ignoreQuality) { - continue; - } + var q = qPriority[_g]; + ++_g; + var quality = "" + q + "p" + (is60fps ? "60" : ""); var _g1 = 0; while(_g1 < formats.length) { var format = formats[_g1]; ++_g1; - if(format.videoCodec == null) { + var tmp = format.height; + if(tmp == null) { + continue; + } + if(tmp > q) { continue; } - if(format.qualityLabel == quality) { + if(this.formatVideoQuality(format) == quality) { return format; } } } return null; } - ,log: function(client,msg) { - this.cache.log(client,msg); + ,formatVideoQuality: function(format) { + var tmp = format.height; + if(tmp == null) { + return null; + } + var tmp1 = format.format_note; + if(tmp1 != null) { + return tmp1; + } else { + return "" + tmp + "p"; + } + } + ,log: function(clientName,msg) { + this.cache.logByName(clientName,msg); } - ,cancelProgress: function(client) { - this.main.send(client,{ type : "Progress", progress : { type : "Canceled", ratio : 0}}); + ,cancelProgress: function(clientName) { + this.main.sendByName(clientName,{ type : "Progress", progress : { type : "Canceled", ratio : 0}}); } ,__class__: server_cache_YoutubeCache }; @@ -6644,10 +6725,12 @@ server_HttpServer.mimeTypes = (function($this) { _g.h["jpeg"] = "image/jpeg"; _g.h["gif"] = "image/gif"; _g.h["webp"] = "image/webp"; + _g.h["avif"] = "image/avif"; _g.h["svg"] = "image/svg+xml"; _g.h["ico"] = "image/x-icon"; _g.h["wav"] = "audio/wav"; _g.h["mp3"] = "audio/mpeg"; + _g.h["ogg"] = "audio/ogg"; _g.h["mp4"] = "video/mp4"; _g.h["webm"] = "video/webm"; _g.h["woff"] = "application/font-woff"; |
