diff options
| author | RblSb <msrblsb@gmail.com> | 2021-08-15 13:40:01 +0300 |
|---|---|---|
| committer | RblSb <msrblsb@gmail.com> | 2021-08-15 13:44:32 +0300 |
| commit | f2d28c726ba46f03716ed37667d0e94c60ad3459 (patch) | |
| tree | d13d389f005cbb5ba5b5f46da05bbacf5801fbbb | |
| parent | 5b908e914ebfeedb2895f5de1b9167a6ce12c136 (diff) | |
Add /flashback (/fb)
| -rw-r--r-- | build/server.js | 75 | ||||
| -rw-r--r-- | res/client.js | 5 | ||||
| -rw-r--r-- | src/Types.hx | 1 | ||||
| -rw-r--r-- | src/client/Main.hx | 4 | ||||
| -rw-r--r-- | src/server/Main.hx | 39 | ||||
| -rw-r--r-- | src/server/VideoTimer.hx | 2 |
6 files changed, 107 insertions, 19 deletions
diff --git a/build/server.js b/build/server.js index 1e842ca..93dec79 100644 --- a/build/server.js +++ b/build/server.js @@ -1059,7 +1059,7 @@ JsonParser_$30.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.value = null; } ,loadJsonString: function(s,pos,variable) { - this.value = this.loadString(s,pos,variable,["Connected","Disconnected","Login","PasswordRequest","LoginError","Logout","Message","ServerMessage","UpdateClients","BanClient","AddVideo","RemoveVideo","SkipVideo","VideoLoaded","Pause","Play","GetTime","SetTime","SetRate","Rewind","SetLeader","PlayItem","SetNextItem","ToggleItemType","ClearChat","ClearPlaylist","ShufflePlaylist","UpdatePlaylist","TogglePlaylistLock"],"Connected"); + this.value = this.loadString(s,pos,variable,["Connected","Disconnected","Login","PasswordRequest","LoginError","Logout","Message","ServerMessage","UpdateClients","BanClient","AddVideo","RemoveVideo","SkipVideo","VideoLoaded","Pause","Play","GetTime","SetTime","SetRate","Rewind","Flashback","SetLeader","PlayItem","SetNextItem","ToggleItemType","ClearChat","ClearPlaylist","ShufflePlaylist","UpdatePlaylist","TogglePlaylistLock"],"Connected"); } ,__class__: JsonParser_$30 }); @@ -3807,6 +3807,7 @@ server_Logger.prototype = { ,__class__: server_Logger }; var server_Main = function() { + this.flashbackTime = 0.0; this.loadedClientsCount = 0; this.matchGuestName = new EReg("guest [0-9]+",""); this.matchHtmlChars = new EReg("[&^<>'\"]",""); @@ -3857,7 +3858,7 @@ var server_Main = function() { 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 : 97, 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 : 98, className : "server.Main", methodName : "new"}); attempts -= 1; _gthis.port++; preparePort(); @@ -3875,10 +3876,10 @@ server_Main.main = function() { server_Main.prototype = { runServer: function() { var _gthis = this; - haxe_Log.trace("Local: http://" + this.localIp + ":" + this.port,{ fileName : "src/server/Main.hx", lineNumber : 110, className : "server.Main", methodName : "runServer"}); + haxe_Log.trace("Local: http://" + this.localIp + ":" + this.port,{ fileName : "src/server/Main.hx", lineNumber : 111, className : "server.Main", methodName : "runServer"}); server_Utils.getGlobalIp(function(ip) { _gthis.globalIp = ip; - haxe_Log.trace("Global: http://" + _gthis.globalIp + ":" + _gthis.port,{ fileName : "src/server/Main.hx", lineNumber : 113, className : "server.Main", methodName : "runServer"}); + haxe_Log.trace("Global: http://" + _gthis.globalIp + ":" + _gthis.port,{ fileName : "src/server/Main.hx", lineNumber : 114, className : "server.Main", methodName : "runServer"}); }); var dir = "" + this.rootDir + "/res"; server_HttpServer.init(dir,"" + this.rootDir + "/user/res",this.config.localAdmins); @@ -3955,7 +3956,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 : 179, className : "server.Main", methodName : "getUserConfig"}); + haxe_Log.trace("Warning: config field \"" + field + "\" is unknown",{ fileName : "src/server/Main.hx", lineNumber : 180, className : "server.Main", methodName : "getUserConfig"}); } config[field] = Reflect.field(customConfig,field); } @@ -3966,14 +3967,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 : 185, className : "server.Main", methodName : "getUserConfig"}); + haxe_Log.trace("Warning: emote name \"" + emote.name + "\" has copy",{ fileName : "src/server/Main.hx", lineNumber : 186, 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 : 189, className : "server.Main", methodName : "getUserConfig"}); + haxe_Log.trace("Warning: emote url of name \"" + emote.name + "\" has copy",{ fileName : "src/server/Main.hx", lineNumber : 190, className : "server.Main", methodName : "getUserConfig"}); } emoteCopies_h[emote.image] = true; } @@ -4015,7 +4016,7 @@ server_Main.prototype = { js_node_Fs.writeFileSync("" + folder + "/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 : 228, className : "server.Main", methodName : "saveState"}); + haxe_Log.trace("Saving state...",{ fileName : "src/server/Main.hx", lineNumber : 229, className : "server.Main", methodName : "saveState"}); var json = JSON.stringify({ videoList : this.videoList, isPlaylistOpen : this.isPlaylistOpen, itemPos : this.itemPos, messages : this.messages, timer : { time : this.videoTimer.getTime(), paused : this.videoTimer.isPaused()}},null,"\t"); js_node_Fs.writeFileSync(this.statePath,json); this.writeUsers(this.userList); @@ -4024,7 +4025,7 @@ server_Main.prototype = { if(!sys_FileSystem.exists(this.statePath)) { return; } - haxe_Log.trace("Loading state...",{ fileName : "src/server/Main.hx", lineNumber : 246, className : "server.Main", methodName : "loadState"}); + haxe_Log.trace("Loading state...",{ fileName : "src/server/Main.hx", lineNumber : 247, className : "server.Main", methodName : "loadState"}); var data = JSON.parse(js_node_Fs.readFileSync(this.statePath,{ encoding : "utf8"})); this.videoList.length = 0; this.messages.length = 0; @@ -4041,7 +4042,7 @@ server_Main.prototype = { this.videoTimer.pause(); } ,logError: function(type,data) { - haxe_Log.trace(type,{ fileName : "src/server/Main.hx", lineNumber : 264, className : "server.Main", methodName : "logError", customParams : [data]}); + haxe_Log.trace(type,{ fileName : "src/server/Main.hx", lineNumber : 265, className : "server.Main", methodName : "logError", customParams : [data]}); var crashesFolder = "" + this.rootDir + "/user/crashes"; server_Utils.ensureDir(crashesFolder); js_node_Fs.writeFileSync("" + crashesFolder + "/" + (DateTools.format(new Date(),"%Y-%m-%d_%H_%M_%S") + "-" + type) + ".json",JSON.stringify(data,null,"\t")); @@ -4058,7 +4059,7 @@ server_Main.prototype = { if(_gthis.clients.length == 0) { return; } - haxe_Log.trace("Ping " + url,{ fileName : "src/server/Main.hx", lineNumber : 281, className : "server.Main", methodName : "initIntergationHandlers"}); + haxe_Log.trace("Ping " + url,{ fileName : "src/server/Main.hx", lineNumber : 282, className : "server.Main", methodName : "initIntergationHandlers"}); js_node_Http.get(url,null,function(r) { }); }; @@ -4079,13 +4080,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 : 305, className : "server.Main", methodName : "addAdmin"}); + haxe_Log.trace("Admin " + name + " added.",{ fileName : "src/server/Main.hx", lineNumber : 306, 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 : 312, className : "server.Main", methodName : "removeAdmin"}); + haxe_Log.trace("Admin " + name + " removed.",{ fileName : "src/server/Main.hx", lineNumber : 313, className : "server.Main", methodName : "removeAdmin"}); } ,replayLog: function(events) { var _gthis = this; @@ -4129,7 +4130,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("" + name + " connected (" + ip + ")",{ fileName : "src/server/Main.hx", lineNumber : 350, className : "server.Main", methodName : "onConnect"}); + haxe_Log.trace("" + name + " connected (" + ip + ")",{ fileName : "src/server/Main.hx", lineNumber : 351, className : "server.Main", methodName : "onConnect"}); var client = new Client(ws,req,id,name,0); client.setGroupFlag(ClientGroup.Admin,this.config.localAdmins && req.socket.localAddress == ip); this.clients.push(client); @@ -4141,7 +4142,7 @@ server_Main.prototype = { var obj = _gthis.wsEventParser.fromJson(data); 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 : 366, className : "server.Main", methodName : "onConnect"}); + haxe_Log.trace(errors,{ fileName : "src/server/Main.hx", lineNumber : 367, className : "server.Main", methodName : "onConnect"}); _gthis.serverMessage(client,errors); return; } @@ -4155,6 +4156,9 @@ server_Main.prototype = { if(data.type == "GetTime") { return false; } + if(data.type == "Flashback") { + return false; + } if(data.type == "TogglePlaylistLock") { return false; } @@ -4274,7 +4278,7 @@ server_Main.prototype = { if(!internal) { return; } - haxe_Log.trace("Client " + client.name + " disconnected",{ fileName : "src/server/Main.hx", lineNumber : 423, className : "server.Main", methodName : "onMessage"}); + haxe_Log.trace("Client " + client.name + " disconnected",{ fileName : "src/server/Main.hx", lineNumber : 426, className : "server.Main", methodName : "onMessage"}); server_Utils.sortedPush(this.freeIds,client.id); HxOverrides.remove(this.clients,client); this.sendClientList(); @@ -4298,6 +4302,16 @@ server_Main.prototype = { _gthis.broadcast({ type : "ServerMessage", serverMessage : { textId : "" + client.name + " has left"}}); },5000); break; + case "Flashback": + if(!this.checkPermission(client,"rewind")) { + return; + } + if(this.videoList.length == 0) { + return; + } + this.loadFlashbackTime(); + this.broadcast({ type : "Rewind", rewind : { time : this.videoTimer.getTime()}}); + break; case "GetTime": if(this.videoList.length == 0) { return; @@ -4405,6 +4419,9 @@ server_Main.prototype = { if((client.group & 4) == 0) { return; } + if(Math.abs(data.pause.time - this.videoTimer.getTime()) > 30) { + this.saveFlashbackTime(); + } this.videoTimer.setTime(data.pause.time); this.videoTimer.pause(); this.broadcast(data); @@ -4416,6 +4433,9 @@ server_Main.prototype = { if((client.group & 4) == 0) { return; } + if(Math.abs(data.play.time - this.videoTimer.getTime()) > 30) { + this.saveFlashbackTime(); + } this.videoTimer.setTime(data.play.time); this.videoTimer.play(); this.broadcast(data); @@ -4462,6 +4482,7 @@ server_Main.prototype = { if(data.rewind.time < 0) { data.rewind.time = 0; } + this.saveFlashbackTime(); this.videoTimer.setTime(data.rewind.time); this.broadcast(data); break; @@ -4519,6 +4540,9 @@ server_Main.prototype = { if((client.group & 4) == 0) { return; } + if(Math.abs(data.setTime.time - this.videoTimer.getTime()) > 30) { + this.saveFlashbackTime(); + } this.videoTimer.setTime(data.setTime.time); this.broadcastExcept(client,data); break; @@ -4643,7 +4667,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 : 844, className : "server.Main", methodName : "checkBan"}); + haxe_Log.trace("" + client.name + " ban removed",{ fileName : "src/server/Main.hx", lineNumber : 868, className : "server.Main", methodName : "checkBan"}); this.sendClientList(); } break; @@ -4670,6 +4694,9 @@ server_Main.prototype = { return false; } ,restartWaitTimer: function() { + if(this.videoTimer.getTime() > 30) { + this.saveFlashbackTime(); + } this.videoTimer.stop(); if(this.waitVideoStart != null) { this.waitVideoStart.stop(); @@ -4696,6 +4723,18 @@ server_Main.prototype = { this.broadcast({ type : "VideoLoaded"}); this.videoTimer.start(); } + ,saveFlashbackTime: function() { + var time = this.videoTimer.getTime(); + if(Math.abs(this.flashbackTime - time) < 30) { + return; + } + this.flashbackTime = time; + } + ,loadFlashbackTime: function() { + var time = this.videoTimer.getTime(); + this.videoTimer.setTime(this.flashbackTime); + this.flashbackTime = time; + } ,__class__: server_Main }; var server_Utils = function() { }; @@ -4813,9 +4852,9 @@ server_VideoTimer.prototype = { this.start(); } this.startTime += this.pauseTime(); + this.pauseStartTime = 0; var hrtime = process.hrtime(); this.rateStartTime = hrtime[0] + hrtime[1] / 1e9; - this.pauseStartTime = 0; } ,getTime: function() { if(this.startTime == 0) { diff --git a/res/client.js b/res/client.js index b0953ae..bad1a65 100644 --- a/res/client.js +++ b/res/client.js @@ -1398,6 +1398,8 @@ client_Main.prototype = { break; case "Disconnected": break; + case "Flashback": + break; case "GetTime": if(data.getTime.paused == null) { data.getTime.paused = false; @@ -1869,6 +1871,9 @@ client_Main.prototype = { case "clear": this.send({ type : "ClearChat"}); return true; + case "fb":case "flashback": + this.send({ type : "Flashback"}); + return false; case "removeBan":case "unban": this.send({ type : "BanClient", banClient : { name : args[0], time : 0}}); return true; diff --git a/src/Types.hx b/src/Types.hx index c2136b4..6a15bba 100644 --- a/src/Types.hx +++ b/src/Types.hx @@ -215,6 +215,7 @@ enum abstract WsEventType(String) { var SetTime; var SetRate; var Rewind; + var Flashback; var SetLeader; var PlayItem; var SetNextItem; diff --git a/src/client/Main.hx b/src/client/Main.hx index 57a2d0f..28fefe8 100644 --- a/src/client/Main.hx +++ b/src/client/Main.hx @@ -500,6 +500,7 @@ class Main { case Rewind: player.setTime(data.rewind.time); + case Flashback: // server-only case SetLeader: clients.setLeader(data.setLeader.clientName); updateUserList(); @@ -858,6 +859,9 @@ class Main { case "clear": send({type: ClearChat}); return true; + case "flashback", "fb": + send({type: Flashback}); + return false; } if (matchSimpleDate.match(command)) { send({ diff --git a/src/server/Main.hx b/src/server/Main.hx index 2f3a8a4..42abaa9 100644 --- a/src/server/Main.hx +++ b/src/server/Main.hx @@ -27,6 +27,7 @@ using StringTools; class Main { static inline var VIDEO_START_MAX_DELAY = 3000; static inline var VIDEO_SKIP_DELAY = 1000; + static inline var FLASHBACK_DIST = 30; final rootDir = '$__dirname/..'; @@ -379,9 +380,11 @@ class Main { function noTypeObj(data:WsEvent):Bool { if (data.type == GetTime) return false; + if (data.type == Flashback) return false; if (data.type == TogglePlaylistLock) return false; if (data.type == UpdatePlaylist) return false; if (data.type == Logout) return false; + // check if request has same field as type value final t:String = cast data.type; final t = t.charAt(0).toLowerCase() + t.substr(1); return js.Syntax.strictEq(Reflect.field(data, t), null); @@ -600,6 +603,9 @@ class Main { case Pause: if (videoList.length == 0) return; if (!client.isLeader) return; + if (Math.abs(data.pause.time - videoTimer.getTime()) > FLASHBACK_DIST) { + saveFlashbackTime(); + } videoTimer.setTime(data.pause.time); videoTimer.pause(); broadcast(data); @@ -607,6 +613,9 @@ class Main { case Play: if (videoList.length == 0) return; if (!client.isLeader) return; + if (Math.abs(data.play.time - videoTimer.getTime()) > FLASHBACK_DIST) { + saveFlashbackTime(); + } videoTimer.setTime(data.play.time); videoTimer.play(); broadcast(data); @@ -647,6 +656,9 @@ class Main { case SetTime: if (videoList.length == 0) return; if (!client.isLeader) return; + if (Math.abs(data.setTime.time - videoTimer.getTime()) > FLASHBACK_DIST) { + saveFlashbackTime(); + } videoTimer.setTime(data.setTime.time); broadcastExcept(client, data); @@ -661,9 +673,21 @@ class Main { if (videoList.length == 0) return; data.rewind.time += videoTimer.getTime(); if (data.rewind.time < 0) data.rewind.time = 0; + saveFlashbackTime(); videoTimer.setTime(data.rewind.time); broadcast(data); + case Flashback: + if (!checkPermission(client, RewindPerm)) return; + if (videoList.length == 0) return; + loadFlashbackTime(); + broadcast({ + type: Rewind, + rewind: { + time: videoTimer.getTime() + } + }); + case SetLeader: final clientName = data.setLeader.clientName; if (client.name == clientName) { @@ -864,6 +888,7 @@ class Main { var loadedClientsCount = 0; function restartWaitTimer():Void { + if (videoTimer.getTime() > FLASHBACK_DIST) saveFlashbackTime(); videoTimer.stop(); if (waitVideoStart != null) waitVideoStart.stop(); waitVideoStart = Timer.delay(startVideoPlayback, VIDEO_START_MAX_DELAY); @@ -882,4 +907,18 @@ class Main { broadcast({type: VideoLoaded}); videoTimer.start(); } + + var flashbackTime = 0.0; + + function saveFlashbackTime() { + final time = videoTimer.getTime(); + if (Math.abs(flashbackTime - time) < FLASHBACK_DIST) return; + flashbackTime = time; + } + + function loadFlashbackTime() { + final time = videoTimer.getTime(); + videoTimer.setTime(flashbackTime); + flashbackTime = time; + } } diff --git a/src/server/VideoTimer.hx b/src/server/VideoTimer.hx index 2dd6720..fcbb461 100644 --- a/src/server/VideoTimer.hx +++ b/src/server/VideoTimer.hx @@ -34,8 +34,8 @@ class VideoTimer { public function play():Void { if (!isStarted) start(); startTime += pauseTime(); - rateStartTime = stamp(); pauseStartTime = 0; + rateStartTime = stamp(); } public function getTime():Float { |
