aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Types.hx21
-rw-r--r--src/server/Main.hx34
-rw-r--r--src/server/cache/YoutubeCache.hx42
-rw-r--r--src/utils/macro/Macro.hx35
4 files changed, 100 insertions, 32 deletions
diff --git a/src/Types.hx b/src/Types.hx
index 60ce612..22b6ec2 100644
--- a/src/Types.hx
+++ b/src/Types.hx
@@ -29,28 +29,35 @@ typedef VideoData = {
var ?playerType:PlayerType;
}
+typedef ServerConfig = Config & {
+ serverChatHistory:Int,
+ localAdmins:Bool,
+ allowProxyIps:Bool,
+ localNetworkOnly:Bool,
+ sslKeyPemPath:String,
+ sslCertPemPath:String,
+ cacheStorageLimitGiB:Float,
+ ytDlp:{
+ channel:String, jsRuntime:String,
+ },
+}
+
typedef Config = {
port:Int,
channelName:String,
maxLoginLength:Int,
maxMessageLength:Int,
- serverChatHistory:Int,
totalVideoLimit:Int,
userVideoLimit:Int,
requestLeaderOnPause:Bool,
unpauseWithoutLeader:Bool,
- localAdmins:Bool,
- allowProxyIps:Bool,
- localNetworkOnly:Bool,
- sslKeyPemPath:String,
- sslCertPemPath:String,
templateUrl:String,
youtubeApiKey:String,
youtubePlaylistLimit:Int,
- cacheStorageLimitGiB:Float,
permissions:Permissions,
emotes:Array<Emote>,
filters:Array<Filter>,
+ ?serverVersion:Int,
?isVerbose:Bool,
?salt:String
}
diff --git a/src/server/Main.hx b/src/server/Main.hx
index e67fbcb..8b9ade1 100644
--- a/src/server/Main.hx
+++ b/src/server/Main.hx
@@ -6,6 +6,7 @@ import Types.FlashbackItem;
import Types.Message;
import Types.Permission;
import Types.PlayerType;
+import Types.ServerConfig;
import Types.UserList;
import Types.VideoItem;
import Types.WsEvent;
@@ -26,6 +27,7 @@ import json2object.JsonParser;
import server.cache.Cache;
import sys.FileSystem;
import sys.io.File;
+import utils.macro.Macro;
private typedef MainOptions = {
loadState:Bool
@@ -34,6 +36,7 @@ private typedef MainOptions = {
class Main {
public static inline var MIN_PASSWORD_LENGTH = 4;
public static inline var MAX_PASSWORD_LENGTH = 50;
+ static inline var SERVER_VERSION = 2;
static inline var VIDEO_START_MAX_DELAY = 3000;
static inline var VIDEO_SKIP_DELAY = 1000;
static inline var FLASHBACKS_COUNT = 50;
@@ -44,7 +47,7 @@ class Main {
public final userDir:String;
public final logsDir:String;
- public final config:Config;
+ public final config:ServerConfig;
public final isNoState:Bool;
final verbose:Bool;
@@ -120,6 +123,12 @@ class Main {
exit();
});
+ config = loadUserConfig();
+ config.serverVersion = SERVER_VERSION;
+ config.isVerbose = verbose;
+ userList = loadUsers();
+ config.salt = generateConfigSalt(userList);
+
logger = new Logger(logsDir, 10, verbose);
consoleInput = new ConsoleInput(this);
consoleInput.initConsoleInput();
@@ -127,11 +136,8 @@ class Main {
if (cache.isYtReady) playersCacheSupport.push(YoutubeType);
initIntergationHandlers();
loadState();
- config = loadUserConfig();
cache.setStorageLimit(cast config.cacheStorageLimitGiB * 1024 * 1024 * 1024);
- userList = loadUsers();
- config.isVerbose = verbose;
- config.salt = generateConfigSalt();
+
if (config.localNetworkOnly) localIp = "127.0.0.1";
else localIp = Utils.getLocalIp();
globalIp = localIp;
@@ -235,7 +241,7 @@ class Main {
};
}
- function getSslConfig(config:Config):Null<{key:String, cert:String}> {
+ function getSslConfig(config:ServerConfig):Null<{key:String, cert:String}> {
final c = config;
if (c.sslKeyPemPath.length == 0 && c.sslCertPemPath.length == 0) return null;
final hasBoth = FileSystem.exists(c.sslKeyPemPath)
@@ -264,12 +270,12 @@ class Main {
process.exit();
}
- function generateConfigSalt():String {
- userList.salt ??= Sha256.encode('${Math.random()}');
- return userList.salt;
+ function generateConfigSalt(users:UserList):String {
+ users.salt ??= Sha256.encode('${Math.random()}');
+ return users.salt;
}
- function loadUserConfig():Config {
+ function loadUserConfig():ServerConfig {
final config = getUserConfig();
inline function getPermissions(type:Permission):Array<Permission> {
return Reflect.field(config.permissions, cast type);
@@ -289,12 +295,12 @@ class Main {
return config;
}
- function getUserConfig():Config {
- final config:Config = Json.parse(File.getContent('$rootDir/default-config.json'));
+ function getUserConfig():ServerConfig {
+ final config:ServerConfig = Json.parse(File.getContent('$rootDir/default-config.json'));
if (isNoState) return config;
final customPath = '$userDir/config.json';
if (!FileSystem.exists(customPath)) return config;
- final customConfig:Config = Json.parse(File.getContent(customPath));
+ final customConfig:ServerConfig = Json.parse(File.getContent(customPath));
for (field in Reflect.fields(customConfig)) {
if (Reflect.field(config, field) == null) {
trace('Warning: config field "$field" is unknown');
@@ -563,7 +569,7 @@ class Main {
type: Connected,
connected: {
uuid: client.uuid,
- config: config,
+ config: Macro.getTypedObject(config, Config),
history: messages,
isUnknownClient: true,
clientName: client.name,
diff --git a/src/server/cache/YoutubeCache.hx b/src/server/cache/YoutubeCache.hx
index c7053f9..0618d00 100644
--- a/src/server/cache/YoutubeCache.hx
+++ b/src/server/cache/YoutubeCache.hx
@@ -1,6 +1,6 @@
package server.cache;
-import haxe.Json;
+import haxe.io.Path;
import js.lib.Promise;
import js.node.ChildProcess;
import sys.FileSystem;
@@ -30,7 +30,8 @@ class YoutubeCache {
}
public function checkUpdate():Void {
- ytDlp.execAsync("-U", {
+ ytDlp.execAsync("", {
+ updateTo: main.config.ytDlp.channel,
onData: d -> {
trace(d);
}
@@ -136,36 +137,51 @@ class YoutubeCache {
}
if (!checkEnoughSpace(getTotalFormatsSize() * 2)) return;
- final formatIds = if (videoFormat.format_id == audioFormat.format_id) {
+ final isMuxed = videoFormat.format_id == audioFormat.format_id;
+ final formatIds = if (isMuxed) {
videoFormat.format_id;
} else {
'${videoFormat.format_id}+${audioFormat.format_id}';
}
- var totalSize = getTotalFormatsSize().limitMin(10);
+ final totalSize = getTotalFormatsSize().limitMin(10);
var videoSizeRatio = (videoFormat.filesize ?? 0).limitMin(8) / totalSize;
var audioSizeRatio = (audioFormat.filesize ?? 0).limitMin(2) / totalSize;
- var isVideoFormatDownloading = true;
+ if (isMuxed) {
+ videoSizeRatio = 1;
+ audioSizeRatio = 0;
+ }
+ trace(formatIds, toMibString(totalSize), videoSizeRatio.toFixed(), audioSizeRatio.toFixed());
+
+ var videoRatioCache = 0.0;
+ var audioRatioCache = 0.0;
final dlVideo:Promise<String> = ytDlp.downloadAsync(url, {
format: formatIds,
output: '${cache.cacheDir}/$inVideoName',
remuxVideo: "mp4",
+ additionalOptions: ["--no-js-runtimes", "--js-runtimes", main.config.ytDlp.jsRuntime],
+ // verbose: true,
cookies: useCookies ? getCookiesPathOrNull() : null,
forceIpv4: true,
socketTimeout: 2,
extractorRetries: 0,
onProgress: p -> {
final isFinished = p.status == "finished";
+ if (isFinished) {
+ final filename = Path.withoutDirectory(p.filename);
+ trace('$filename format file downloaded');
+ }
var ratio = if (isFinished) {
1;
} else {
(p.downloaded / p.total).clamp(0, 1);
}
- if (isVideoFormatDownloading) {
- ratio = ratio * videoSizeRatio;
- } else {
- ratio = videoSizeRatio + ratio * audioSizeRatio;
- }
- if (isFinished) isVideoFormatDownloading = false;
+
+ final isVideo = p.filename.contains('f${videoFormat.format_id}');
+ if (isVideo) videoRatioCache = ratio;
+ else audioRatioCache = ratio;
+
+ ratio = videoRatioCache * videoSizeRatio + audioRatioCache * audioSizeRatio;
+
main.sendByName(clientName, {
type: Progress,
progress: {
@@ -249,6 +265,10 @@ class YoutubeCache {
return format.format_note ?? '${resolution}p';
}
+ inline function toMibString(bytes:Int):String {
+ return '${(bytes / 1024 / 1024).toFixed()} MiB';
+ }
+
function log(clientName:String, msg:String):Void {
cache.logByName(clientName, msg);
}
diff --git a/src/utils/macro/Macro.hx b/src/utils/macro/Macro.hx
new file mode 100644
index 0000000..118f0e8
--- /dev/null
+++ b/src/utils/macro/Macro.hx
@@ -0,0 +1,35 @@
+package utils.macro;
+
+import haxe.macro.Context;
+import haxe.macro.Expr;
+
+using haxe.macro.Tools;
+
+class Macro {
+ macro public static function getTypedObject(obj:Expr, typePath:Expr):Expr {
+ final type = Context.getType(typePath.toString());
+ switch (type.follow()) {
+ case TAnonymous(_.get() => td):
+ final name = obj.toString();
+ if (obj.expr.match(EObjectDecl(_))) {
+ throw new Error('$name should be passed as reference (inside of variable)', obj.pos);
+ }
+ final e:Expr = {
+ expr: EObjectDecl([
+ for (field in td.fields) {
+ field: field.name,
+ expr: macro $p{['$name', '${field.name}']},
+ }
+ ]),
+ pos: Context.currentPos()
+ }
+ return e;
+ default:
+ throw new Error(type.toString() + " should be typedef structure", typePath.pos);
+ }
+ }
+
+ macro public static function getBuildTime():Expr {
+ return macro $v{Date.now().toString()};
+ }
+}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage