diff options
| author | RblSb <msrblsb@gmail.com> | 2020-03-04 20:41:43 +0300 |
|---|---|---|
| committer | RblSb <msrblsb@gmail.com> | 2020-03-04 20:41:43 +0300 |
| commit | 6e28381de77265f8b6a24cdd9c583d1d27d8d7b2 (patch) | |
| tree | 4a960040204580999774bfffea23634c19d02c9c | |
| parent | 4155b95cce55e1176aecb1531b9c06344a2e81b5 (diff) | |
Playlist config limits
| -rw-r--r-- | build/server.js | 45 | ||||
| -rw-r--r-- | default-config.json | 5 | ||||
| -rw-r--r-- | res/client.js | 7 | ||||
| -rw-r--r-- | res/langs/en.json | 7 | ||||
| -rw-r--r-- | res/langs/ru.json | 5 | ||||
| -rw-r--r-- | src/Types.hx | 7 | ||||
| -rw-r--r-- | src/VideoList.hx | 6 | ||||
| -rw-r--r-- | src/client/Main.hx | 13 | ||||
| -rw-r--r-- | src/server/Main.hx | 34 |
9 files changed, 106 insertions, 23 deletions
diff --git a/build/server.js b/build/server.js index 33b0f13..c7b1101 100644 --- a/build/server.js +++ b/build/server.js @@ -376,6 +376,14 @@ _$VideoList_VideoList_$Impl_$.skipItem = function(this1,itemPos) { } return itemPos; }; +_$VideoList_VideoList_$Impl_$.itemsByUser = function(this1,client) { + var i = 0; + var _g = 0; + while(_g < this1.length) if(this1[_g++].author == client.name) { + ++i; + } + return i; +}; var haxe_Log = function() { }; haxe_Log.__name__ = true; haxe_Log.formatOutput = function(v,infos) { @@ -971,8 +979,8 @@ var server_Main = function(port,wsPort) { this.port = port; server_Utils.getGlobalIp(function(ip) { _gthis.globalIp = ip; - haxe_Log.trace("Local: http://" + _gthis.localIp + ":" + port,{ fileName : "src/server/Main.hx", lineNumber : 75, className : "server.Main", methodName : "new"}); - haxe_Log.trace("Global: http://" + _gthis.globalIp + ":" + port,{ fileName : "src/server/Main.hx", lineNumber : 76, className : "server.Main", methodName : "new"}); + haxe_Log.trace("Local: http://" + _gthis.localIp + ":" + port,{ fileName : "src/server/Main.hx", lineNumber : 78, className : "server.Main", methodName : "new"}); + haxe_Log.trace("Global: http://" + _gthis.globalIp + ":" + port,{ fileName : "src/server/Main.hx", lineNumber : 79, className : "server.Main", methodName : "new"}); return; }); var dir = "" + this.rootDir + "/res"; @@ -1015,7 +1023,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 : 108, className : "server.Main", methodName : "loadUserConfig"}); + haxe_Log.trace("Warning: config field \"" + field + "\" is unknown",{ fileName : "src/server/Main.hx", lineNumber : 111, className : "server.Main", methodName : "loadUserConfig"}); } config[field] = Reflect.field(customConfig,field); } @@ -1036,7 +1044,7 @@ server_Main.prototype = { js_node_Fs.writeFileSync("" + folder + "/users.json",JSON.stringify(users,null,"\t")); } ,saveState: function() { - haxe_Log.trace("Saving state...",{ fileName : "src/server/Main.hx", lineNumber : 132, className : "server.Main", methodName : "saveState"}); + haxe_Log.trace("Saving state...",{ fileName : "src/server/Main.hx", lineNumber : 135, 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); } @@ -1044,7 +1052,7 @@ server_Main.prototype = { if(!sys_FileSystem.exists(this.statePath)) { return; } - haxe_Log.trace("Loading state...",{ fileName : "src/server/Main.hx", lineNumber : 149, className : "server.Main", methodName : "loadState"}); + haxe_Log.trace("Loading state...",{ fileName : "src/server/Main.hx", lineNumber : 152, 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; @@ -1061,7 +1069,7 @@ server_Main.prototype = { this.videoTimer.pause(); } ,logError: function(type,data) { - haxe_Log.trace(type,{ fileName : "src/server/Main.hx", lineNumber : 163, className : "server.Main", methodName : "logError", customParams : [data]}); + haxe_Log.trace(type,{ fileName : "src/server/Main.hx", lineNumber : 166, className : "server.Main", methodName : "logError", customParams : [data]}); var crashesFolder = "" + this.rootDir + "/user/crashes"; var name = new Date().toISOString() + "-" + type; if(!sys_FileSystem.exists(crashesFolder)) { @@ -1077,7 +1085,7 @@ server_Main.prototype = { return; } var url = "http://" + process.env["APP_URL"]; - haxe_Log.trace("Ping " + url,{ fileName : "src/server/Main.hx", lineNumber : 177, className : "server.Main", methodName : "initIntergationHandlers"}); + haxe_Log.trace("Ping " + url,{ fileName : "src/server/Main.hx", lineNumber : 180, className : "server.Main", methodName : "initIntergationHandlers"}); js_node_Http.get(url,function(r) { return; }); @@ -1092,14 +1100,14 @@ server_Main.prototype = { } this.userList.admins.push({ name : name, hash : hash}); this.writeUsers(this.userList); - haxe_Log.trace("Admin " + name + " added.",{ fileName : "src/server/Main.hx", lineNumber : 192, className : "server.Main", methodName : "addAdmin"}); + haxe_Log.trace("Admin " + name + " added.",{ fileName : "src/server/Main.hx", lineNumber : 195, className : "server.Main", methodName : "addAdmin"}); } ,onConnect: function(ws,req) { var _gthis = this; var ip = req.connection.remoteAddress; 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 : 199, className : "server.Main", methodName : "onConnect"}); + haxe_Log.trace("" + name + " connected (" + ip + ")",{ fileName : "src/server/Main.hx", lineNumber : 202, className : "server.Main", methodName : "onConnect"}); var client = new Client(ws,req,id,name,0); client.setGroupFlag(ClientGroup.Admin,req.connection.localAddress == ip); this.clients.push(client); @@ -1123,7 +1131,7 @@ server_Main.prototype = { return; }); ws.on("close",function(err) { - haxe_Log.trace("Client " + client.name + " disconnected",{ fileName : "src/server/Main.hx", lineNumber : 229, className : "server.Main", methodName : "onConnect"}); + haxe_Log.trace("Client " + client.name + " disconnected",{ fileName : "src/server/Main.hx", lineNumber : 232, className : "server.Main", methodName : "onConnect"}); server_Utils.sortedPush(_gthis.freeIds,client.id); HxOverrides.remove(_gthis.clients,client); _gthis.sendClientList(); @@ -1145,6 +1153,15 @@ server_Main.prototype = { switch(data.type) { case "AddVideo": if((client.group & 4) == 0 && !this.isPlaylistOpen) { + this.serverMessage(client,"accessError"); + return; + } + if(this.config.totalVideoLimit != 0 && this.videoList.length >= this.config.totalVideoLimit) { + this.serverMessage(client,"totalVideoLimitError"); + return; + } + if(this.config.userVideoLimit != 0 && _$VideoList_VideoList_$Impl_$.itemsByUser(this.videoList,client) >= this.config.userVideoLimit) { + this.serverMessage(client,"videoLimitPerUserError"); return; } var item = data.addVideo.item; @@ -1156,6 +1173,7 @@ server_Main.prototype = { if(Lambda.exists(this.videoList,function(i) { return i.url == item.url; })) { + this.serverMessage(client,"videoAlreadyExistsError"); return; } _$VideoList_VideoList_$Impl_$.addItem(this.videoList,item,data.addVideo.atEnd,this.itemPos); @@ -1192,6 +1210,7 @@ server_Main.prototype = { case "Login": var name = data.login.clientName; if(this.badNickName(name) || name.length > this.config.maxLoginLength || ClientTools.getByName(this.clients,name) != null) { + this.serverMessage(client,"usernameError"); this.send(client,{ type : "LoginError"}); return; } @@ -1212,6 +1231,7 @@ server_Main.prototype = { })) { client.setGroupFlag(ClientGroup.Admin,true); } else { + this.serverMessage(client,"passwordMatchError"); this.send(client,{ type : "LoginError"}); return; } @@ -1304,6 +1324,8 @@ server_Main.prototype = { this.videoTimer.setTime(data.rewind.time); this.broadcast(data); break; + case "ServerMessage": + break; case "SetLeader": ClientTools.setLeader(this.clients,data.setLeader.clientName); this.broadcast({ type : "SetLeader", setLeader : { clientName : data.setLeader.clientName}}); @@ -1390,6 +1412,9 @@ server_Main.prototype = { ,sendClientList: function() { this.broadcast({ type : "UpdateClients", updateClients : { clients : this.clientList()}}); } + ,serverMessage: function(client,textId) { + this.send(client,{ type : "ServerMessage", serverMessage : { textId : textId}}); + } ,send: function(client,data) { client.ws.send(JSON.stringify(data),null); } diff --git a/default-config.json b/default-config.json index 40c3b11..4635f38 100644 --- a/default-config.json +++ b/default-config.json @@ -2,8 +2,9 @@ "channelName": "SyncTube", "maxLoginLength": 20, "maxMessageLength": 500, - "serverChatHistory": 30, - "videoLimit": 0, + "serverChatHistory": 50, + "totalVideoLimit": 0, + "userVideoLimit": 0, "leaderRequest": "everyone", "emotes": [ {"name": ":adorable:", "image": "https://i.imgur.com/5GxNwDY.png"}, diff --git a/res/client.js b/res/client.js index e785320..d603436 100644 --- a/res/client.js +++ b/res/client.js @@ -998,8 +998,6 @@ client_Main.prototype = { this.onLogin(data.login.clients,data.login.clientName); break; case "LoginError": - var text = StringTools.replace(Lang.get("usernameError"),"$MAX","" + this.config.maxLoginLength); - this.serverMessage(4,text); this.showGuestLoginPanel(); break; case "Logout": @@ -1039,6 +1037,11 @@ client_Main.prototype = { case "Rewind": this.player.setTime(data.rewind.time); break; + case "ServerMessage": + var id = data.serverMessage.textId; + var text = id == "usernameError" ? StringTools.replace(Lang.get(id),"$MAX","" + this.config.maxLoginLength) : Lang.get(id); + this.serverMessage(4,text); + break; case "SetLeader": ClientTools.setLeader(this.clients,data.setLeader.clientName); this.updateUserList(); diff --git a/res/langs/en.json b/res/langs/en.json index ef70b8c..375bd79 100644 --- a/res/langs/en.json +++ b/res/langs/en.json @@ -5,7 +5,12 @@ "joined": "joined", "online": "online", "nothingPlaying": "Nothing Playing", - "usernameError": "Username must be from 1 to $MAX characters and don't repeat another's. Characters &^<>'\" are not allowed.", + "usernameError": "Username length must be from 1 to $MAX characters and don't repeat another's. Characters &^<>'\" are not allowed.", + "passwordMatchError": "Wrong password.", + "accessError": "Access Error.", + "totalVideoLimitError": "Playlist video limit has been reached.", + "userVideoLimitError": "Playlist video limit per user has been reached.", + "videoAlreadyExistsError": "The video already exists in playlist.", "addVideoError": "Failed to add video.", "rawVideo": "Raw video", "videos": "videos", diff --git a/res/langs/ru.json b/res/langs/ru.json index 112e931..a52142f 100644 --- a/res/langs/ru.json +++ b/res/langs/ru.json @@ -6,6 +6,11 @@ "online": "онлайн", "nothingPlaying": "Ничего не играет", "usernameError": "Ник должен быть от 1 до $MAX символов и не повторять чужие. Символы &^<>'\" запрещены.", + "passwordMatchError": "Неправильный пароль.", + "accessError": "Ошибка доступа.", + "totalVideoLimitError": "Был достингут лимит видео в плейлисте.", + "userVideoLimitError": "Был достингут лимит видео на пользователя.", + "videoAlreadyExistsError": "Видео уже имеется в плейлисте.", "addVideoError": "Не удалось добавить видео.", "rawVideo": "Исходное видео", "videos": "видео", diff --git a/src/Types.hx b/src/Types.hx index 5dbc07a..e5b467a 100644 --- a/src/Types.hx +++ b/src/Types.hx @@ -12,7 +12,8 @@ typedef Config = { maxLoginLength:Int, maxMessageLength:Int, serverChatHistory:Int, - videoLimit:Int, + totalVideoLimit:Int, + userVideoLimit:Int, leaderRequest:String, emotes:Array<Emote>, filters:Array<Filter>, @@ -84,6 +85,9 @@ typedef WsEvent = { clientName:String, text:String }, + ?serverMessage:{ + textId:String + }, ?updateClients:{ clients:Array<ClientData>, }, @@ -140,6 +144,7 @@ enum abstract WsEventType(String) { var LoginError; var Logout; var Message; + var ServerMessage; var UpdateClients; // var AddClient; // var RemoveClient; diff --git a/src/VideoList.hx b/src/VideoList.hx index 2f13b6c..e2d88d5 100644 --- a/src/VideoList.hx +++ b/src/VideoList.hx @@ -64,4 +64,10 @@ abstract VideoList(Array<VideoItem>) from Array<VideoItem> to Array<VideoItem> { return itemPos; } + public function itemsByUser(client:Client):Int { + var i = 0; + for (item in this) if (item.author == client.name) i++; + return i; + } + } diff --git a/src/client/Main.hx b/src/client/Main.hx index a5fe9bb..b2f51ca 100644 --- a/src/client/Main.hx +++ b/src/client/Main.hx @@ -267,9 +267,6 @@ class Main { showGuestPasswordPanel(); case LoginError: - final text = Lang.get("usernameError") - .replace("$MAX", '${config.maxLoginLength}'); - serverMessage(4, text); showGuestLoginPanel(); case Logout: @@ -284,6 +281,16 @@ class Main { case Message: addMessage(data.message.clientName, data.message.text); + case ServerMessage: + final id = data.serverMessage.textId; + final text = switch (id) { + case "usernameError": + Lang.get(id).replace("$MAX", '${config.maxLoginLength}'); + default: + Lang.get(id); + } + serverMessage(4, text); + case AddVideo: player.addVideoItem(data.addVideo.item, data.addVideo.atEnd); if (player.itemsLength() == 1) player.setVideo(0); diff --git a/src/server/Main.hx b/src/server/Main.hx index 6a2ad82..8f71bd2 100644 --- a/src/server/Main.hx +++ b/src/server/Main.hx @@ -13,7 +13,10 @@ import js.npm.ws.Server as WSServer; import js.npm.ws.WebSocket; import js.node.http.IncomingMessage; import js.node.Http; -import Types; +import Types.Config; +import Types.UserList; +import Types.Message; +import Types.WsEvent; using StringTools; using ClientTools; using Lambda; @@ -249,6 +252,7 @@ class Main { final name = data.login.clientName; if (badNickName(name) || name.length > config.maxLoginLength || clients.getByName(name) != null) { + serverMessage(client, "usernameError"); send(client, {type: LoginError}); return; } @@ -263,7 +267,7 @@ class Main { a -> a.name == name && a.hash == hash )) client.isAdmin = true; else { - // TODO server msg type + serverMessage(client, "passwordMatchError"); send(client, {type: LoginError}); return; } @@ -310,8 +314,22 @@ class Main { if (messages.length > config.serverChatHistory) messages.shift(); broadcast(data); + case ServerMessage: case AddVideo: - if (!client.isAdmin && !isPlaylistOpen) return; + if (!client.isAdmin && !isPlaylistOpen) { + serverMessage(client, "accessError"); + return; + } + if (config.totalVideoLimit != 0 + && videoList.length >= config.totalVideoLimit) { + serverMessage(client, "totalVideoLimitError"); + return; + } + if (config.userVideoLimit != 0 + && videoList.itemsByUser(client) >= config.userVideoLimit) { + serverMessage(client, "videoLimitPerUserError"); + return; + } final item = data.addVideo.item; item.author = client.name; final local = '$localIp:$port'; @@ -319,7 +337,7 @@ class Main { item.url = item.url.replace(local, '$globalIp:$port'); } if (videoList.exists(i -> i.url == item.url)) { - // TODO send server message + serverMessage(client, "videoAlreadyExistsError"); return; } videoList.addItem(item, data.addVideo.atEnd, itemPos); @@ -486,6 +504,14 @@ class Main { }); } + function serverMessage(client:Client, textId:String):Void { + send(client, { + type: ServerMessage, serverMessage: { + textId: textId + } + }); + } + function send(client:Client, data:WsEvent):Void { client.ws.send(Json.stringify(data), null); } |
