aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build/server.js45
-rw-r--r--default-config.json5
-rw-r--r--res/client.js7
-rw-r--r--res/langs/en.json7
-rw-r--r--res/langs/ru.json5
-rw-r--r--src/Types.hx7
-rw-r--r--src/VideoList.hx6
-rw-r--r--src/client/Main.hx13
-rw-r--r--src/server/Main.hx34
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);
}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage