diff options
| -rw-r--r-- | build/server.js | 1486 | ||||
| -rw-r--r-- | res/client.js | 194 | ||||
| -rw-r--r-- | res/css/des.css | 24 | ||||
| -rw-r--r-- | res/index.html | 13 | ||||
| -rw-r--r-- | res/langs/en.json | 4 | ||||
| -rw-r--r-- | res/langs/ru.json | 4 | ||||
| -rw-r--r-- | src/Types.hx | 20 | ||||
| -rw-r--r-- | src/client/Buttons.hx | 61 | ||||
| -rw-r--r-- | src/client/JsApi.hx | 24 | ||||
| -rw-r--r-- | src/client/Main.hx | 45 | ||||
| -rw-r--r-- | src/client/Utils.hx | 56 | ||||
| -rw-r--r-- | src/client/players/Raw.hx | 2 | ||||
| -rw-r--r-- | src/import.hx | 2 | ||||
| -rw-r--r-- | src/server/Cache.hx | 139 | ||||
| -rw-r--r-- | src/server/HttpServer.hx | 214 | ||||
| -rw-r--r-- | src/server/Main.hx | 34 | ||||
| -rw-r--r-- | src/server/Utils.hx | 6 | ||||
| -rw-r--r-- | src/tools/MathTools.hx | 55 | ||||
| -rw-r--r-- | src/utils/YoutubeUtils.hx | 2 |
19 files changed, 1676 insertions, 709 deletions
diff --git a/build/server.js b/build/server.js index e2f25cc..ac708e8 100644 --- a/build/server.js +++ b/build/server.js @@ -523,7 +523,7 @@ JsonParser_$1.__name__ = true; JsonParser_$1.__super__ = json2object_reader_BaseParser; JsonParser_$1.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { - this.errors.push(json2object_Error.IncorrectType(variable,"{ ?updatePlaylist : Null<{ videoList : Array<VideoItem> }>, ?updateClients : Null<{ clients : Array<ClientData> }>, type : WsEventType, ?togglePlaylistLock : Null<{ isOpen : Bool }>, ?toggleItemType : Null<{ pos : Int }>, ?skipVideo : Null<{ url : String }>, ?setTime : Null<{ time : Float }>, ?setRate : Null<{ rate : Float }>, ?setNextItem : Null<{ pos : Int }>, ?setLeader : Null<{ clientName : String }>, ?serverMessage : Null<{ textId : String }>, ?rewind : Null<{ time : Float }>, ?removeVideo : Null<{ url : String }>, ?playItem : Null<{ pos : Int }>, ?play : Null<{ time : Float }>, ?pause : Null<{ time : Float }>, ?message : Null<{ text : String, clientName : String }>, ?logout : Null<{ oldClientName : String, clients : Array<ClientData>, clientName : String }>, ?login : Null<{ ?passHash : Null<String>, ?isUnknownClient : Null<Bool>, ?clients : Null<Array<ClientData>>, clientName : String }>, ?kickClient : Null<{ name : String }>, ?getTime : Null<GetTimeEvent>, ?dump : Null<{ data : String }>, ?connected : Null<{ videoList : Array<VideoItem>, uuid : String, playersCacheSupport : Array<PlayerType>, itemPos : Int, isUnknownClient : Bool, isPlaylistOpen : Bool, history : Array<Message>, globalIp : String, config : Config, clients : Array<ClientData>, clientName : String }>, ?banClient : Null<{ time : Float, name : String }>, ?addVideo : Null<{ item : VideoItem, atEnd : Bool }> }",pos)); + this.errors.push(json2object_Error.IncorrectType(variable,"{ ?updatePlaylist : Null<{ videoList : Array<VideoItem> }>, ?updateClients : Null<{ clients : Array<ClientData> }>, type : WsEventType, ?togglePlaylistLock : Null<{ isOpen : Bool }>, ?toggleItemType : Null<{ pos : Int }>, ?skipVideo : Null<{ url : String }>, ?setTime : Null<{ time : Float }>, ?setRate : Null<{ rate : Float }>, ?setNextItem : Null<{ pos : Int }>, ?setLeader : Null<{ clientName : String }>, ?serverMessage : Null<{ textId : String }>, ?rewind : Null<{ time : Float }>, ?removeVideo : Null<{ url : String }>, ?progress : Null<{ type : ProgressType, ratio : Float, ?data : Null<String> }>, ?playItem : Null<{ pos : Int }>, ?play : Null<{ time : Float }>, ?pause : Null<{ time : Float }>, ?message : Null<{ text : String, clientName : String }>, ?logout : Null<{ oldClientName : String, clients : Array<ClientData>, clientName : String }>, ?login : Null<{ ?passHash : Null<String>, ?isUnknownClient : Null<Bool>, ?clients : Null<Array<ClientData>>, clientName : String }>, ?kickClient : Null<{ name : String }>, ?getTime : Null<GetTimeEvent>, ?dump : Null<{ data : String }>, ?connected : Null<{ videoList : Array<VideoItem>, uuid : String, playersCacheSupport : Array<PlayerType>, itemPos : Int, isUnknownClient : Bool, isPlaylistOpen : Bool, history : Array<Message>, globalIp : String, config : Config, clients : Array<ClientData>, clientName : String }>, ?banClient : Null<{ time : Float, name : String }>, ?addVideo : Null<{ item : VideoItem, atEnd : Bool }> }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } ,loadJsonNull: function(pos,variable) { @@ -531,7 +531,7 @@ JsonParser_$1.prototype = $extend(json2object_reader_BaseParser.prototype,{ } ,loadJsonObject: function(o,pos,variable) { var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["addVideo","banClient","connected","dump","getTime","kickClient","login","logout","message","pause","play","playItem","removeVideo","rewind","serverMessage","setLeader","setNextItem","setRate","setTime","skipVideo","toggleItemType","togglePlaylistLock","type","updateClients","updatePlaylist"],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true]); + this.objectSetupAssign(assigned,["addVideo","banClient","connected","dump","getTime","kickClient","login","logout","message","pause","play","playItem","progress","removeVideo","rewind","serverMessage","setLeader","setNextItem","setRate","setTime","skipVideo","toggleItemType","togglePlaylistLock","type","updateClients","updatePlaylist"],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true]); this.value = this.getAuto(); var _g = 0; while(_g < o.length) { @@ -574,44 +574,47 @@ JsonParser_$1.prototype = $extend(json2object_reader_BaseParser.prototype,{ case "playItem": this.value.playItem = this.loadObjectField(($_=new JsonParser_$24(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"playItem",assigned,this.value.playItem,pos); break; + case "progress": + this.value.progress = this.loadObjectField(($_=new JsonParser_$26(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"progress",assigned,this.value.progress,pos); + break; case "removeVideo": - this.value.removeVideo = this.loadObjectField(($_=new JsonParser_$26(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"removeVideo",assigned,this.value.removeVideo,pos); + this.value.removeVideo = this.loadObjectField(($_=new JsonParser_$28(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"removeVideo",assigned,this.value.removeVideo,pos); break; case "rewind": this.value.rewind = this.loadObjectField(($_=new JsonParser_$22(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"rewind",assigned,this.value.rewind,pos); break; case "serverMessage": - this.value.serverMessage = this.loadObjectField(($_=new JsonParser_$28(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"serverMessage",assigned,this.value.serverMessage,pos); + this.value.serverMessage = this.loadObjectField(($_=new JsonParser_$30(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"serverMessage",assigned,this.value.serverMessage,pos); break; case "setLeader": - this.value.setLeader = this.loadObjectField(($_=new JsonParser_$30(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"setLeader",assigned,this.value.setLeader,pos); + this.value.setLeader = this.loadObjectField(($_=new JsonParser_$32(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"setLeader",assigned,this.value.setLeader,pos); break; case "setNextItem": this.value.setNextItem = this.loadObjectField(($_=new JsonParser_$24(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"setNextItem",assigned,this.value.setNextItem,pos); break; case "setRate": - this.value.setRate = this.loadObjectField(($_=new JsonParser_$32(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"setRate",assigned,this.value.setRate,pos); + this.value.setRate = this.loadObjectField(($_=new JsonParser_$34(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"setRate",assigned,this.value.setRate,pos); break; case "setTime": this.value.setTime = this.loadObjectField(($_=new JsonParser_$22(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"setTime",assigned,this.value.setTime,pos); break; case "skipVideo": - this.value.skipVideo = this.loadObjectField(($_=new JsonParser_$26(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"skipVideo",assigned,this.value.skipVideo,pos); + this.value.skipVideo = this.loadObjectField(($_=new JsonParser_$28(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"skipVideo",assigned,this.value.skipVideo,pos); break; case "toggleItemType": this.value.toggleItemType = this.loadObjectField(($_=new JsonParser_$24(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"toggleItemType",assigned,this.value.toggleItemType,pos); break; case "togglePlaylistLock": - this.value.togglePlaylistLock = this.loadObjectField(($_=new JsonParser_$34(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"togglePlaylistLock",assigned,this.value.togglePlaylistLock,pos); + this.value.togglePlaylistLock = this.loadObjectField(($_=new JsonParser_$36(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"togglePlaylistLock",assigned,this.value.togglePlaylistLock,pos); break; case "type": - this.value.type = this.loadObjectField(($_=new JsonParser_$35(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"type",assigned,this.value.type,pos); + this.value.type = this.loadObjectField(($_=new JsonParser_$37(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"type",assigned,this.value.type,pos); break; case "updateClients": - this.value.updateClients = this.loadObjectField(($_=new JsonParser_$37(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"updateClients",assigned,this.value.updateClients,pos); + this.value.updateClients = this.loadObjectField(($_=new JsonParser_$39(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"updateClients",assigned,this.value.updateClients,pos); break; case "updatePlaylist": - this.value.updatePlaylist = this.loadObjectField(($_=new JsonParser_$39(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"updatePlaylist",assigned,this.value.updatePlaylist,pos); + this.value.updatePlaylist = this.loadObjectField(($_=new JsonParser_$41(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"updatePlaylist",assigned,this.value.updatePlaylist,pos); break; default: this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); @@ -620,7 +623,7 @@ JsonParser_$1.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { addVideo : new JsonParser_$3([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), banClient : new JsonParser_$5([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), connected : new JsonParser_$7([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), dump : new JsonParser_$9([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), getTime : new JsonParser_$12([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), kickClient : new JsonParser_$14([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), login : new JsonParser_$16([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), logout : new JsonParser_$18([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), message : new JsonParser_$20([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), pause : new JsonParser_$22([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), play : new JsonParser_$22([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), playItem : new JsonParser_$24([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), removeVideo : new JsonParser_$26([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), rewind : new JsonParser_$22([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), serverMessage : new JsonParser_$28([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), setLeader : new JsonParser_$30([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), setNextItem : new JsonParser_$24([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), setRate : new JsonParser_$32([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), setTime : new JsonParser_$22([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), skipVideo : new JsonParser_$26([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), toggleItemType : new JsonParser_$24([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), togglePlaylistLock : new JsonParser_$34([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), type : new JsonParser_$35([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), updateClients : new JsonParser_$37([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), updatePlaylist : new JsonParser_$39([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { addVideo : new JsonParser_$3([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), banClient : new JsonParser_$5([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), connected : new JsonParser_$7([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), dump : new JsonParser_$9([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), getTime : new JsonParser_$12([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), kickClient : new JsonParser_$14([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), login : new JsonParser_$16([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), logout : new JsonParser_$18([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), message : new JsonParser_$20([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), pause : new JsonParser_$22([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), play : new JsonParser_$22([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), playItem : new JsonParser_$24([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), progress : new JsonParser_$26([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), removeVideo : new JsonParser_$28([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), rewind : new JsonParser_$22([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), serverMessage : new JsonParser_$30([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), setLeader : new JsonParser_$32([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), setNextItem : new JsonParser_$24([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), setRate : new JsonParser_$34([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), setTime : new JsonParser_$22([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), skipVideo : new JsonParser_$28([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), toggleItemType : new JsonParser_$24([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), togglePlaylistLock : new JsonParser_$36([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), type : new JsonParser_$37([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), updateClients : new JsonParser_$39([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), updatePlaylist : new JsonParser_$41([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$1 }); @@ -650,16 +653,16 @@ JsonParser_$12.prototype = $extend(json2object_reader_BaseParser.prototype,{ ++_g; switch(field.name) { case "paused": - this.value.paused = this.loadObjectField(($_=new JsonParser_$58(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"paused",assigned,this.value.paused,pos); + this.value.paused = this.loadObjectField(($_=new JsonParser_$61(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"paused",assigned,this.value.paused,pos); break; case "pausedByServer": - this.value.pausedByServer = this.loadObjectField(($_=new JsonParser_$58(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"pausedByServer",assigned,this.value.pausedByServer,pos); + this.value.pausedByServer = this.loadObjectField(($_=new JsonParser_$61(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"pausedByServer",assigned,this.value.pausedByServer,pos); break; case "rate": - this.value.rate = this.loadObjectField(($_=new JsonParser_$60(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"rate",assigned,this.value.rate,pos); + this.value.rate = this.loadObjectField(($_=new JsonParser_$63(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"rate",assigned,this.value.rate,pos); break; case "time": - this.value.time = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"time",assigned,this.value.time,pos); + this.value.time = this.loadObjectField(($_=new JsonParser_$49(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"time",assigned,this.value.time,pos); break; default: this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); @@ -668,7 +671,7 @@ JsonParser_$12.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { paused : new JsonParser_$58([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), pausedByServer : new JsonParser_$58([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), rate : new JsonParser_$60([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), time : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { paused : new JsonParser_$61([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), pausedByServer : new JsonParser_$61([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), rate : new JsonParser_$63([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), time : new JsonParser_$49([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$12 }); @@ -697,7 +700,7 @@ JsonParser_$14.prototype = $extend(json2object_reader_BaseParser.prototype,{ var field = o[_g]; ++_g; if(field.name == "name") { - this.value.name = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"name",assigned,this.value.name,pos); + this.value.name = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"name",assigned,this.value.name,pos); } else { this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); } @@ -705,7 +708,7 @@ JsonParser_$14.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { name : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { name : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$14 }); @@ -735,16 +738,16 @@ JsonParser_$16.prototype = $extend(json2object_reader_BaseParser.prototype,{ ++_g; switch(field.name) { case "clientName": - this.value.clientName = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clientName",assigned,this.value.clientName,pos); + this.value.clientName = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clientName",assigned,this.value.clientName,pos); break; case "clients": - this.value.clients = this.loadObjectField(($_=new JsonParser_$56(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clients",assigned,this.value.clients,pos); + this.value.clients = this.loadObjectField(($_=new JsonParser_$59(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clients",assigned,this.value.clients,pos); break; case "isUnknownClient": - this.value.isUnknownClient = this.loadObjectField(($_=new JsonParser_$58(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isUnknownClient",assigned,this.value.isUnknownClient,pos); + this.value.isUnknownClient = this.loadObjectField(($_=new JsonParser_$61(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isUnknownClient",assigned,this.value.isUnknownClient,pos); break; case "passHash": - this.value.passHash = this.loadObjectField(($_=new JsonParser_$50(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"passHash",assigned,this.value.passHash,pos); + this.value.passHash = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"passHash",assigned,this.value.passHash,pos); break; default: this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); @@ -753,7 +756,7 @@ JsonParser_$16.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { clientName : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), clients : new JsonParser_$56([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isUnknownClient : new JsonParser_$58([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), passHash : new JsonParser_$50([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { clientName : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), clients : new JsonParser_$59([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isUnknownClient : new JsonParser_$61([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), passHash : new JsonParser_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$16 }); @@ -783,13 +786,13 @@ JsonParser_$18.prototype = $extend(json2object_reader_BaseParser.prototype,{ ++_g; switch(field.name) { case "clientName": - this.value.clientName = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clientName",assigned,this.value.clientName,pos); + this.value.clientName = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clientName",assigned,this.value.clientName,pos); break; case "clients": - this.value.clients = this.loadObjectField(($_=new JsonParser_$51(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clients",assigned,this.value.clients,pos); + this.value.clients = this.loadObjectField(($_=new JsonParser_$53(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clients",assigned,this.value.clients,pos); break; case "oldClientName": - this.value.oldClientName = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"oldClientName",assigned,this.value.oldClientName,pos); + this.value.oldClientName = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"oldClientName",assigned,this.value.oldClientName,pos); break; default: this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); @@ -798,7 +801,7 @@ JsonParser_$18.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { clientName : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), clients : new JsonParser_$51([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), oldClientName : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { clientName : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), clients : new JsonParser_$53([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), oldClientName : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$18 }); @@ -828,10 +831,10 @@ JsonParser_$20.prototype = $extend(json2object_reader_BaseParser.prototype,{ ++_g; switch(field.name) { case "clientName": - this.value.clientName = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clientName",assigned,this.value.clientName,pos); + this.value.clientName = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clientName",assigned,this.value.clientName,pos); break; case "text": - this.value.text = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"text",assigned,this.value.text,pos); + this.value.text = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"text",assigned,this.value.text,pos); break; default: this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); @@ -840,7 +843,7 @@ JsonParser_$20.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { clientName : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), text : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { clientName : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), text : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$20 }); @@ -869,7 +872,7 @@ JsonParser_$22.prototype = $extend(json2object_reader_BaseParser.prototype,{ var field = o[_g]; ++_g; if(field.name == "time") { - this.value.time = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"time",assigned,this.value.time,pos); + this.value.time = this.loadObjectField(($_=new JsonParser_$49(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"time",assigned,this.value.time,pos); } else { this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); } @@ -877,7 +880,7 @@ JsonParser_$22.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { time : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { time : new JsonParser_$49([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$22 }); @@ -906,7 +909,7 @@ JsonParser_$24.prototype = $extend(json2object_reader_BaseParser.prototype,{ var field = o[_g]; ++_g; if(field.name == "pos") { - this.value.pos = this.loadObjectField(($_=new JsonParser_$54(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"pos",assigned,this.value.pos,pos); + this.value.pos = this.loadObjectField(($_=new JsonParser_$56(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"pos",assigned,this.value.pos,pos); } else { this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); } @@ -914,7 +917,7 @@ JsonParser_$24.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { pos : new JsonParser_$54([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { pos : new JsonParser_$56([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$24 }); @@ -928,7 +931,7 @@ JsonParser_$26.__name__ = true; JsonParser_$26.__super__ = json2object_reader_BaseParser; JsonParser_$26.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { - this.errors.push(json2object_Error.IncorrectType(variable,"{ url : String }",pos)); + this.errors.push(json2object_Error.IncorrectType(variable,"{ type : ProgressType, ratio : Float, ?data : Null<String> }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } ,loadJsonNull: function(pos,variable) { @@ -936,22 +939,30 @@ JsonParser_$26.prototype = $extend(json2object_reader_BaseParser.prototype,{ } ,loadJsonObject: function(o,pos,variable) { var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["url"],[false]); + this.objectSetupAssign(assigned,["data","ratio","type"],[true,false,false]); this.value = this.getAuto(); var _g = 0; while(_g < o.length) { var field = o[_g]; ++_g; - if(field.name == "url") { - this.value.url = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"url",assigned,this.value.url,pos); - } else { + switch(field.name) { + case "data": + this.value.data = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"data",assigned,this.value.data,pos); + break; + case "ratio": + this.value.ratio = this.loadObjectField(($_=new JsonParser_$49(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"ratio",assigned,this.value.ratio,pos); + break; + case "type": + this.value.type = this.loadObjectField(($_=new JsonParser_$57(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"type",assigned,this.value.type,pos); + break; + default: this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); } } this.objectErrors(assigned,pos); } ,getAuto: function() { - return { url : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { data : new JsonParser_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), ratio : new JsonParser_$49([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), type : new JsonParser_$57([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$26 }); @@ -965,7 +976,7 @@ JsonParser_$28.__name__ = true; JsonParser_$28.__super__ = json2object_reader_BaseParser; JsonParser_$28.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { - this.errors.push(json2object_Error.IncorrectType(variable,"{ textId : String }",pos)); + this.errors.push(json2object_Error.IncorrectType(variable,"{ url : String }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } ,loadJsonNull: function(pos,variable) { @@ -973,14 +984,14 @@ JsonParser_$28.prototype = $extend(json2object_reader_BaseParser.prototype,{ } ,loadJsonObject: function(o,pos,variable) { var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["textId"],[false]); + this.objectSetupAssign(assigned,["url"],[false]); this.value = this.getAuto(); var _g = 0; while(_g < o.length) { var field = o[_g]; ++_g; - if(field.name == "textId") { - this.value.textId = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"textId",assigned,this.value.textId,pos); + if(field.name == "url") { + this.value.url = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"url",assigned,this.value.url,pos); } else { this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); } @@ -988,7 +999,7 @@ JsonParser_$28.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { textId : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { url : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$28 }); @@ -1018,10 +1029,10 @@ JsonParser_$3.prototype = $extend(json2object_reader_BaseParser.prototype,{ ++_g; switch(field.name) { case "atEnd": - this.value.atEnd = this.loadObjectField(($_=new JsonParser_$46(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"atEnd",assigned,this.value.atEnd,pos); + this.value.atEnd = this.loadObjectField(($_=new JsonParser_$48(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"atEnd",assigned,this.value.atEnd,pos); break; case "item": - this.value.item = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"item",assigned,this.value.item,pos); + this.value.item = this.loadObjectField(($_=new JsonParser_$46(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"item",assigned,this.value.item,pos); break; default: this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); @@ -1030,7 +1041,7 @@ JsonParser_$3.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { atEnd : new JsonParser_$46([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), item : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { atEnd : new JsonParser_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), item : new JsonParser_$46([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$3 }); @@ -1044,7 +1055,7 @@ JsonParser_$30.__name__ = true; JsonParser_$30.__super__ = json2object_reader_BaseParser; JsonParser_$30.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { - this.errors.push(json2object_Error.IncorrectType(variable,"{ clientName : String }",pos)); + this.errors.push(json2object_Error.IncorrectType(variable,"{ textId : String }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } ,loadJsonNull: function(pos,variable) { @@ -1052,14 +1063,14 @@ JsonParser_$30.prototype = $extend(json2object_reader_BaseParser.prototype,{ } ,loadJsonObject: function(o,pos,variable) { var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["clientName"],[false]); + this.objectSetupAssign(assigned,["textId"],[false]); this.value = this.getAuto(); var _g = 0; while(_g < o.length) { var field = o[_g]; ++_g; - if(field.name == "clientName") { - this.value.clientName = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clientName",assigned,this.value.clientName,pos); + if(field.name == "textId") { + this.value.textId = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"textId",assigned,this.value.textId,pos); } else { this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); } @@ -1067,7 +1078,7 @@ JsonParser_$30.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { clientName : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { textId : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$30 }); @@ -1081,7 +1092,7 @@ JsonParser_$32.__name__ = true; JsonParser_$32.__super__ = json2object_reader_BaseParser; JsonParser_$32.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { - this.errors.push(json2object_Error.IncorrectType(variable,"{ rate : Float }",pos)); + this.errors.push(json2object_Error.IncorrectType(variable,"{ clientName : String }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } ,loadJsonNull: function(pos,variable) { @@ -1089,14 +1100,14 @@ JsonParser_$32.prototype = $extend(json2object_reader_BaseParser.prototype,{ } ,loadJsonObject: function(o,pos,variable) { var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["rate"],[false]); + this.objectSetupAssign(assigned,["clientName"],[false]); this.value = this.getAuto(); var _g = 0; while(_g < o.length) { var field = o[_g]; ++_g; - if(field.name == "rate") { - this.value.rate = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"rate",assigned,this.value.rate,pos); + if(field.name == "clientName") { + this.value.clientName = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clientName",assigned,this.value.clientName,pos); } else { this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); } @@ -1104,7 +1115,7 @@ JsonParser_$32.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { rate : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { clientName : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$32 }); @@ -1118,6 +1129,43 @@ JsonParser_$34.__name__ = true; JsonParser_$34.__super__ = json2object_reader_BaseParser; JsonParser_$34.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { + this.errors.push(json2object_Error.IncorrectType(variable,"{ rate : Float }",pos)); + json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); + } + ,loadJsonNull: function(pos,variable) { + this.value = null; + } + ,loadJsonObject: function(o,pos,variable) { + var assigned = new haxe_ds_StringMap(); + this.objectSetupAssign(assigned,["rate"],[false]); + this.value = this.getAuto(); + var _g = 0; + while(_g < o.length) { + var field = o[_g]; + ++_g; + if(field.name == "rate") { + this.value.rate = this.loadObjectField(($_=new JsonParser_$49(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"rate",assigned,this.value.rate,pos); + } else { + this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); + } + } + this.objectErrors(assigned,pos); + } + ,getAuto: function() { + return { rate : new JsonParser_$49([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + } + ,__class__: JsonParser_$34 +}); +var JsonParser_$36 = function(errors,putils,errorType) { + if(errorType == null) { + errorType = 0; + } + json2object_reader_BaseParser.call(this,errors,putils,errorType); +}; +JsonParser_$36.__name__ = true; +JsonParser_$36.__super__ = json2object_reader_BaseParser; +JsonParser_$36.prototype = $extend(json2object_reader_BaseParser.prototype,{ + onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"{ isOpen : Bool }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } @@ -1133,7 +1181,7 @@ JsonParser_$34.prototype = $extend(json2object_reader_BaseParser.prototype,{ var field = o[_g]; ++_g; if(field.name == "isOpen") { - this.value.isOpen = this.loadObjectField(($_=new JsonParser_$46(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isOpen",assigned,this.value.isOpen,pos); + this.value.isOpen = this.loadObjectField(($_=new JsonParser_$48(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isOpen",assigned,this.value.isOpen,pos); } else { this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); } @@ -1141,19 +1189,19 @@ JsonParser_$34.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { isOpen : new JsonParser_$46([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { isOpen : new JsonParser_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,__class__: JsonParser_$34 + ,__class__: JsonParser_$36 }); -var JsonParser_$35 = function(errors,putils,errorType) { +var JsonParser_$37 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$35.__name__ = true; -JsonParser_$35.__super__ = json2object_reader_BaseParser; -JsonParser_$35.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$37.__name__ = true; +JsonParser_$37.__super__ = json2object_reader_BaseParser; +JsonParser_$37.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.value = "Connected"; this.errors.push(json2object_Error.IncorrectType(variable,"WsEventType",pos)); @@ -1163,19 +1211,19 @@ JsonParser_$35.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","KickClient","AddVideo","RemoveVideo","SkipVideo","VideoLoaded","Pause","Play","GetTime","SetTime","SetRate","Rewind","Flashback","SetLeader","PlayItem","SetNextItem","ToggleItemType","ClearChat","ClearPlaylist","ShufflePlaylist","UpdatePlaylist","TogglePlaylistLock","Dump"],"Connected"); + this.value = this.loadString(s,pos,variable,["Connected","Disconnected","Login","PasswordRequest","LoginError","Logout","Message","ServerMessage","Progress","UpdateClients","BanClient","KickClient","AddVideo","RemoveVideo","SkipVideo","VideoLoaded","Pause","Play","GetTime","SetTime","SetRate","Rewind","Flashback","SetLeader","PlayItem","SetNextItem","ToggleItemType","ClearChat","ClearPlaylist","ShufflePlaylist","UpdatePlaylist","TogglePlaylistLock","Dump"],"Connected"); } - ,__class__: JsonParser_$35 + ,__class__: JsonParser_$37 }); -var JsonParser_$37 = function(errors,putils,errorType) { +var JsonParser_$39 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$37.__name__ = true; -JsonParser_$37.__super__ = json2object_reader_BaseParser; -JsonParser_$37.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$39.__name__ = true; +JsonParser_$39.__super__ = json2object_reader_BaseParser; +JsonParser_$39.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"{ clients : Array<ClientData> }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1192,7 +1240,7 @@ JsonParser_$37.prototype = $extend(json2object_reader_BaseParser.prototype,{ var field = o[_g]; ++_g; if(field.name == "clients") { - this.value.clients = this.loadObjectField(($_=new JsonParser_$51(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clients",assigned,this.value.clients,pos); + this.value.clients = this.loadObjectField(($_=new JsonParser_$53(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clients",assigned,this.value.clients,pos); } else { this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); } @@ -1200,19 +1248,19 @@ JsonParser_$37.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { clients : new JsonParser_$51([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { clients : new JsonParser_$53([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,__class__: JsonParser_$37 + ,__class__: JsonParser_$39 }); -var JsonParser_$39 = function(errors,putils,errorType) { +var JsonParser_$41 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$39.__name__ = true; -JsonParser_$39.__super__ = json2object_reader_BaseParser; -JsonParser_$39.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$41.__name__ = true; +JsonParser_$41.__super__ = json2object_reader_BaseParser; +JsonParser_$41.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"{ videoList : Array<VideoItem> }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1229,7 +1277,7 @@ JsonParser_$39.prototype = $extend(json2object_reader_BaseParser.prototype,{ var field = o[_g]; ++_g; if(field.name == "videoList") { - this.value.videoList = this.loadObjectField(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"videoList",assigned,this.value.videoList,pos); + this.value.videoList = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"videoList",assigned,this.value.videoList,pos); } else { this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); } @@ -1237,19 +1285,19 @@ JsonParser_$39.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { videoList : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { videoList : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,__class__: JsonParser_$39 + ,__class__: JsonParser_$41 }); -var JsonParser_$42 = function(errors,putils,errorType) { +var JsonParser_$44 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$42.__name__ = true; -JsonParser_$42.__super__ = json2object_reader_BaseParser; -JsonParser_$42.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$44.__name__ = true; +JsonParser_$44.__super__ = json2object_reader_BaseParser; +JsonParser_$44.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"Array<VideoItem>",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1258,19 +1306,19 @@ JsonParser_$42.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.value = null; } ,loadJsonArray: function(a,pos,variable) { - this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$44(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); + this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$46(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); } - ,__class__: JsonParser_$42 + ,__class__: JsonParser_$44 }); -var JsonParser_$44 = function(errors,putils,errorType) { +var JsonParser_$46 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$44.__name__ = true; -JsonParser_$44.__super__ = json2object_reader_BaseParser; -JsonParser_$44.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$46.__name__ = true; +JsonParser_$46.__super__ = json2object_reader_BaseParser; +JsonParser_$46.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"{ ?voiceOverTrack : Null<String>, url : String, title : String, ?subs : Null<String>, playerType : PlayerType, isTemp : Bool, duration : Float, doCache : Bool, author : String }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1288,31 +1336,31 @@ JsonParser_$44.prototype = $extend(json2object_reader_BaseParser.prototype,{ ++_g; switch(field.name) { case "author": - this.value.author = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"author",assigned,this.value.author,pos); + this.value.author = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"author",assigned,this.value.author,pos); break; case "doCache": - this.value.doCache = this.loadObjectField(($_=new JsonParser_$46(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"doCache",assigned,this.value.doCache,pos); + this.value.doCache = this.loadObjectField(($_=new JsonParser_$48(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"doCache",assigned,this.value.doCache,pos); break; case "duration": - this.value.duration = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"duration",assigned,this.value.duration,pos); + this.value.duration = this.loadObjectField(($_=new JsonParser_$49(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"duration",assigned,this.value.duration,pos); break; case "isTemp": - this.value.isTemp = this.loadObjectField(($_=new JsonParser_$46(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isTemp",assigned,this.value.isTemp,pos); + this.value.isTemp = this.loadObjectField(($_=new JsonParser_$48(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isTemp",assigned,this.value.isTemp,pos); break; case "playerType": - this.value.playerType = this.loadObjectField(($_=new JsonParser_$48(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"playerType",assigned,this.value.playerType,pos); + this.value.playerType = this.loadObjectField(($_=new JsonParser_$50(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"playerType",assigned,this.value.playerType,pos); break; case "subs": - this.value.subs = this.loadObjectField(($_=new JsonParser_$50(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"subs",assigned,this.value.subs,pos); + this.value.subs = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"subs",assigned,this.value.subs,pos); break; case "title": - this.value.title = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"title",assigned,this.value.title,pos); + this.value.title = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"title",assigned,this.value.title,pos); break; case "url": - this.loadObjectFieldReflect(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"url",assigned,pos); + this.loadObjectFieldReflect(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"url",assigned,pos); break; case "voiceOverTrack": - this.value.voiceOverTrack = this.loadObjectField(($_=new JsonParser_$50(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"voiceOverTrack",assigned,this.value.voiceOverTrack,pos); + this.value.voiceOverTrack = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"voiceOverTrack",assigned,this.value.voiceOverTrack,pos); break; default: this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); @@ -1321,19 +1369,19 @@ JsonParser_$44.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { author : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), doCache : new JsonParser_$46([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), duration : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isTemp : new JsonParser_$46([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), playerType : new JsonParser_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), subs : new JsonParser_$50([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), title : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), url : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), voiceOverTrack : new JsonParser_$50([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { author : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), doCache : new JsonParser_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), duration : new JsonParser_$49([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isTemp : new JsonParser_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), playerType : new JsonParser_$50([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), subs : new JsonParser_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), title : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), url : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), voiceOverTrack : new JsonParser_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,__class__: JsonParser_$44 + ,__class__: JsonParser_$46 }); -var JsonParser_$45 = function(errors,putils,errorType) { +var JsonParser_$47 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$45.__name__ = true; -JsonParser_$45.__super__ = json2object_reader_BaseParser; -JsonParser_$45.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$47.__name__ = true; +JsonParser_$47.__super__ = json2object_reader_BaseParser; +JsonParser_$47.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"String",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1344,18 +1392,18 @@ JsonParser_$45.prototype = $extend(json2object_reader_BaseParser.prototype,{ ,loadJsonString: function(s,pos,variable) { this.value = s; } - ,__class__: JsonParser_$45 + ,__class__: JsonParser_$47 }); -var JsonParser_$46 = function(errors,putils,errorType) { +var JsonParser_$48 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); this.value = false; }; -JsonParser_$46.__name__ = true; -JsonParser_$46.__super__ = json2object_reader_BaseParser; -JsonParser_$46.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$48.__name__ = true; +JsonParser_$48.__super__ = json2object_reader_BaseParser; +JsonParser_$48.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"Bool",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1363,18 +1411,18 @@ JsonParser_$46.prototype = $extend(json2object_reader_BaseParser.prototype,{ ,loadJsonBool: function(b,pos,variable) { this.value = b; } - ,__class__: JsonParser_$46 + ,__class__: JsonParser_$48 }); -var JsonParser_$47 = function(errors,putils,errorType) { +var JsonParser_$49 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); this.value = 0; }; -JsonParser_$47.__name__ = true; -JsonParser_$47.__super__ = json2object_reader_BaseParser; -JsonParser_$47.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$49.__name__ = true; +JsonParser_$49.__super__ = json2object_reader_BaseParser; +JsonParser_$49.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"Float",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1382,29 +1430,7 @@ JsonParser_$47.prototype = $extend(json2object_reader_BaseParser.prototype,{ ,loadJsonNumber: function(f,pos,variable) { this.value = this.loadJsonFloat(f,pos,variable,this.value); } - ,__class__: JsonParser_$47 -}); -var JsonParser_$48 = function(errors,putils,errorType) { - if(errorType == null) { - errorType = 0; - } - json2object_reader_BaseParser.call(this,errors,putils,errorType); -}; -JsonParser_$48.__name__ = true; -JsonParser_$48.__super__ = json2object_reader_BaseParser; -JsonParser_$48.prototype = $extend(json2object_reader_BaseParser.prototype,{ - onIncorrectType: function(pos,variable) { - this.value = "RawType"; - this.errors.push(json2object_Error.IncorrectType(variable,"PlayerType",pos)); - this.objectThrow(pos,variable); - } - ,loadJsonNull: function(pos,variable) { - this.value = null; - } - ,loadJsonString: function(s,pos,variable) { - this.value = this.loadString(s,pos,variable,["RawType","YoutubeType","VkType","IframeType"],"RawType"); - } - ,__class__: JsonParser_$48 + ,__class__: JsonParser_$49 }); var JsonParser_$5 = function(errors,putils,errorType) { if(errorType == null) { @@ -1432,10 +1458,10 @@ JsonParser_$5.prototype = $extend(json2object_reader_BaseParser.prototype,{ ++_g; switch(field.name) { case "name": - this.value.name = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"name",assigned,this.value.name,pos); + this.value.name = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"name",assigned,this.value.name,pos); break; case "time": - this.value.time = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"time",assigned,this.value.time,pos); + this.value.time = this.loadObjectField(($_=new JsonParser_$49(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"time",assigned,this.value.time,pos); break; default: this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); @@ -1444,7 +1470,7 @@ JsonParser_$5.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { name : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), time : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { name : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), time : new JsonParser_$49([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$5 }); @@ -1458,37 +1484,38 @@ JsonParser_$50.__name__ = true; JsonParser_$50.__super__ = json2object_reader_BaseParser; JsonParser_$50.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { - this.errors.push(json2object_Error.IncorrectType(variable,"String",pos)); - json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); + this.value = "RawType"; + this.errors.push(json2object_Error.IncorrectType(variable,"PlayerType",pos)); + this.objectThrow(pos,variable); } ,loadJsonNull: function(pos,variable) { this.value = null; } ,loadJsonString: function(s,pos,variable) { - this.value = s; + this.value = this.loadString(s,pos,variable,["RawType","YoutubeType","VkType","IframeType"],"RawType"); } ,__class__: JsonParser_$50 }); -var JsonParser_$51 = function(errors,putils,errorType) { +var JsonParser_$52 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$51.__name__ = true; -JsonParser_$51.__super__ = json2object_reader_BaseParser; -JsonParser_$51.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$52.__name__ = true; +JsonParser_$52.__super__ = json2object_reader_BaseParser; +JsonParser_$52.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { - this.errors.push(json2object_Error.IncorrectType(variable,"Array<ClientData>",pos)); + this.errors.push(json2object_Error.IncorrectType(variable,"String",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } ,loadJsonNull: function(pos,variable) { this.value = null; } - ,loadJsonArray: function(a,pos,variable) { - this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$53(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); + ,loadJsonString: function(s,pos,variable) { + this.value = s; } - ,__class__: JsonParser_$51 + ,__class__: JsonParser_$52 }); var JsonParser_$53 = function(errors,putils,errorType) { if(errorType == null) { @@ -1500,6 +1527,27 @@ JsonParser_$53.__name__ = true; JsonParser_$53.__super__ = json2object_reader_BaseParser; JsonParser_$53.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { + this.errors.push(json2object_Error.IncorrectType(variable,"Array<ClientData>",pos)); + json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); + } + ,loadJsonNull: function(pos,variable) { + this.value = null; + } + ,loadJsonArray: function(a,pos,variable) { + this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$55(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); + } + ,__class__: JsonParser_$53 +}); +var JsonParser_$55 = function(errors,putils,errorType) { + if(errorType == null) { + errorType = 0; + } + json2object_reader_BaseParser.call(this,errors,putils,errorType); +}; +JsonParser_$55.__name__ = true; +JsonParser_$55.__super__ = json2object_reader_BaseParser; +JsonParser_$55.prototype = $extend(json2object_reader_BaseParser.prototype,{ + onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"{ name : String, group : Int }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } @@ -1516,10 +1564,10 @@ JsonParser_$53.prototype = $extend(json2object_reader_BaseParser.prototype,{ ++_g; switch(field.name) { case "group": - this.value.group = this.loadObjectField(($_=new JsonParser_$54(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"group",assigned,this.value.group,pos); + this.value.group = this.loadObjectField(($_=new JsonParser_$56(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"group",assigned,this.value.group,pos); break; case "name": - this.value.name = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"name",assigned,this.value.name,pos); + this.value.name = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"name",assigned,this.value.name,pos); break; default: this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); @@ -1528,20 +1576,20 @@ JsonParser_$53.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { group : new JsonParser_$54([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), name : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { group : new JsonParser_$56([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), name : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,__class__: JsonParser_$53 + ,__class__: JsonParser_$55 }); -var JsonParser_$54 = function(errors,putils,errorType) { +var JsonParser_$56 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); this.value = 0; }; -JsonParser_$54.__name__ = true; -JsonParser_$54.__super__ = json2object_reader_BaseParser; -JsonParser_$54.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$56.__name__ = true; +JsonParser_$56.__super__ = json2object_reader_BaseParser; +JsonParser_$56.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"Int",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1549,17 +1597,39 @@ JsonParser_$54.prototype = $extend(json2object_reader_BaseParser.prototype,{ ,loadJsonNumber: function(f,pos,variable) { this.value = this.loadJsonInt(f,pos,variable,this.value); } - ,__class__: JsonParser_$54 + ,__class__: JsonParser_$56 }); -var JsonParser_$56 = function(errors,putils,errorType) { +var JsonParser_$57 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$56.__name__ = true; -JsonParser_$56.__super__ = json2object_reader_BaseParser; -JsonParser_$56.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$57.__name__ = true; +JsonParser_$57.__super__ = json2object_reader_BaseParser; +JsonParser_$57.prototype = $extend(json2object_reader_BaseParser.prototype,{ + onIncorrectType: function(pos,variable) { + this.value = "Caching"; + this.errors.push(json2object_Error.IncorrectType(variable,"ProgressType",pos)); + this.objectThrow(pos,variable); + } + ,loadJsonNull: function(pos,variable) { + this.value = null; + } + ,loadJsonString: function(s,pos,variable) { + this.value = this.loadString(s,pos,variable,["Caching","Downloading","Uploading"],"Caching"); + } + ,__class__: JsonParser_$57 +}); +var JsonParser_$59 = function(errors,putils,errorType) { + if(errorType == null) { + errorType = 0; + } + json2object_reader_BaseParser.call(this,errors,putils,errorType); +}; +JsonParser_$59.__name__ = true; +JsonParser_$59.__super__ = json2object_reader_BaseParser; +JsonParser_$59.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"Array<ClientData>",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1568,19 +1638,19 @@ JsonParser_$56.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.value = null; } ,loadJsonArray: function(a,pos,variable) { - this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$53(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); + this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$55(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); } - ,__class__: JsonParser_$56 + ,__class__: JsonParser_$59 }); -var JsonParser_$58 = function(errors,putils,errorType) { +var JsonParser_$61 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$58.__name__ = true; -JsonParser_$58.__super__ = json2object_reader_BaseParser; -JsonParser_$58.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$61.__name__ = true; +JsonParser_$61.__super__ = json2object_reader_BaseParser; +JsonParser_$61.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"Bool",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1591,17 +1661,17 @@ JsonParser_$58.prototype = $extend(json2object_reader_BaseParser.prototype,{ ,loadJsonBool: function(b,pos,variable) { this.value = b; } - ,__class__: JsonParser_$58 + ,__class__: JsonParser_$61 }); -var JsonParser_$60 = function(errors,putils,errorType) { +var JsonParser_$63 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$60.__name__ = true; -JsonParser_$60.__super__ = json2object_reader_BaseParser; -JsonParser_$60.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$63.__name__ = true; +JsonParser_$63.__super__ = json2object_reader_BaseParser; +JsonParser_$63.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"Float",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1612,17 +1682,17 @@ JsonParser_$60.prototype = $extend(json2object_reader_BaseParser.prototype,{ ,loadJsonNumber: function(f,pos,variable) { this.value = this.loadJsonFloat(f,pos,variable,this.value); } - ,__class__: JsonParser_$60 + ,__class__: JsonParser_$63 }); -var JsonParser_$62 = function(errors,putils,errorType) { +var JsonParser_$65 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$62.__name__ = true; -JsonParser_$62.__super__ = json2object_reader_BaseParser; -JsonParser_$62.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$65.__name__ = true; +JsonParser_$65.__super__ = json2object_reader_BaseParser; +JsonParser_$65.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"{ youtubePlaylistLimit : Int, youtubeApiKey : String, userVideoLimit : Int, unpauseWithoutLeader : Bool, totalVideoLimit : Int, templateUrl : String, serverChatHistory : Int, ?salt : Null<String>, requestLeaderOnPause : Bool, port : Int, permissions : Permissions, maxMessageLength : Int, maxLoginLength : Int, localNetworkOnly : Bool, localAdmins : Bool, ?isVerbose : Null<Bool>, filters : Array<Filter>, emotes : Array<Emote>, channelName : String, cacheStorageLimitGiB : Float, allowProxyIps : Bool }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1640,67 +1710,67 @@ JsonParser_$62.prototype = $extend(json2object_reader_BaseParser.prototype,{ ++_g; switch(field.name) { case "allowProxyIps": - this.value.allowProxyIps = this.loadObjectField(($_=new JsonParser_$46(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"allowProxyIps",assigned,this.value.allowProxyIps,pos); + this.value.allowProxyIps = this.loadObjectField(($_=new JsonParser_$48(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"allowProxyIps",assigned,this.value.allowProxyIps,pos); break; case "cacheStorageLimitGiB": - this.value.cacheStorageLimitGiB = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"cacheStorageLimitGiB",assigned,this.value.cacheStorageLimitGiB,pos); + this.value.cacheStorageLimitGiB = this.loadObjectField(($_=new JsonParser_$49(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"cacheStorageLimitGiB",assigned,this.value.cacheStorageLimitGiB,pos); break; case "channelName": - this.value.channelName = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"channelName",assigned,this.value.channelName,pos); + this.value.channelName = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"channelName",assigned,this.value.channelName,pos); break; case "emotes": - this.value.emotes = this.loadObjectField(($_=new JsonParser_$67(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"emotes",assigned,this.value.emotes,pos); + this.value.emotes = this.loadObjectField(($_=new JsonParser_$70(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"emotes",assigned,this.value.emotes,pos); break; case "filters": - this.value.filters = this.loadObjectField(($_=new JsonParser_$68(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"filters",assigned,this.value.filters,pos); + this.value.filters = this.loadObjectField(($_=new JsonParser_$71(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"filters",assigned,this.value.filters,pos); break; case "isVerbose": - this.value.isVerbose = this.loadObjectField(($_=new JsonParser_$58(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isVerbose",assigned,this.value.isVerbose,pos); + this.value.isVerbose = this.loadObjectField(($_=new JsonParser_$61(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isVerbose",assigned,this.value.isVerbose,pos); break; case "localAdmins": - this.value.localAdmins = this.loadObjectField(($_=new JsonParser_$46(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"localAdmins",assigned,this.value.localAdmins,pos); + this.value.localAdmins = this.loadObjectField(($_=new JsonParser_$48(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"localAdmins",assigned,this.value.localAdmins,pos); break; case "localNetworkOnly": - this.value.localNetworkOnly = this.loadObjectField(($_=new JsonParser_$46(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"localNetworkOnly",assigned,this.value.localNetworkOnly,pos); + this.value.localNetworkOnly = this.loadObjectField(($_=new JsonParser_$48(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"localNetworkOnly",assigned,this.value.localNetworkOnly,pos); break; case "maxLoginLength": - this.value.maxLoginLength = this.loadObjectField(($_=new JsonParser_$54(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"maxLoginLength",assigned,this.value.maxLoginLength,pos); + this.value.maxLoginLength = this.loadObjectField(($_=new JsonParser_$56(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"maxLoginLength",assigned,this.value.maxLoginLength,pos); break; case "maxMessageLength": - this.value.maxMessageLength = this.loadObjectField(($_=new JsonParser_$54(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"maxMessageLength",assigned,this.value.maxMessageLength,pos); + this.value.maxMessageLength = this.loadObjectField(($_=new JsonParser_$56(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"maxMessageLength",assigned,this.value.maxMessageLength,pos); break; case "permissions": - this.value.permissions = this.loadObjectField(($_=new JsonParser_$70(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"permissions",assigned,this.value.permissions,pos); + this.value.permissions = this.loadObjectField(($_=new JsonParser_$73(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"permissions",assigned,this.value.permissions,pos); break; case "port": - this.value.port = this.loadObjectField(($_=new JsonParser_$54(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"port",assigned,this.value.port,pos); + this.value.port = this.loadObjectField(($_=new JsonParser_$56(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"port",assigned,this.value.port,pos); break; case "requestLeaderOnPause": - this.value.requestLeaderOnPause = this.loadObjectField(($_=new JsonParser_$46(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"requestLeaderOnPause",assigned,this.value.requestLeaderOnPause,pos); + this.value.requestLeaderOnPause = this.loadObjectField(($_=new JsonParser_$48(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"requestLeaderOnPause",assigned,this.value.requestLeaderOnPause,pos); break; case "salt": - this.value.salt = this.loadObjectField(($_=new JsonParser_$50(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"salt",assigned,this.value.salt,pos); + this.value.salt = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"salt",assigned,this.value.salt,pos); break; case "serverChatHistory": - this.value.serverChatHistory = this.loadObjectField(($_=new JsonParser_$54(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"serverChatHistory",assigned,this.value.serverChatHistory,pos); + this.value.serverChatHistory = this.loadObjectField(($_=new JsonParser_$56(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"serverChatHistory",assigned,this.value.serverChatHistory,pos); break; case "templateUrl": - this.value.templateUrl = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"templateUrl",assigned,this.value.templateUrl,pos); + this.value.templateUrl = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"templateUrl",assigned,this.value.templateUrl,pos); break; case "totalVideoLimit": - this.value.totalVideoLimit = this.loadObjectField(($_=new JsonParser_$54(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"totalVideoLimit",assigned,this.value.totalVideoLimit,pos); + this.value.totalVideoLimit = this.loadObjectField(($_=new JsonParser_$56(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"totalVideoLimit",assigned,this.value.totalVideoLimit,pos); break; case "unpauseWithoutLeader": - this.value.unpauseWithoutLeader = this.loadObjectField(($_=new JsonParser_$46(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"unpauseWithoutLeader",assigned,this.value.unpauseWithoutLeader,pos); + this.value.unpauseWithoutLeader = this.loadObjectField(($_=new JsonParser_$48(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"unpauseWithoutLeader",assigned,this.value.unpauseWithoutLeader,pos); break; case "userVideoLimit": - this.value.userVideoLimit = this.loadObjectField(($_=new JsonParser_$54(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"userVideoLimit",assigned,this.value.userVideoLimit,pos); + this.value.userVideoLimit = this.loadObjectField(($_=new JsonParser_$56(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"userVideoLimit",assigned,this.value.userVideoLimit,pos); break; case "youtubeApiKey": - this.value.youtubeApiKey = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"youtubeApiKey",assigned,this.value.youtubeApiKey,pos); + this.value.youtubeApiKey = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"youtubeApiKey",assigned,this.value.youtubeApiKey,pos); break; case "youtubePlaylistLimit": - this.value.youtubePlaylistLimit = this.loadObjectField(($_=new JsonParser_$54(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"youtubePlaylistLimit",assigned,this.value.youtubePlaylistLimit,pos); + this.value.youtubePlaylistLimit = this.loadObjectField(($_=new JsonParser_$56(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"youtubePlaylistLimit",assigned,this.value.youtubePlaylistLimit,pos); break; default: this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); @@ -1709,19 +1779,19 @@ JsonParser_$62.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { allowProxyIps : new JsonParser_$46([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), cacheStorageLimitGiB : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), channelName : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), emotes : new JsonParser_$67([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), filters : new JsonParser_$68([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isVerbose : new JsonParser_$58([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), localAdmins : new JsonParser_$46([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), localNetworkOnly : new JsonParser_$46([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), maxLoginLength : new JsonParser_$54([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), maxMessageLength : new JsonParser_$54([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), permissions : new JsonParser_$70([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), port : new JsonParser_$54([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), requestLeaderOnPause : new JsonParser_$46([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), salt : new JsonParser_$50([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), serverChatHistory : new JsonParser_$54([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), templateUrl : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), totalVideoLimit : new JsonParser_$54([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), unpauseWithoutLeader : new JsonParser_$46([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), userVideoLimit : new JsonParser_$54([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), youtubeApiKey : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), youtubePlaylistLimit : new JsonParser_$54([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { allowProxyIps : new JsonParser_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), cacheStorageLimitGiB : new JsonParser_$49([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), channelName : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), emotes : new JsonParser_$70([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), filters : new JsonParser_$71([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isVerbose : new JsonParser_$61([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), localAdmins : new JsonParser_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), localNetworkOnly : new JsonParser_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), maxLoginLength : new JsonParser_$56([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), maxMessageLength : new JsonParser_$56([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), permissions : new JsonParser_$73([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), port : new JsonParser_$56([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), requestLeaderOnPause : new JsonParser_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), salt : new JsonParser_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), serverChatHistory : new JsonParser_$56([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), templateUrl : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), totalVideoLimit : new JsonParser_$56([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), unpauseWithoutLeader : new JsonParser_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), userVideoLimit : new JsonParser_$56([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), youtubeApiKey : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), youtubePlaylistLimit : new JsonParser_$56([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,__class__: JsonParser_$62 + ,__class__: JsonParser_$65 }); -var JsonParser_$63 = function(errors,putils,errorType) { +var JsonParser_$66 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$63.__name__ = true; -JsonParser_$63.__super__ = json2object_reader_BaseParser; -JsonParser_$63.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$66.__name__ = true; +JsonParser_$66.__super__ = json2object_reader_BaseParser; +JsonParser_$66.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"Array<Message>",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1730,19 +1800,19 @@ JsonParser_$63.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.value = null; } ,loadJsonArray: function(a,pos,variable) { - this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$66(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); + this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$69(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); } - ,__class__: JsonParser_$63 + ,__class__: JsonParser_$66 }); -var JsonParser_$64 = function(errors,putils,errorType) { +var JsonParser_$67 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$64.__name__ = true; -JsonParser_$64.__super__ = json2object_reader_BaseParser; -JsonParser_$64.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$67.__name__ = true; +JsonParser_$67.__super__ = json2object_reader_BaseParser; +JsonParser_$67.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"Array<PlayerType>",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1751,19 +1821,19 @@ JsonParser_$64.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.value = null; } ,loadJsonArray: function(a,pos,variable) { - this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$48(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); + this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$50(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); } - ,__class__: JsonParser_$64 + ,__class__: JsonParser_$67 }); -var JsonParser_$66 = function(errors,putils,errorType) { +var JsonParser_$69 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$66.__name__ = true; -JsonParser_$66.__super__ = json2object_reader_BaseParser; -JsonParser_$66.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$69.__name__ = true; +JsonParser_$69.__super__ = json2object_reader_BaseParser; +JsonParser_$69.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"{ time : String, text : String, name : String }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1781,13 +1851,13 @@ JsonParser_$66.prototype = $extend(json2object_reader_BaseParser.prototype,{ ++_g; switch(field.name) { case "name": - this.value.name = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"name",assigned,this.value.name,pos); + this.value.name = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"name",assigned,this.value.name,pos); break; case "text": - this.value.text = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"text",assigned,this.value.text,pos); + this.value.text = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"text",assigned,this.value.text,pos); break; case "time": - this.value.time = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"time",assigned,this.value.time,pos); + this.value.time = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"time",assigned,this.value.time,pos); break; default: this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); @@ -1796,51 +1866,9 @@ JsonParser_$66.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { name : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), text : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), time : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; - } - ,__class__: JsonParser_$66 -}); -var JsonParser_$67 = function(errors,putils,errorType) { - if(errorType == null) { - errorType = 0; - } - json2object_reader_BaseParser.call(this,errors,putils,errorType); -}; -JsonParser_$67.__name__ = true; -JsonParser_$67.__super__ = json2object_reader_BaseParser; -JsonParser_$67.prototype = $extend(json2object_reader_BaseParser.prototype,{ - onIncorrectType: function(pos,variable) { - this.errors.push(json2object_Error.IncorrectType(variable,"Array<Emote>",pos)); - json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); - } - ,loadJsonNull: function(pos,variable) { - this.value = null; - } - ,loadJsonArray: function(a,pos,variable) { - this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$76(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); - } - ,__class__: JsonParser_$67 -}); -var JsonParser_$68 = function(errors,putils,errorType) { - if(errorType == null) { - errorType = 0; - } - json2object_reader_BaseParser.call(this,errors,putils,errorType); -}; -JsonParser_$68.__name__ = true; -JsonParser_$68.__super__ = json2object_reader_BaseParser; -JsonParser_$68.prototype = $extend(json2object_reader_BaseParser.prototype,{ - onIncorrectType: function(pos,variable) { - this.errors.push(json2object_Error.IncorrectType(variable,"Array<Filter>",pos)); - json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); - } - ,loadJsonNull: function(pos,variable) { - this.value = null; - } - ,loadJsonArray: function(a,pos,variable) { - this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$74(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); + return { name : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), text : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), time : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,__class__: JsonParser_$68 + ,__class__: JsonParser_$69 }); var JsonParser_$7 = function(errors,putils,errorType) { if(errorType == null) { @@ -1868,37 +1896,37 @@ JsonParser_$7.prototype = $extend(json2object_reader_BaseParser.prototype,{ ++_g; switch(field.name) { case "clientName": - this.value.clientName = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clientName",assigned,this.value.clientName,pos); + this.value.clientName = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clientName",assigned,this.value.clientName,pos); break; case "clients": - this.value.clients = this.loadObjectField(($_=new JsonParser_$51(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clients",assigned,this.value.clients,pos); + this.value.clients = this.loadObjectField(($_=new JsonParser_$53(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clients",assigned,this.value.clients,pos); break; case "config": - this.value.config = this.loadObjectField(($_=new JsonParser_$62(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"config",assigned,this.value.config,pos); + this.value.config = this.loadObjectField(($_=new JsonParser_$65(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"config",assigned,this.value.config,pos); break; case "globalIp": - this.value.globalIp = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"globalIp",assigned,this.value.globalIp,pos); + this.value.globalIp = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"globalIp",assigned,this.value.globalIp,pos); break; case "history": - this.value.history = this.loadObjectField(($_=new JsonParser_$63(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"history",assigned,this.value.history,pos); + this.value.history = this.loadObjectField(($_=new JsonParser_$66(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"history",assigned,this.value.history,pos); break; case "isPlaylistOpen": - this.value.isPlaylistOpen = this.loadObjectField(($_=new JsonParser_$46(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isPlaylistOpen",assigned,this.value.isPlaylistOpen,pos); + this.value.isPlaylistOpen = this.loadObjectField(($_=new JsonParser_$48(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isPlaylistOpen",assigned,this.value.isPlaylistOpen,pos); break; case "isUnknownClient": - this.value.isUnknownClient = this.loadObjectField(($_=new JsonParser_$46(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isUnknownClient",assigned,this.value.isUnknownClient,pos); + this.value.isUnknownClient = this.loadObjectField(($_=new JsonParser_$48(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isUnknownClient",assigned,this.value.isUnknownClient,pos); break; case "itemPos": - this.value.itemPos = this.loadObjectField(($_=new JsonParser_$54(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"itemPos",assigned,this.value.itemPos,pos); + this.value.itemPos = this.loadObjectField(($_=new JsonParser_$56(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"itemPos",assigned,this.value.itemPos,pos); break; case "playersCacheSupport": - this.value.playersCacheSupport = this.loadObjectField(($_=new JsonParser_$64(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"playersCacheSupport",assigned,this.value.playersCacheSupport,pos); + this.value.playersCacheSupport = this.loadObjectField(($_=new JsonParser_$67(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"playersCacheSupport",assigned,this.value.playersCacheSupport,pos); break; case "uuid": - this.value.uuid = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"uuid",assigned,this.value.uuid,pos); + this.value.uuid = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"uuid",assigned,this.value.uuid,pos); break; case "videoList": - this.value.videoList = this.loadObjectField(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"videoList",assigned,this.value.videoList,pos); + this.value.videoList = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"videoList",assigned,this.value.videoList,pos); break; default: this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); @@ -1907,7 +1935,7 @@ JsonParser_$7.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { clientName : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), clients : new JsonParser_$51([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), config : new JsonParser_$62([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), globalIp : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), history : new JsonParser_$63([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isPlaylistOpen : new JsonParser_$46([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isUnknownClient : new JsonParser_$46([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), itemPos : new JsonParser_$54([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), playersCacheSupport : new JsonParser_$64([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), uuid : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), videoList : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { clientName : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), clients : new JsonParser_$53([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), config : new JsonParser_$65([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), globalIp : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), history : new JsonParser_$66([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isPlaylistOpen : new JsonParser_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isUnknownClient : new JsonParser_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), itemPos : new JsonParser_$56([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), playersCacheSupport : new JsonParser_$67([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), uuid : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), videoList : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$7 }); @@ -1921,6 +1949,48 @@ JsonParser_$70.__name__ = true; JsonParser_$70.__super__ = json2object_reader_BaseParser; JsonParser_$70.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { + this.errors.push(json2object_Error.IncorrectType(variable,"Array<Emote>",pos)); + json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); + } + ,loadJsonNull: function(pos,variable) { + this.value = null; + } + ,loadJsonArray: function(a,pos,variable) { + this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$79(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); + } + ,__class__: JsonParser_$70 +}); +var JsonParser_$71 = function(errors,putils,errorType) { + if(errorType == null) { + errorType = 0; + } + json2object_reader_BaseParser.call(this,errors,putils,errorType); +}; +JsonParser_$71.__name__ = true; +JsonParser_$71.__super__ = json2object_reader_BaseParser; +JsonParser_$71.prototype = $extend(json2object_reader_BaseParser.prototype,{ + onIncorrectType: function(pos,variable) { + this.errors.push(json2object_Error.IncorrectType(variable,"Array<Filter>",pos)); + json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); + } + ,loadJsonNull: function(pos,variable) { + this.value = null; + } + ,loadJsonArray: function(a,pos,variable) { + this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$77(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); + } + ,__class__: JsonParser_$71 +}); +var JsonParser_$73 = function(errors,putils,errorType) { + if(errorType == null) { + errorType = 0; + } + json2object_reader_BaseParser.call(this,errors,putils,errorType); +}; +JsonParser_$73.__name__ = true; +JsonParser_$73.__super__ = json2object_reader_BaseParser; +JsonParser_$73.prototype = $extend(json2object_reader_BaseParser.prototype,{ + onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"{ user : Array<Permission>, leader : Array<Permission>, guest : Array<Permission>, banned : Array<Permission>, admin : Array<Permission> }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } @@ -1937,19 +2007,19 @@ JsonParser_$70.prototype = $extend(json2object_reader_BaseParser.prototype,{ ++_g; switch(field.name) { case "admin": - this.value.admin = this.loadObjectField(($_=new JsonParser_$71(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"admin",assigned,this.value.admin,pos); + this.value.admin = this.loadObjectField(($_=new JsonParser_$74(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"admin",assigned,this.value.admin,pos); break; case "banned": - this.value.banned = this.loadObjectField(($_=new JsonParser_$71(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"banned",assigned,this.value.banned,pos); + this.value.banned = this.loadObjectField(($_=new JsonParser_$74(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"banned",assigned,this.value.banned,pos); break; case "guest": - this.value.guest = this.loadObjectField(($_=new JsonParser_$71(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"guest",assigned,this.value.guest,pos); + this.value.guest = this.loadObjectField(($_=new JsonParser_$74(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"guest",assigned,this.value.guest,pos); break; case "leader": - this.value.leader = this.loadObjectField(($_=new JsonParser_$71(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"leader",assigned,this.value.leader,pos); + this.value.leader = this.loadObjectField(($_=new JsonParser_$74(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"leader",assigned,this.value.leader,pos); break; case "user": - this.value.user = this.loadObjectField(($_=new JsonParser_$71(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"user",assigned,this.value.user,pos); + this.value.user = this.loadObjectField(($_=new JsonParser_$74(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"user",assigned,this.value.user,pos); break; default: this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); @@ -1958,19 +2028,19 @@ JsonParser_$70.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { admin : new JsonParser_$71([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), banned : new JsonParser_$71([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), guest : new JsonParser_$71([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), leader : new JsonParser_$71([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), user : new JsonParser_$71([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { admin : new JsonParser_$74([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), banned : new JsonParser_$74([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), guest : new JsonParser_$74([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), leader : new JsonParser_$74([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), user : new JsonParser_$74([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,__class__: JsonParser_$70 + ,__class__: JsonParser_$73 }); -var JsonParser_$71 = function(errors,putils,errorType) { +var JsonParser_$74 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$71.__name__ = true; -JsonParser_$71.__super__ = json2object_reader_BaseParser; -JsonParser_$71.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$74.__name__ = true; +JsonParser_$74.__super__ = json2object_reader_BaseParser; +JsonParser_$74.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"Array<Permission>",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1979,19 +2049,19 @@ JsonParser_$71.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.value = null; } ,loadJsonArray: function(a,pos,variable) { - this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$72(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); + this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$75(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); } - ,__class__: JsonParser_$71 + ,__class__: JsonParser_$74 }); -var JsonParser_$72 = function(errors,putils,errorType) { +var JsonParser_$75 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$72.__name__ = true; -JsonParser_$72.__super__ = json2object_reader_BaseParser; -JsonParser_$72.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$75.__name__ = true; +JsonParser_$75.__super__ = json2object_reader_BaseParser; +JsonParser_$75.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.value = "guest"; this.errors.push(json2object_Error.IncorrectType(variable,"Permission",pos)); @@ -2003,17 +2073,17 @@ JsonParser_$72.prototype = $extend(json2object_reader_BaseParser.prototype,{ ,loadJsonString: function(s,pos,variable) { this.value = this.loadString(s,pos,variable,["guest","user","leader","admin","writeChat","addVideo","removeVideo","requestLeader","rewind","clearChat","setLeader","changeOrder","toggleItemType","lockPlaylist","banClient"],"guest"); } - ,__class__: JsonParser_$72 + ,__class__: JsonParser_$75 }); -var JsonParser_$74 = function(errors,putils,errorType) { +var JsonParser_$77 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$74.__name__ = true; -JsonParser_$74.__super__ = json2object_reader_BaseParser; -JsonParser_$74.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$77.__name__ = true; +JsonParser_$77.__super__ = json2object_reader_BaseParser; +JsonParser_$77.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"{ replace : String, regex : String, name : String, flags : String }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -2031,16 +2101,16 @@ JsonParser_$74.prototype = $extend(json2object_reader_BaseParser.prototype,{ ++_g; switch(field.name) { case "flags": - this.value.flags = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"flags",assigned,this.value.flags,pos); + this.value.flags = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"flags",assigned,this.value.flags,pos); break; case "name": - this.value.name = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"name",assigned,this.value.name,pos); + this.value.name = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"name",assigned,this.value.name,pos); break; case "regex": - this.value.regex = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"regex",assigned,this.value.regex,pos); + this.value.regex = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"regex",assigned,this.value.regex,pos); break; case "replace": - this.value.replace = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"replace",assigned,this.value.replace,pos); + this.value.replace = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"replace",assigned,this.value.replace,pos); break; default: this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); @@ -2049,19 +2119,19 @@ JsonParser_$74.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { flags : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), name : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), regex : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), replace : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { flags : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), name : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), regex : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), replace : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,__class__: JsonParser_$74 + ,__class__: JsonParser_$77 }); -var JsonParser_$76 = function(errors,putils,errorType) { +var JsonParser_$79 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$76.__name__ = true; -JsonParser_$76.__super__ = json2object_reader_BaseParser; -JsonParser_$76.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$79.__name__ = true; +JsonParser_$79.__super__ = json2object_reader_BaseParser; +JsonParser_$79.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"{ name : String, image : String }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -2079,10 +2149,10 @@ JsonParser_$76.prototype = $extend(json2object_reader_BaseParser.prototype,{ ++_g; switch(field.name) { case "image": - this.value.image = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"image",assigned,this.value.image,pos); + this.value.image = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"image",assigned,this.value.image,pos); break; case "name": - this.value.name = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"name",assigned,this.value.name,pos); + this.value.name = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"name",assigned,this.value.name,pos); break; default: this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); @@ -2091,9 +2161,9 @@ JsonParser_$76.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { image : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), name : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { image : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), name : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,__class__: JsonParser_$76 + ,__class__: JsonParser_$79 }); var JsonParser_$9 = function(errors,putils,errorType) { if(errorType == null) { @@ -2120,7 +2190,7 @@ JsonParser_$9.prototype = $extend(json2object_reader_BaseParser.prototype,{ var field = o[_g]; ++_g; if(field.name == "data") { - this.value.data = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"data",assigned,this.value.data,pos); + this.value.data = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"data",assigned,this.value.data,pos); } else { this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); } @@ -2128,7 +2198,7 @@ JsonParser_$9.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { data : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { data : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$9 }); @@ -2808,6 +2878,11 @@ haxe_io_Path.withoutExtension = function(path) { s.ext = null; return s.toString(); }; +haxe_io_Path.withoutDirectory = function(path) { + var s = new haxe_io_Path(path); + s.dir = null; + return s.toString(); +}; haxe_io_Path.extension = function(path) { var s = new haxe_io_Path(path); if(s.ext == null) { @@ -3436,6 +3511,7 @@ var js_node_Https = require("https"); var js_node_Os = require("os"); var js_node_Path = require("path"); var js_node_Readline = require("readline"); +var js_node_buffer_Buffer = require("buffer").Buffer; var js_node_url_URL = require("url").URL; var js_npm_ws_Server = require("ws").Server; var json2object_Error = $hxEnums["json2object.Error"] = { __ename__:true,__constructs__:null @@ -3601,6 +3677,7 @@ json2object_PositionUtils.prototype = { ,__class__: json2object_PositionUtils }; var server_Cache = function(main,cacheDir) { + this.freeSpaceBlock = 10485760; this.storageLimit = 3145728 * 1024; this.isYtReady = false; this.cachedFiles = []; @@ -3627,12 +3704,12 @@ server_Cache.prototype = { } ,log: function(client,msg) { this.main.serverMessage(client,msg); - haxe_Log.trace(msg,{ fileName : "src/server/Cache.hx", lineNumber : 44, className : "server.Cache", methodName : "log"}); + haxe_Log.trace(msg,{ fileName : "src/server/Cache.hx", lineNumber : 46, className : "server.Cache", methodName : "log"}); } ,cacheYoutubeVideo: function(client,url,callback) { var _gthis = this; if(!this.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.hx", lineNumber : 49, className : "server.Cache", methodName : "cacheYoutubeVideo"}); + 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.hx", lineNumber : 51, className : "server.Cache", methodName : "cacheYoutubeVideo"}); return; } var videoId = utils_YoutubeUtils.extractVideoId(url); @@ -3641,15 +3718,16 @@ server_Cache.prototype = { return; } var outName = videoId + ".mp4"; - if(this.cachedFiles.indexOf(outName) != -1 && sys_FileSystem.exists("" + this.cacheDir + "/" + outName)) { + if(this.cachedFiles.indexOf(outName) != -1 && this.isFileExists(outName)) { callback(outName); return; } var ytdl = require("@distube/ytdl-core"); - this.log(client,"Caching " + url + " to " + outName + "..."); + haxe_Log.trace("Caching " + url + " to " + outName + "...",{ fileName : "src/server/Cache.hx", lineNumber : 65, className : "server.Cache", methodName : "cacheYoutubeVideo"}); + this.main.send(client,{ type : "Progress", progress : { type : "Caching", ratio : 0, data : outName}}); var promise = ytdl.getInfo(url); promise.then(function(info) { - haxe_Log.trace("Get info with " + info.formats.length + " formats",{ fileName : "src/server/Cache.hx", lineNumber : 68, className : "server.Cache", methodName : "cacheYoutubeVideo"}); + haxe_Log.trace("Get info with " + info.formats.length + " formats",{ fileName : "src/server/Cache.hx", lineNumber : 76, className : "server.Cache", methodName : "cacheYoutubeVideo"}); var audioFormat; try { var ytdl1 = ytdl.chooseFormat; @@ -3668,8 +3746,18 @@ server_Cache.prototype = { } catch( _g ) { var e = haxe_Exception.caught(_g); _gthis.log(client,"Error: audio format not found"); - haxe_Log.trace(e,{ fileName : "src/server/Cache.hx", lineNumber : 75, className : "server.Cache", methodName : "cacheYoutubeVideo"}); - haxe_Log.trace(info.formats,{ fileName : "src/server/Cache.hx", lineNumber : 76, className : "server.Cache", methodName : "cacheYoutubeVideo"}); + haxe_Log.trace(e,{ fileName : "src/server/Cache.hx", lineNumber : 83, className : "server.Cache", 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); + } + } + haxe_Log.trace(_g1,{ fileName : "src/server/Cache.hx", lineNumber : 84, className : "server.Cache", methodName : "cacheYoutubeVideo"}); return; } var videoFormat; @@ -3678,10 +3766,19 @@ server_Cache.prototype = { videoFormat = tmp; } else { _gthis.log(client,"Error: video format not found"); - haxe_Log.trace(info.formats,{ fileName : "src/server/Cache.hx", lineNumber : 81, className : "server.Cache", methodName : "cacheYoutubeVideo"}); + var _g = []; + 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.hx", lineNumber : 89, className : "server.Cache", methodName : "cacheYoutubeVideo"}); return; } - haxe_Log.trace("Picked audio and video formats",{ fileName : "src/server/Cache.hx", lineNumber : 84, className : "server.Cache", methodName : "cacheYoutubeVideo"}); var dlVideo = ytdl(url,{ format : videoFormat}); dlVideo.pipe(js_node_Fs.createWriteStream("" + _gthis.cacheDir + "/input-video")); dlVideo.on("error",function(err) { @@ -3695,10 +3792,13 @@ server_Cache.prototype = { var count = 0; var onComplete = function(type) { count += 1; - _gthis.log(client,"" + type + " track downloaded (" + count + "/2)"); + haxe_Log.trace("" + type + " track downloaded (" + count + "/2)",{ fileName : "src/server/Cache.hx", lineNumber : 108, className : "server.Cache", methodName : "cacheYoutubeVideo"}); if(count < 2) { return; } + var size = js_node_Fs.statSync("" + _gthis.cacheDir + "/input-video").size; + size += js_node_Fs.statSync("" + _gthis.cacheDir + "/input-audio").size; + _gthis.removeOlderCache(size + _gthis.freeSpaceBlock); var args = ("-y -i input-video -i input-audio -c copy -map 0:v -map 1:a ./" + outName).split(" "); var $process = js_node_ChildProcess.spawn("ffmpeg",args,{ cwd : _gthis.cacheDir, stdio : "ignore"}); $process.on("close",function(code) { @@ -3708,16 +3808,9 @@ server_Cache.prototype = { } var inVideo = "" + _gthis.cacheDir + "/input-video"; var inAudio = "" + _gthis.cacheDir + "/input-audio"; - if(sys_FileSystem.exists(inVideo)) { - js_node_Fs.unlinkSync(inVideo); - } - if(sys_FileSystem.exists(inAudio)) { - js_node_Fs.unlinkSync(inAudio); - } - if(_gthis.cachedFiles.indexOf(outName) == -1) { - _gthis.cachedFiles.unshift(outName); - } - _gthis.removeOlderCache(); + js_node_Fs.unlinkSync(inVideo); + js_node_Fs.unlinkSync(inAudio); + _gthis.add(outName); callback(outName); }); }; @@ -3727,26 +3820,109 @@ server_Cache.prototype = { dlAudio.on("finish",function() { onComplete("Audio"); }); + var isAudioStart = true; + dlAudio.on("progress",function(chunkLength,downloaded,contentLength) { + if(isAudioStart) { + isAudioStart = false; + _gthis.removeOlderCache(contentLength); + } + }); + var isVideoStart = true; + dlVideo.on("progress",function(chunkLength,downloaded,contentLength) { + if(isVideoStart) { + isVideoStart = false; + _gthis.removeOlderCache(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}}); + }); }).catch(function(err) { _gthis.log(client,"" + err); }); } - ,removeOlderCache: function() { - while(this.getUsedSpace() > this.storageLimit) { - var name = this.cachedFiles.pop(); - var path = "" + this.cacheDir + "/" + name; + ,setStorageLimit: function(bytes) { + var _gthis = this; + this.storageLimit = bytes; + var a = this.storageLimit; + this.storageLimit = a < 0 ? 0 : a; + var tmp = js_node_Fs.statfs; + if(tmp == null) { + return; + } + tmp("/",function(err,stats) { + if(err != null) { + haxe_Log.trace(err,{ fileName : "src/server/Cache.hx", lineNumber : 173, className : "server.Cache", methodName : "setStorageLimit"}); + return; + } + var a = stats.bsize * stats.bavail - _gthis.freeSpaceBlock; + var availSpace = a < 0 ? 0 : a; + _gthis.removeOlderCache(); + var freeSpace = _gthis.getFreeSpace(); + if(availSpace < freeSpace) { + var a = _gthis.storageLimit += availSpace - freeSpace; + _gthis.storageLimit = a < 0 ? 0 : a; + _gthis.removeOlderCache(); + } + }); + } + ,add: function(name) { + if(this.cachedFiles.indexOf(name) == -1) { + this.cachedFiles.unshift(name); + } + } + ,removeOlderCache: function(addFileSize) { + if(addFileSize == null) { + addFileSize = 0; + } + var space = this.getUsedSpace(addFileSize); + while(space > this.storageLimit) { + var tmp = this.cachedFiles.pop(); + if(tmp == null) { + break; + } + var path = this.getFilePath(tmp); if(sys_FileSystem.exists(path)) { js_node_Fs.unlinkSync(path); } + space = this.getUsedSpace(addFileSize); + } + } + ,getFreeFileName: function(baseName) { + if(baseName == null) { + baseName = "video"; + } + var i = 1; + while(true) { + var name = "" + baseName + (i == 1 ? "" : "" + i) + ".mp4"; + if(!this.isFileExists(name)) { + return name; + } + ++i; } } - ,getUsedSpace: function() { - var total = 0; + ,getFilePath: function(name) { + return "" + this.cacheDir + "/" + name; + } + ,getFileUrl: function(name) { + return "/" + haxe_io_Path.withoutDirectory(this.cacheDir) + "/" + name; + } + ,isFileExists: function(name) { + return sys_FileSystem.exists(this.getFilePath(name)); + } + ,getFreeSpace: function() { + return this.storageLimit - this.getUsedSpace(); + } + ,getUsedSpace: function(addFileSize) { + if(addFileSize == null) { + addFileSize = 0; + } + var total = addFileSize < 0 ? 0 : addFileSize; var arr = this.cachedFiles; var _g_i = arr.length - 1; while(_g_i > -1) { var name = arr[_g_i--]; - var path = "" + this.cacheDir + "/" + name; + var path = this.getFilePath(name); if(!sys_FileSystem.exists(path)) { HxOverrides.remove(this.cachedFiles,name); continue; @@ -3756,7 +3932,7 @@ server_Cache.prototype = { return total; } ,getBestYoutubeVideoFormat: function(formats) { - var qPriority = [1080,720,480,360,240]; + var qPriority = [1080,720,480,360,240,144]; var _g = 0; while(_g < qPriority.length) { var quality = "" + qPriority[_g++] + "p"; @@ -3931,233 +4107,391 @@ server_ConsoleInput.prototype = { } ,__class__: server_ConsoleInput }; -var server_HttpServer = function() { }; -server_HttpServer.__name__ = true; -server_HttpServer.init = function(dir,customDir,allowLocalRequests) { - server_HttpServer.dir = dir; - if(customDir == null) { - return; +var server__$HttpServer_HttpServerConfig = function(dir,customDir,allowLocalRequests,cache) { + this.cache = null; + this.allowLocalRequests = false; + this.customDir = null; + this.dir = dir; + if(customDir != null) { + this.customDir = customDir; + } + if(allowLocalRequests != null) { + this.allowLocalRequests = allowLocalRequests; + } + if(cache != null) { + this.cache = cache; } - server_HttpServer.customDir = customDir; - server_HttpServer.hasCustomRes = sys_FileSystem.exists(customDir); - server_HttpServer.allowLocalRequests = allowLocalRequests; }; -server_HttpServer.serveFiles = function(req,res) { - var url; - try { - url = new js_node_url_URL(server_HttpServer.safeDecodeURI(req.url),"http://localhost"); - } catch( _g ) { - url = new js_node_url_URL("/","http://localhost"); +server__$HttpServer_HttpServerConfig.__name__ = true; +server__$HttpServer_HttpServerConfig.prototype = { + __class__: server__$HttpServer_HttpServerConfig +}; +var server_HttpServer = function(main,config) { + this.ctrlCharacters = new EReg("[\\u0000-\\u001F\\u007F-\\u009F\\u2000-\\u200D\\uFEFF]","g"); + this.matchVarString = new EReg("\\${([A-z_]+)}","g"); + this.matchLang = new EReg("^[A-z]+",""); + this.uploadingFilesLastChunks = new haxe_ds_StringMap(); + this.uploadingFiles = new haxe_ds_StringMap(); + this.CHUNK_SIZE = 5242880; + this.cache = null; + this.allowLocalRequests = false; + this.allowedLocalFiles = new haxe_ds_StringMap(); + this.hasCustomRes = false; + this.main = main; + this.dir = config.dir; + this.customDir = config.customDir; + this.allowLocalRequests = config.allowLocalRequests; + this.cache = config.cache; + if(this.customDir != null) { + this.hasCustomRes = sys_FileSystem.exists(this.customDir); } - var filePath = server_HttpServer.getPath(server_HttpServer.dir,url); - var ext = haxe_io_Path.extension(filePath).toLowerCase(); - res.setHeader("Accept-Ranges","bytes"); - res.setHeader("Content-Type",server_HttpServer.getMimeType(ext)); - if(server_HttpServer.allowLocalRequests && req.socket.remoteAddress == req.socket.localAddress || server_HttpServer.allowedLocalFiles.h[url.pathname]) { - if(server_HttpServer.isMediaExtension(ext)) { - server_HttpServer.allowedLocalFiles.h[url.pathname] = true; - var s = url.pathname; - if(server_HttpServer.serveMedia(req,res,decodeURIComponent(s.split("+").join(" ")))) { - return; +}; +server_HttpServer.__name__ = true; +server_HttpServer.prototype = { + serveFiles: function(req,res) { + var _gthis = this; + var url; + try { + url = new js_node_url_URL(this.safeDecodeURI(req.url),"http://localhost"); + } catch( _g ) { + url = new js_node_url_URL("/","http://localhost"); + } + var filePath = this.getPath(this.dir,url); + var ext = haxe_io_Path.extension(filePath).toLowerCase(); + res.setHeader("Accept-Ranges","bytes"); + res.setHeader("Content-Type",this.getMimeType(ext)); + if(this.cache != null && req.method == "POST") { + switch(url.pathname) { + case "/upload": + this.uploadFile(req,res); + break; + case "/upload-last-chunk": + this.uploadFileLastChunk(req,res); + break; } + return; } - } - if(!server_HttpServer.isChildOf(server_HttpServer.dir,filePath)) { - res.statusCode = 500; - var rel = js_node_Path.relative(server_HttpServer.dir,filePath); - res.end("Error getting the file: No access to " + rel + "."); - return; - } - if(url.pathname == "/proxy") { - if(!server_HttpServer.proxyUrl(req,res)) { - res.end("Proxy error: " + req.url); + if(this.allowLocalRequests && req.socket.remoteAddress == req.socket.localAddress || this.allowedLocalFiles.h[url.pathname]) { + if(this.isMediaExtension(ext)) { + this.allowedLocalFiles.h[url.pathname] = true; + var s = url.pathname; + if(this.serveMedia(req,res,decodeURIComponent(s.split("+").join(" ")))) { + return; + } + } } - return; - } - if(server_HttpServer.hasCustomRes) { - var path = server_HttpServer.getPath(server_HttpServer.customDir,url); - if(js_node_Fs.existsSync(path)) { - filePath = path; + if(!this.isChildOf(this.dir,filePath)) { + res.statusCode = 500; + var rel = js_node_Path.relative(this.dir,filePath); + res.end("Error getting the file: No access to " + rel + "."); + return; } - } - if(server_HttpServer.isMediaExtension(ext)) { - if(server_HttpServer.serveMedia(req,res,filePath)) { + if(url.pathname == "/proxy") { + if(!this.proxyUrl(req,res)) { + res.end("Proxy error: " + req.url); + } return; } + if(this.hasCustomRes) { + var path = this.getPath(this.customDir,url); + if(js_node_Fs.existsSync(path)) { + filePath = path; + } + } + if(this.isMediaExtension(ext)) { + if(this.serveMedia(req,res,filePath)) { + return; + } + } + js_node_Fs.readFile(filePath,function(err,data) { + if(err != null) { + _gthis.readFileError(err,res,filePath); + return; + } + if(ext == "html") { + data = _gthis.localizeHtml(data.toString(),req.headers["accept-language"]); + } + res.end(data); + }); + } + ,uploadFileLastChunk: function(req,res) { + var _gthis = this; + var name = this.cache.getFreeFileName(req.headers["content-name"]); + var filePath = this.cache.getFilePath(name); + var body = []; + req.on("data",function(chunk) { + return body.push(chunk); + }); + req.on("end",function() { + var buffer = js_node_buffer_Buffer.concat(body); + _gthis.uploadingFilesLastChunks.h[filePath] = buffer; + res.writeHead(200,{ "Content-Type" : "application/json"}); + res.end(JSON.stringify({ info : "File last chunk uploaded"})); + }); } - js_node_Fs.readFile(filePath,function(err,data) { - if(err != null) { - server_HttpServer.readFileError(err,res,filePath); + ,uploadFile: function(req,res) { + var _gthis = this; + var name = this.cache.getFreeFileName(req.headers["content-name"]); + var clientName = req.headers["client-name"]; + var filePath = this.cache.getFilePath(name); + var size; + var tmp = Std.parseInt(req.headers["content-length"]); + if(tmp != null) { + size = tmp; + } else { return; } - if(ext == "html") { - data = server_HttpServer.localizeHtml(data.toString(),req.headers["accept-language"]); + var written = 0; + if(this.cache.getFreeSpace() < size) { + var _this = _gthis.uploadingFiles; + if(Object.prototype.hasOwnProperty.call(_this.h,name)) { + delete(_this.h[name]); + } + var _this = _gthis.uploadingFilesLastChunks; + if(Object.prototype.hasOwnProperty.call(_this.h,name)) { + delete(_this.h[name]); + } + res.statusCode = 200; + res.end(JSON.stringify({ info : "Error: Not enough free space on server or file size is out of cache storage limit.", errorId : "freeSpace"})); + return; } - res.end(data); - }); -}; -server_HttpServer.getPath = function(dir,url) { - var filePath = dir + url.pathname; - filePath = decodeURIComponent(filePath.split("+").join(" ")); - if(!sys_FileSystem.isDirectory(filePath)) { - return filePath; + var stream = js_node_Fs.createWriteStream(filePath); + req.pipe(stream); + var isStart = true; + req.on("data",function(chunk) { + var url = null; + if(isStart) { + isStart = false; + _gthis.cache.removeOlderCache(size); + _gthis.cache.add(name); + _gthis.uploadingFiles.h[filePath] = size; + url = _gthis.cache.getFileUrl(name); + } + written += chunk.length; + var v = written / size; + var ratio = v < 0 ? 0 : v > 1 ? 1 : v; + tools_MathTools.toFixed(ratio * 100,2); + var tmp = ClientTools.getByName(_gthis.main.clients,clientName); + if(tmp == null) { + return; + } + _gthis.main.send(tmp,{ type : "Progress", progress : { type : "Uploading", ratio : ratio, data : url}}); + }); + stream.on("close",function() { + var _this = _gthis.uploadingFiles; + if(Object.prototype.hasOwnProperty.call(_this.h,name)) { + delete(_this.h[name]); + } + var _this = _gthis.uploadingFilesLastChunks; + if(Object.prototype.hasOwnProperty.call(_this.h,name)) { + delete(_this.h[name]); + } + res.statusCode = 200; + res.end(JSON.stringify({ info : "File write stream closed."})); + }); + stream.on("error",function(err) { + haxe_Log.trace(err,{ fileName : "src/server/HttpServer.hx", lineNumber : 210, className : "server.HttpServer", methodName : "uploadFile"}); + var _this = _gthis.uploadingFiles; + if(Object.prototype.hasOwnProperty.call(_this.h,name)) { + delete(_this.h[name]); + } + var _this = _gthis.uploadingFilesLastChunks; + if(Object.prototype.hasOwnProperty.call(_this.h,name)) { + delete(_this.h[name]); + } + res.statusCode = 200; + res.end(JSON.stringify({ info : "File write stream error."})); + }); + req.on("error",function(err) { + haxe_Log.trace("Request Error:",{ fileName : "src/server/HttpServer.hx", lineNumber : 216, className : "server.HttpServer", methodName : "uploadFile", customParams : [err]}); + stream.destroy(); + var _this = _gthis.uploadingFiles; + if(Object.prototype.hasOwnProperty.call(_this.h,name)) { + delete(_this.h[name]); + } + var _this = _gthis.uploadingFilesLastChunks; + if(Object.prototype.hasOwnProperty.call(_this.h,name)) { + delete(_this.h[name]); + } + res.statusCode = 200; + res.end(JSON.stringify({ info : "File request error."})); + }); } - return haxe_io_Path.addTrailingSlash(filePath) + "index.html"; -}; -server_HttpServer.readFileError = function(err,res,filePath) { - res.setHeader("Content-Type",server_HttpServer.getMimeType("html")); - if(err.code == "ENOENT") { - res.statusCode = 404; - var rel = js_node_Path.relative(server_HttpServer.dir,filePath); - res.end("File " + rel + " not found."); - } else { - res.statusCode = 500; - res.end("Error getting the file: " + Std.string(err) + "."); + ,getPath: function(dir,url) { + var filePath = dir + url.pathname; + filePath = decodeURIComponent(filePath.split("+").join(" ")); + if(!sys_FileSystem.isDirectory(filePath)) { + return filePath; + } + return haxe_io_Path.addTrailingSlash(filePath) + "index.html"; } -}; -server_HttpServer.serveMedia = function(req,res,filePath) { - if(!js_node_Fs.existsSync(filePath)) { - return false; + ,readFileError: function(err,res,filePath) { + res.setHeader("Content-Type",this.getMimeType("html")); + if(err.code == "ENOENT") { + res.statusCode = 404; + var rel = js_node_Path.relative(this.dir,filePath); + res.end("File " + rel + " not found."); + } else { + res.statusCode = 500; + res.end("Error getting the file: " + Std.string(err) + "."); + } } - var videoSize = js_node_Fs.statSync(filePath).size; - var rangeHeader = req.headers["range"]; - if(rangeHeader == null) { - res.statusCode = 200; - res.setHeader("Content-Length","" + videoSize); - var videoStream = js_node_Fs.createReadStream(filePath); - videoStream.pipe(res); + ,serveMedia: function(req,res,filePath) { + if(!js_node_Fs.existsSync(filePath)) { + return false; + } + var videoSize = js_node_Fs.statSync(filePath).size; + if(Object.prototype.hasOwnProperty.call(this.uploadingFiles.h,filePath)) { + videoSize = this.uploadingFiles.h[filePath]; + } + var rangeHeader = req.headers["range"]; + if(rangeHeader == null) { + res.statusCode = 200; + res.setHeader("Content-Length","" + videoSize); + var videoStream = js_node_Fs.createReadStream(filePath); + videoStream.pipe(res); + res.on("error",function() { + return videoStream.destroy(); + }); + res.on("close",function() { + return videoStream.destroy(); + }); + return true; + } + var range = this.parseRangeHeader(rangeHeader,videoSize); + var start = range.start; + var end = range.end; + var contentLength = end - start + 1; + res.setHeader("Content-Range","bytes " + start + "-" + end + "/" + videoSize); + res.setHeader("Content-Length","" + contentLength); + res.statusCode = 206; + var buffer = this.uploadingFilesLastChunks.h[filePath]; + if(buffer != null && end == videoSize - 1 && contentLength < buffer.byteLength) { + var a = buffer.byteLength - contentLength; + res.end(buffer.slice(a < 0 ? 0 : a)); + return true; + } + var videoStream1 = js_node_Fs.createReadStream(filePath,{ start : start, end : end}); + videoStream1.pipe(res); res.on("error",function() { - return videoStream.destroy(); + return videoStream1.destroy(); }); res.on("close",function() { - return videoStream.destroy(); + return videoStream1.destroy(); }); return true; } - var range = server_HttpServer.parseRangeHeader(rangeHeader,videoSize); - var start = range.start; - var end = range.end; - res.setHeader("Content-Range","bytes " + start + "-" + end + "/" + videoSize); - res.setHeader("Content-Length","" + (end - start + 1)); - res.statusCode = 206; - var videoStream1 = js_node_Fs.createReadStream(filePath,{ start : start, end : end}); - videoStream1.pipe(res); - res.on("error",function() { - return videoStream1.destroy(); - }); - res.on("close",function() { - return videoStream1.destroy(); - }); - return true; -}; -server_HttpServer.parseRangeHeader = function(rangeHeader,videoSize) { - var ranges = new EReg("[-=]","g").split(rangeHeader); - var start = parseFloat(ranges[1]); - if(server_Utils.isOutOfRange(start,0,videoSize - 1)) { - start = 0; - } - var end = parseFloat(ranges[2]); - if(isNaN(end)) { - end = start + server_HttpServer.CHUNK_SIZE; - } - if(server_Utils.isOutOfRange(end,start,videoSize - 1)) { - end = videoSize - 1; - } - return { start : start, end : end}; -}; -server_HttpServer.isMediaExtension = function(ext) { - if(!(ext == "mp4" || ext == "webm" || ext == "mp3")) { - return ext == "wav"; - } else { - return true; + ,parseRangeHeader: function(rangeHeader,videoSize) { + var ranges = new EReg("[-=]","g").split(rangeHeader); + var start = Std.parseInt(ranges[1]); + if(server_Utils.isOutOfRange(start,0,videoSize - 1)) { + start = 0; + } + var end = Std.parseInt(ranges[2]); + if(end == null) { + end = start + this.CHUNK_SIZE; + } + if(server_Utils.isOutOfRange(end,start,videoSize - 1)) { + end = videoSize - 1; + } + return { start : start, end : end}; } -}; -server_HttpServer.localizeHtml = function(data,lang) { - if(lang != null && server_HttpServer.matchLang.match(lang)) { - lang = server_HttpServer.matchLang.matched(0); - } else { - lang = "en"; + ,isMediaExtension: function(ext) { + if(!(ext == "mp4" || ext == "webm" || ext == "mp3")) { + return ext == "wav"; + } else { + return true; + } } - data = server_HttpServer.matchVarString.map(data,function(regExp) { - var key = regExp.matched(1); - return Lang.get(lang,key); - }); - return data; -}; -server_HttpServer.proxyUrl = function(req,res) { - var url = StringTools.replace(req.url,"/proxy?url=",""); - var proxy = server_HttpServer.proxyRequest(url,req,res,function(proxyRes) { - var tmp = proxyRes.headers["location"]; - if(tmp == null) { - return false; + ,localizeHtml: function(data,lang) { + if(lang != null && this.matchLang.match(lang)) { + lang = this.matchLang.matched(0); + } else { + lang = "en"; } - var proxy2 = server_HttpServer.proxyRequest(tmp,req,res,function(proxyRes) { - return false; + data = this.matchVarString.map(data,function(regExp) { + var key = regExp.matched(1); + return Lang.get(lang,key); }); - if(proxy2 == null) { - res.end("Proxy error: multiple redirects for url " + tmp); + return data; + } + ,proxyUrl: function(req,res) { + var _gthis = this; + var url = StringTools.replace(req.url,"/proxy?url=",""); + var proxy = this.proxyRequest(url,req,res,function(proxyRes) { + var tmp = proxyRes.headers["location"]; + if(tmp == null) { + return false; + } + var proxy2 = _gthis.proxyRequest(tmp,req,res,function(proxyRes) { + return false; + }); + if(proxy2 == null) { + res.end("Proxy error: multiple redirects for url " + tmp); + return true; + } + req.pipe(proxy2); return true; + }); + if(proxy == null) { + return false; } - req.pipe(proxy2); + req.pipe(proxy); return true; - }); - if(proxy == null) { - return false; - } - req.pipe(proxy); - return true; -}; -server_HttpServer.proxyRequest = function(url,req,res,cancelProxyRequest) { - var url1; - try { - url1 = new js_node_url_URL(server_HttpServer.safeDecodeURI(url)); - } catch( _g ) { - return null; } - if(url1.host == req.headers["host"]) { - return null; + ,proxyRequest: function(url,req,res,cancelProxyRequest) { + var url1; + try { + url1 = new js_node_url_URL(this.safeDecodeURI(url)); + } catch( _g ) { + return null; + } + if(url1.host == req.headers["host"]) { + return null; + } + var options = { host : url1.hostname, port : Std.parseInt(url1.port), path : url1.pathname + url1.search, method : req.method}; + req.headers["referer"] = url1.toString(); + req.headers["host"] = url1.hostname; + var request = url1.protocol == "https:" ? js_node_Https.request : js_node_Http.request; + var proxy = request(options,function(proxyRes) { + if(cancelProxyRequest(proxyRes)) { + return; + } + proxyRes.headers["content-type"] = "application/octet-stream"; + res.writeHead(proxyRes.statusCode,proxyRes.headers); + proxyRes.pipe(res); + }); + proxy.on("error",function(err) { + res.end("Proxy error: " + url1.href); + }); + return proxy; } - var options = { host : url1.hostname, port : Std.parseInt(url1.port), path : url1.pathname + url1.search, method : req.method}; - req.headers["referer"] = url1.toString(); - req.headers["host"] = url1.hostname; - var request = url1.protocol == "https:" ? js_node_Https.request : js_node_Http.request; - var proxy = request(options,function(proxyRes) { - if(cancelProxyRequest(proxyRes)) { - return; + ,isChildOf: function(parent,child) { + var rel = js_node_Path.relative(parent,child); + if(rel.length > 0 && !StringTools.startsWith(rel,"..")) { + return !js_node_Path.isAbsolute(rel); + } else { + return false; } - proxyRes.headers["Content-Type"] = "application/octet-stream"; - res.writeHead(proxyRes.statusCode,proxyRes.headers); - proxyRes.pipe(res); - }); - proxy.on("error",function(err) { - res.end("Proxy error: " + url1.href); - }); - return proxy; -}; -server_HttpServer.isChildOf = function(parent,child) { - var rel = js_node_Path.relative(parent,child); - if(rel.length > 0 && !StringTools.startsWith(rel,"..")) { - return !js_node_Path.isAbsolute(rel); - } else { - return false; } -}; -server_HttpServer.getMimeType = function(ext) { - var tmp = server_HttpServer.mimeTypes.h[ext]; - if(tmp != null) { - return tmp; - } else { - return "application/octet-stream"; + ,getMimeType: function(ext) { + var tmp = server_HttpServer.mimeTypes.h[ext]; + if(tmp != null) { + return tmp; + } else { + return "application/octet-stream"; + } } -}; -server_HttpServer.safeDecodeURI = function(data) { - try { - data = decodeURI(data); - } catch( _g ) { - data = ""; + ,safeDecodeURI: function(data) { + try { + data = decodeURI(data); + } catch( _g ) { + data = ""; + } + data = data.replace(this.ctrlCharacters.r,""); + return data; } - data = data.replace(server_HttpServer.ctrlCharacters.r,""); - return data; + ,__class__: server_HttpServer }; var server_Logger = function(folder,maxCount,verbose) { this.matchFileFormat = new EReg("[0-9_-]+\\.json$",""); @@ -4272,6 +4606,7 @@ var server_Main = function(opts) { this.verbose = Object.prototype.hasOwnProperty.call(args.h,"verbose"); this.statePath = "" + this.rootDir + "/user/state.json"; this.logsDir = "" + this.rootDir + "/user/logs"; + this.cacheDir = "" + this.rootDir + "/user/res/cache"; process.on("SIGINT",$bind(this,this.exit)); process.on("SIGUSR1",$bind(this,this.exit)); process.on("SIGUSR2",$bind(this,this.exit)); @@ -4287,14 +4622,14 @@ var server_Main = function(opts) { this.logger = new server_Logger(this.logsDir,10,this.verbose); this.consoleInput = new server_ConsoleInput(this); this.consoleInput.initConsoleInput(); - this.cache = new server_Cache(this,"" + this.rootDir + "/user/res/cache"); + this.cache = new server_Cache(this,this.cacheDir); if(this.cache.isYtReady) { this.playersCacheSupport.push("YoutubeType"); } this.initIntergationHandlers(); this.loadState(); this.config = this.loadUserConfig(); - this.cache.storageLimit = this.config.cacheStorageLimitGiB * 1024 * 1024 * 1024; + this.cache.setStorageLimit(this.config.cacheStorageLimitGiB * 1024 * 1024 * 1024); this.userList = this.loadUsers(); this.config.isVerbose = this.verbose; this.config.salt = this.generateConfigSalt(); @@ -4321,7 +4656,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 : 131, 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 : 135, className : "server.Main", methodName : "new"}); attempts -= 1; _gthis.port++; preparePort(); @@ -4339,23 +4674,23 @@ 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 : 144, className : "server.Main", methodName : "runServer"}); + haxe_Log.trace("Local: http://" + this.localIp + ":" + this.port,{ fileName : "src/server/Main.hx", lineNumber : 148, className : "server.Main", methodName : "runServer"}); if(this.config.localNetworkOnly) { - haxe_Log.trace("Global network is disabled in config",{ fileName : "src/server/Main.hx", lineNumber : 146, className : "server.Main", methodName : "runServer"}); + haxe_Log.trace("Global network is disabled in config",{ fileName : "src/server/Main.hx", lineNumber : 150, 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 : 152, className : "server.Main", methodName : "runServer"}); + haxe_Log.trace("Global: http://" + _gthis.globalIp + ":" + _gthis.port,{ fileName : "src/server/Main.hx", lineNumber : 156, className : "server.Main", methodName : "runServer"}); }); } var dir = "" + this.rootDir + "/res"; - server_HttpServer.init(dir,"" + this.rootDir + "/user/res",this.config.localAdmins); + var httpServer = new server_HttpServer(this,new server__$HttpServer_HttpServerConfig(dir,"" + this.rootDir + "/user/res",this.config.localAdmins,this.cache)); Lang.init("" + dir + "/langs"); var server = js_node_Http.createServer(function(req,res) { - server_HttpServer.serveFiles(req,res); + httpServer.serveFiles(req,res); }); this.wss = new js_npm_ws_Server({ server : server}); this.wss.on("connection",$bind(this,this.onConnect)); @@ -4433,7 +4768,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 : 221, className : "server.Main", methodName : "getUserConfig"}); + haxe_Log.trace("Warning: config field \"" + field + "\" is unknown",{ fileName : "src/server/Main.hx", lineNumber : 230, className : "server.Main", methodName : "getUserConfig"}); } config[field] = Reflect.field(customConfig,field); } @@ -4444,14 +4779,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 : 227, className : "server.Main", methodName : "getUserConfig"}); + haxe_Log.trace("Warning: emote name \"" + emote.name + "\" has copy",{ fileName : "src/server/Main.hx", lineNumber : 236, 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 : 231, className : "server.Main", methodName : "getUserConfig"}); + haxe_Log.trace("Warning: emote url of name \"" + emote.name + "\" has copy",{ fileName : "src/server/Main.hx", lineNumber : 240, className : "server.Main", methodName : "getUserConfig"}); } emoteCopies_h[emote.image] = true; } @@ -4489,7 +4824,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 : 270, className : "server.Main", methodName : "saveState"}); + haxe_Log.trace("Saving state...",{ fileName : "src/server/Main.hx", lineNumber : 279, className : "server.Main", methodName : "saveState"}); var json = JSON.stringify(this.getCurrentState(),null,"\t"); js_node_Fs.writeFileSync(this.statePath,json); this.writeUsers(this.userList); @@ -4504,7 +4839,7 @@ server_Main.prototype = { if(!sys_FileSystem.exists(this.statePath)) { return; } - haxe_Log.trace("Loading state...",{ fileName : "src/server/Main.hx", lineNumber : 294, className : "server.Main", methodName : "loadState"}); + haxe_Log.trace("Loading state...",{ fileName : "src/server/Main.hx", lineNumber : 303, 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 : []; @@ -4528,7 +4863,7 @@ server_Main.prototype = { this.videoTimer.pause(); } ,logError: function(type,data) { - haxe_Log.trace(type,{ fileName : "src/server/Main.hx", lineNumber : 318, className : "server.Main", methodName : "logError", customParams : [data]}); + haxe_Log.trace(type,{ fileName : "src/server/Main.hx", lineNumber : 327, className : "server.Main", methodName : "logError", customParams : [data]}); var crashesFolder = "" + this.rootDir + "/user/crashes"; server_Utils.ensureDir(crashesFolder); var name = DateTools.format(new Date(),"%Y-%m-%d_%H_%M_%S") + "-" + type; @@ -4546,7 +4881,7 @@ server_Main.prototype = { if(_gthis.clients.length == 0) { return; } - haxe_Log.trace("Ping " + url,{ fileName : "src/server/Main.hx", lineNumber : 335, className : "server.Main", methodName : "initIntergationHandlers"}); + haxe_Log.trace("Ping " + url,{ fileName : "src/server/Main.hx", lineNumber : 344, className : "server.Main", methodName : "initIntergationHandlers"}); js_node_Http.get(url,null,function(r) { }); }; @@ -4566,13 +4901,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 : 358, 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 : 365, className : "server.Main", methodName : "removeAdmin"}); + haxe_Log.trace("Admin " + name + " removed.",{ fileName : "src/server/Main.hx", lineNumber : 374, className : "server.Main", methodName : "removeAdmin"}); } ,replayLog: function(events) { var _gthis = this; @@ -4639,7 +4974,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 : 424, className : "server.Main", methodName : "onConnect", customParams : ["" + name + " connected (" + ip + ")"]}); + haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 433, 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; @@ -4653,7 +4988,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 : 441, className : "server.Main", methodName : "onConnect"}); + haxe_Log.trace(errors,{ fileName : "src/server/Main.hx", lineNumber : 450, className : "server.Main", methodName : "onConnect"}); _gthis.serverMessage(client,errors); return; } @@ -4729,7 +5064,7 @@ server_Main.prototype = { } } else { this.cache.cacheYoutubeVideo(client,item.url,function(name) { - item = _$Types_VideoItemTools.withUrl(item,"/cache/" + name); + item = _$Types_VideoItemTools.withUrl(item,_gthis.cache.getFileUrl(name)); if(item.duration > 1) { item.duration -= 1; } @@ -4821,7 +5156,7 @@ server_Main.prototype = { if(!internal) { return; } - haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 506, className : "server.Main", methodName : "onMessage", customParams : ["Client " + client.name + " disconnected"]}); + haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 515, className : "server.Main", methodName : "onMessage", customParams : ["Client " + client.name + " disconnected"]}); server_Utils.sortedPush(this.freeIds,client.id); HxOverrides.remove(this.clients,client); this.sendClientList(); @@ -4960,7 +5295,7 @@ server_Main.prototype = { this.send(client,{ type : "LoginError"}); return; } - haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 598, 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 : 607, className : "server.Main", methodName : "onMessage", customParams : ["Client " + client.name + " logged as " + name]}); client.name = name; client.setGroupFlag(ClientGroup.User,true); this.checkBan(client); @@ -4973,7 +5308,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 : 619, 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 : 628, 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; @@ -5044,6 +5379,8 @@ server_Main.prototype = { this.restartWaitTimer(); this.broadcast(data); break; + case "Progress": + break; case "RemoveVideo": if(this.isPlaylistLockedFor(client)) { return; @@ -5290,7 +5627,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 : 1035, className : "server.Main", methodName : "checkBan"}); + haxe_Log.trace("" + client.name + " ban removed",{ fileName : "src/server/Main.hx", lineNumber : 1045, className : "server.Main", methodName : "checkBan"}); this.sendClientList(); } break; @@ -5468,7 +5805,7 @@ server_Utils.getGlobalIp = function(callback) { r.on("data",function(chunk) { data_b += Std.string(chunk); }); - r.on("end",function(_) { + r.on("end",function() { callback(data_b); }); }).on("error",onError).on("timeout",onError); @@ -5492,7 +5829,7 @@ server_Utils.getLocalIp = function() { return "127.0.0.1"; }; server_Utils.isOutOfRange = function(value,min,max) { - if(!(value == null || isNaN(value) || value < min)) { + if(!(value == null || value < min)) { return value > max; } else { return true; @@ -5631,6 +5968,18 @@ sys_FileSystem.createDirectory = function(path) { } } }; +var tools_MathTools = function() { }; +tools_MathTools.__name__ = true; +tools_MathTools.toFixed = function(v,digits) { + if(digits == null) { + digits = 2; + } + if(digits > 8) { + throw haxe_Exception.thrown("digits is " + digits + ", but cannot be bigger than 8 (for value " + v + ")"); + } + var ratio = Math.pow(10,digits); + return (v * ratio | 0) / ratio; +}; var utils_YoutubeUtils = function() { }; utils_YoutubeUtils.__name__ = true; utils_YoutubeUtils.extractVideoId = function(url) { @@ -5699,13 +6048,6 @@ server_HttpServer.mimeTypes = (function($this) { $r = _g; return $r; }(this)); -server_HttpServer.hasCustomRes = false; -server_HttpServer.allowedLocalFiles = new haxe_ds_StringMap(); -server_HttpServer.allowLocalRequests = false; -server_HttpServer.CHUNK_SIZE = 5242880; -server_HttpServer.matchLang = new EReg("^[A-z]+",""); -server_HttpServer.matchVarString = new EReg("\\${([A-z_]+)}","g"); -server_HttpServer.ctrlCharacters = new EReg("[\\u0000-\\u001F\\u007F-\\u009F\\u2000-\\u200D\\uFEFF]","g"); utils_YoutubeUtils.matchId = new EReg("youtube\\.com.*v=([A-z0-9_-]+)",""); utils_YoutubeUtils.matchShort = new EReg("youtu\\.be/([A-z0-9_-]+)",""); utils_YoutubeUtils.matchShorts = new EReg("youtube\\.com/shorts/([A-z0-9_-]+)",""); diff --git a/res/client.js b/res/client.js index b009967..ac32132 100644 --- a/res/client.js +++ b/res/client.js @@ -789,6 +789,48 @@ client_Buttons.init = function(main) { mediaUrl.value = main.getTemplateUrl(); mediaUrl.focus(); }; + window.document.querySelector("#mediaurl-upload").onclick = function(e) { + client_Utils.browseFile(function(buffer,name) { + if(name == null || name.length == 0) { + name = "video"; + } + if(buffer.byteLength > 5242880) { + var lastChunk = buffer.slice(buffer.byteLength - 5242880); + window.fetch("/upload-last-chunk",{ method : "POST", headers : { "content-name" : haxe_io_Path.withoutExtension(name), "client-name" : main.personal.name}, body : lastChunk}); + } + var request = window.fetch("/upload",{ method : "POST", headers : { "content-name" : haxe_io_Path.withoutExtension(name), "client-name" : main.personal.name}, body : buffer}); + request.then(function(e) { + return e.json().then(function(data) { + haxe_Log.trace(data.info,{ fileName : "src/client/Buttons.hx", lineNumber : 274, className : "client.Buttons", methodName : "init"}); + if(data.errorId == null) { + return; + } + main.serverMessage(data.info,true,false); + }); + }).catch(function(err) { + haxe_Log.trace(err,{ fileName : "src/client/Buttons.hx", lineNumber : 279, className : "client.Buttons", methodName : "init"}); + return haxe_Timer.delay(function() { + main.hideDynamicChin(); + },500); + }); + var onStartUpload = null; + onStartUpload = function(event) { + if(event.type != "Progress") { + return; + } + var data = event.progress; + if(data.type != "Uploading") { + return; + } + if(data.data == null) { + return; + } + window.document.querySelector("#mediaurl").value = data.data; + client_JsApi.off("Progress",onStartUpload); + }; + client_JsApi.on("Progress",onStartUpload); + }); + }; var showOptions = window.document.querySelector("#showoptions"); showOptions.onclick = function(e) { var isActive = client_Buttons.toggleGroup(showOptions); @@ -1244,7 +1286,28 @@ client_JsApi.hasSubtitleSupport = $hx_exports["client"]["JsApi"]["hasSubtitleSup client_JsApi.once = $hx_exports["client"]["JsApi"]["once"] = function(type,callback) { client_JsApi.onceListeners.unshift({ type : type, callback : callback}); }; -client_JsApi.fireOnceEvent = function(event) { +client_JsApi.on = function(type,callback) { + client_JsApi.onListeners.unshift({ type : type, callback : callback}); +}; +client_JsApi.off = function(type,callback) { + HxOverrides.remove(client_JsApi.onListeners,Lambda.find(client_JsApi.onListeners,function(item) { + if(item.type == type) { + return item.callback == callback; + } else { + return false; + } + })); +}; +client_JsApi.fireEvents = function(event) { + var _g_arr = client_JsApi.onListeners; + var _g_i = _g_arr.length - 1; + while(_g_i > -1) { + var listener = _g_arr[_g_i--]; + if(listener.type != event.type) { + continue; + } + listener.callback(event); + } var _g_arr = client_JsApi.onceListeners; var _g_i = _g_arr.length - 1; while(_g_i > -1) { @@ -1634,12 +1697,13 @@ client_Main.prototype = { } } ,onMessage: function(e) { + var _gthis = this; var data = JSON.parse(e.data); if(this.config != null && this.config.isVerbose) { var t = data.type; - haxe_Log.trace("Event: " + data.type,{ fileName : "src/client/Main.hx", lineNumber : 458, className : "client.Main", methodName : "onMessage", customParams : [Reflect.field(data,t.charAt(0).toLowerCase() + HxOverrides.substr(t,1,null))]}); + haxe_Log.trace("Event: " + data.type,{ fileName : "src/client/Main.hx", lineNumber : 456, className : "client.Main", methodName : "onMessage", customParams : [Reflect.field(data,t.charAt(0).toLowerCase() + HxOverrides.substr(t,1,null))]}); } - client_JsApi.fireOnceEvent(data); + client_JsApi.fireEvents(data); switch(data.type) { case "AddVideo": this.player.addVideoItem(data.addVideo.item,data.addVideo.atEnd); @@ -1784,6 +1848,32 @@ client_Main.prototype = { case "PlayItem": this.player.setVideo(data.playItem.pos); break; + case "Progress": + var data1 = data.progress; + var text; + switch(data1.type) { + case "Caching": + text = "" + Lang.get("caching") + " " + data1.data; + break; + case "Downloading": + text = Lang.get("downloading"); + break; + case "Uploading": + text = Lang.get("uploading"); + break; + } + var percent = tools_MathTools.toFixed(data1.ratio * 100,1); + var text1 = "" + text + "..."; + if(percent > 0) { + text1 += " " + percent + "%"; + } + this.showProgressInfo(text1); + if(data1.ratio == 1) { + haxe_Timer.delay(function() { + _gthis.hideDynamicChin(); + },500); + } + break; case "RemoveVideo": this.player.removeItem(data.removeVideo.url); if(this.player.isListEmpty()) { @@ -2166,6 +2256,7 @@ client_Main.prototype = { } this.addMessageDiv(div); this.scrollChatToEnd(); + return div; } ,updateUserList: function() { window.document.querySelector("#usercount").textContent = this.clients.length + " " + Lang.get("online"); @@ -2277,6 +2368,17 @@ client_Main.prototype = { return btn.style.display = "none"; },{ once : true}); } + ,showProgressInfo: function(text) { + var chin = window.document.querySelector("#dynamic-chin"); + var div = chin.querySelector("#progress-info"); + if(div == null) { + div = window.document.createElement("div"); + div.id = "progress-info"; + chin.prepend(div); + } + div.textContent = text; + this.showDynamicChin(); + } ,showServerUnpause: function() { var _gthis = this; if(this.showingServerPause) { @@ -2300,6 +2402,13 @@ client_Main.prototype = { _gthis.removeLeader(); }); }; + this.showDynamicChin(); + } + ,showDynamicChin: function() { + var chin = window.document.querySelector("#dynamic-chin"); + if(chin.style.display == "") { + return; + } chin.style.display = ""; chin.style.transition = "none"; chin.classList.remove("collapsed"); @@ -3434,42 +3543,63 @@ client_Utils.copyToClipboard = function(text) { client_Utils.matchedNum = function(ereg) { return ereg.r.m.length; }; -client_Utils.browseFileUrl = function(onFileLoad,isBinary,revoke) { +client_Utils.browseFile = function(onFileLoad) { + client_Utils.browseFileImpl(onFileLoad,true,false); +}; +client_Utils.browseFileUrl = function(onFileLoad,revoke) { if(revoke == null) { revoke = false; } - if(isBinary == null) { - isBinary = true; - } + client_Utils.browseFileImpl(onFileLoad,false,revoke); +}; +client_Utils.browseFileImpl = function(onFileLoad,isBinary,revokeAfterLoad) { var input = window.document.createElement("input"); input.style.visibility = "hidden"; - input.setAttribute("type","file"); + input.type = "file"; input.id = "browse"; input.onclick = function(e) { e.cancelBubble = true; - e.stopPropagation(); + return e.stopPropagation(); }; - input.onchange = function() { - var file = input.files[0]; - var url = URL.createObjectURL(file); - onFileLoad(url,file.name); - window.document.body.removeChild(input); - if(revoke) { - URL.revokeObjectURL(url); + input.onchange = function(e) { + var file; + var tmp = input.files[0]; + if(tmp != null) { + file = tmp; + } else { + return; + } + if(!isBinary) { + var url = URL.createObjectURL(file); + onFileLoad(url,file.name); + window.document.body.removeChild(input); + if(revokeAfterLoad) { + URL.revokeObjectURL(url); + } + return; } + var reader = new FileReader(); + reader.onload = function(e) { + var result = reader.result; + onFileLoad(result,file.name); + return window.document.body.removeChild(input); + }; + reader.onerror = function(e) { + return window.document.body.removeChild(input); + }; + reader.readAsArrayBuffer(file); }; window.document.body.appendChild(input); input.click(); }; client_Utils.saveFile = function(name,mime,data) { - var blob = new Blob([data],{ type : mime}); - var url = URL.createObjectURL(blob); + var url = URL.createObjectURL(new Blob([data],{ type : mime})); var a = window.document.createElement("a"); a.download = name; a.href = url; a.onclick = function(e) { e.cancelBubble = true; - e.stopPropagation(); + return e.stopPropagation(); }; window.document.body.appendChild(a); a.click(); @@ -3645,7 +3775,7 @@ client_players_Raw.prototype = { ,loadVideo: function(item) { var _gthis = this; var url = this.main.tryLocalIp(item.url); - var isHls = item.url.indexOf("m3u8") != -1 || StringTools.endsWith(item.title,"m3u8"); + var isHls = url.indexOf("m3u8") != -1 || StringTools.endsWith(item.title,"m3u8"); if(isHls && !this.isHlsLoaded) { this.loadHlsPlugin(function() { _gthis.loadVideo(item); @@ -5262,6 +5392,14 @@ js_Browser.createXMLHttpRequest = function() { }; var js_hlsjs_HlsConfig = function() { }; js_hlsjs_HlsConfig.__name__ = true; +var js_lib__$ArrayBuffer_ArrayBufferCompat = function() { }; +js_lib__$ArrayBuffer_ArrayBufferCompat.__name__ = true; +js_lib__$ArrayBuffer_ArrayBufferCompat.sliceImpl = function(begin,end) { + var u = new Uint8Array(this,begin,end == null ? null : end - begin); + var resultArray = new Uint8Array(u.byteLength); + resultArray.set(u); + return resultArray.buffer; +}; var js_youtube_Youtube = function() { }; js_youtube_Youtube.__name__ = true; js_youtube_Youtube.init = function(onAPIReady) { @@ -5276,6 +5414,18 @@ js_youtube_Youtube.init = function(onAPIReady) { } }; }; +var tools_MathTools = function() { }; +tools_MathTools.__name__ = true; +tools_MathTools.toFixed = function(v,digits) { + if(digits == null) { + digits = 2; + } + if(digits > 8) { + throw haxe_Exception.thrown("digits is " + digits + ", but cannot be bigger than 8 (for value " + v + ")"); + } + var ratio = Math.pow(10,digits); + return (v * ratio | 0) / ratio; +}; var utils_YoutubeUtils = function() { }; utils_YoutubeUtils.__name__ = true; utils_YoutubeUtils.extractVideoId = function(url) { @@ -5310,12 +5460,16 @@ String.__name__ = true; Array.__name__ = true; Date.__name__ = "Date"; js_Boot.__toStr = ({ }).toString; +if(ArrayBuffer.prototype.slice == null) { + ArrayBuffer.prototype.slice = js_lib__$ArrayBuffer_ArrayBufferCompat.sliceImpl; +} Lang.langs = new haxe_ds_StringMap(); Lang.ids = ["en","ru"]; Lang.lang = HxOverrides.substr($global.navigator.language,0,2).toLowerCase(); client_JsApi.subtitleFormats = []; client_JsApi.videoChange = []; client_JsApi.videoRemove = []; +client_JsApi.onListeners = []; client_JsApi.onceListeners = []; client_Settings.isSupported = false; client_Utils.isMacSafari = client_Utils._isMacSafari(); diff --git a/res/css/des.css b/res/css/des.css index 8c7f0cc..d6cd5ed 100644 --- a/res/css/des.css +++ b/res/css/des.css @@ -423,7 +423,7 @@ header h4 { background: var(--background-video); } - .info { + .video-info { order: 2; } @@ -480,6 +480,8 @@ iframe#videoplayer { /* Playlist */ #playlist { + display: flex; + flex-direction: column; border-top: .063rem solid; border-color: var(--border); } @@ -527,8 +529,25 @@ iframe#videoplayer { flex-grow: 1; } -#mediaurl { +.mediaurl-wrap { + display: flex; flex-grow: 2; + position: relative; +} + +#mediaurl { + display: flex; + flex: 1; + padding-right: 2rem; +} + +#mediaurl-upload { + display: flex; + position: absolute; + right: 0.1rem; + top: 50%; + transform: translateY(-50%); + background: transparent; } #customembed>*>input, @@ -682,6 +701,7 @@ footer#footer { } #userlisttoggle { + padding: 0; overflow: hidden; white-space: nowrap; text-align: left; diff --git a/res/index.html b/res/index.html index 47be463..4c06632 100644 --- a/res/index.html +++ b/res/index.html @@ -20,8 +20,8 @@ <section id="player"> <div id="ytapiplayer" class="embed-responsive"></div> <!-- Video info --> - <div class="info"> - <header id="header"> + <div class="info video-info"> + <header> <h2 id="currenttitle">${nothingPlaying}</h2> </header> <!-- Video controls --> @@ -44,7 +44,7 @@ <!-- Playlist --> <section id="playlist"> <!-- Playlist info --> - <div class="info"> + <div class="info playlist-info"> <header> <h3>${playlist}</h3> <button id="lockplaylist" title="${playlistOpen}"> @@ -88,7 +88,12 @@ <button id="insert_template" title="${addTemplateUrl}"> <div>></div> </button> - <input id="mediaurl" type="text" placeholder="${addVideoFromUrl}"> + <div class="mediaurl-wrap"> + <input id="mediaurl" type="text" placeholder="${addVideoFromUrl}"> + <button id="mediaurl-upload"> + <ion-icon name="cloud-upload"></ion-icon> + </button> + </div> </div> <div id="mediatitleblock" class="display-flex" style="display: none;"> <input id="mediatitle" type="text" placeholder="${optionalTitle}"> diff --git a/res/langs/en.json b/res/langs/en.json index 8869f48..36ff556 100644 --- a/res/langs/en.json +++ b/res/langs/en.json @@ -24,6 +24,9 @@ "videoAlreadyExistsError": "The video already exists in playlist.", "addVideoError": "Failed to add video.", "adminsCannotBeBannedError": "Admins cannot be banned. Remove them first.", + "caching": "Caching", + "downloading": "Downloading", + "uploading": "Uploading", "rawVideo": "Raw video", "videos": "videos", "addedBy": "Added by", @@ -91,6 +94,7 @@ "queueLast": "Queue last", "and": "and", "or": "or", + "to": "to", "pasteEmbedCodeAndClick": "Paste the embed code here", "acceptableEmbedCodesAre": "Acceptable embed codes are", "customEmbedsCannotBeSynchronized": "CUSTOM EMBEDS CANNOT BE SYNCHRONIZED", diff --git a/res/langs/ru.json b/res/langs/ru.json index 8ce24af..ec0a642 100644 --- a/res/langs/ru.json +++ b/res/langs/ru.json @@ -24,6 +24,9 @@ "videoAlreadyExistsError": "Видео уже имеется в плейлисте.", "addVideoError": "Не удалось добавить видео.", "adminsCannotBeBannedError": "Админы не могут быть заблокированы. Сначала удалите их.", + "caching": "Кэширование", + "uploading": "Выгрузка", + "downloading": "Загрузка", "rawVideo": "Исходное видео", "videos": "видео", "addedBy": "Добавлено", @@ -91,6 +94,7 @@ "queueLast": "В конец", "and": "и", "or": "или", + "to": "в", "pasteEmbedCodeAndClick": "Вставьте код видео в это поле", "acceptableEmbedCodesAre": "Можно добавить видео с тегами", "customEmbedsCannotBeSynchronized": "СИНХРОНИЗАЦИЯ БУДЕТ НЕДОСТУПНА", diff --git a/src/Types.hx b/src/Types.hx index ec09b5c..ac2599c 100644 --- a/src/Types.hx +++ b/src/Types.hx @@ -14,6 +14,12 @@ typedef VideoDataRequest = { final atEnd:Bool; } +typedef UploadResponse = { + info:String, + ?url:String, + ?errorId:String, +} + typedef VideoData = { final duration:Float; var ?title:String; @@ -107,6 +113,12 @@ typedef Message = { time:String } +enum abstract ProgressType(String) { + var Caching; + var Downloading; + var Uploading; +} + @:using(Types.VideoItemTools) typedef VideoItem = { /** Immutable, used as identifier for skipping / removing items **/ @@ -183,6 +195,11 @@ typedef WsEvent = { ?serverMessage:{ textId:String }, + ?progress:{ + type:ProgressType, + ratio:Float, + ?data:String + }, ?updateClients:{ clients:Array<ClientData>, }, @@ -251,9 +268,8 @@ enum abstract WsEventType(String) { var Logout; var Message; var ServerMessage; + var Progress; var UpdateClients; - // var AddClient; - // var RemoveClient; var BanClient; var KickClient; var AddVideo; diff --git a/src/client/Buttons.hx b/src/client/Buttons.hx index fb8337d..334debc 100644 --- a/src/client/Buttons.hx +++ b/src/client/Buttons.hx @@ -1,7 +1,10 @@ package client; +import Types.UploadResponse; +import Types.WsEvent; import client.Main.ge; import haxe.Timer; +import haxe.io.Path; import js.Browser.document; import js.Browser.window; import js.html.Element; @@ -239,6 +242,60 @@ class Buttons { mediaUrl.focus(); } + ge("#mediaurl-upload").onclick = e -> { + Utils.browseFile((buffer, name) -> { + if (name == null || name.length == 0) name = "video"; + + // send last chunk separately to allow server file streaming while uploading + final chunkSize = 1024 * 1024 * 5; // 5 MB + if (buffer.byteLength > chunkSize) { + final lastChunk = buffer.slice(buffer.byteLength - chunkSize); + window.fetch("/upload-last-chunk", { + method: "POST", + headers: { + "content-name": Path.withoutExtension(name), + "client-name": main.getName(), + }, + body: lastChunk, + }); + } + + // send full file + final request = window.fetch("/upload", { + method: "POST", + headers: { + "content-name": Path.withoutExtension(name), + "client-name": main.getName(), + }, + body: buffer, + }); + request.then(e -> { + e.json().then((data:UploadResponse) -> { + trace(data.info); + if (data.errorId == null) return; + main.serverMessage(data.info, true, false); + }); + }).catchError(err -> { + trace(err); + Timer.delay(() -> { + main.hideDynamicChin(); + }, 500); + }); + + // set file url to input after upload starts + function onStartUpload(event:WsEvent):Void { + if (event.type != Progress) return; + final data = event.progress; + if (data.type != Uploading) return; + if (data.data == null) return; + final input:InputElement = ge("#mediaurl"); + input.value = data.data; + JsApi.off(Progress, onStartUpload); + } + JsApi.on(Progress, onStartUpload); + }); + } + final showOptions = ge("#showoptions"); showOptions.onclick = e -> { final isActive = toggleGroup(showOptions); @@ -362,7 +419,7 @@ class Buttons { } final selectLocalVideoBtn = ge("#selectLocalVideoBtn"); selectLocalVideoBtn.onclick = e -> { - Utils.browseFileUrl((url:String, name:String) -> { + Utils.browseFileUrl((url, name) -> { JsApi.setVideoSrc(url); }); } @@ -374,7 +431,7 @@ class Buttons { ge("#getplaylist").title += " (Alt-C)"; ge("#fullscreenbtn").title += " (Alt-F)"; ge("#leader_btn").title += " (Alt-L)"; - window.onkeydown = function(e:KeyboardEvent) { + window.onkeydown = (e:KeyboardEvent) -> { if (!settings.hotkeysEnabled) return; final target:Element = cast e.target; if (isElementEditable(target)) return; diff --git a/src/client/JsApi.hx b/src/client/JsApi.hx index defcc4d..b576b47 100644 --- a/src/client/JsApi.hx +++ b/src/client/JsApi.hx @@ -8,7 +8,7 @@ import js.Browser.window; import js.Syntax; private typedef VideoChangeFunc = (item:VideoItem) -> Void; -private typedef OnceEventFunc = (event:WsEvent) -> Void; +private typedef EventCallback = (event:WsEvent) -> Void; class JsApi { static var main:Main; @@ -16,7 +16,8 @@ class JsApi { static final subtitleFormats = []; static final videoChange:Array<VideoChangeFunc> = []; static final videoRemove:Array<VideoChangeFunc> = []; - static final onceListeners:Array<{type:WsEventType, callback:OnceEventFunc}> = []; + static final onListeners:Array<{type:WsEventType, callback:EventCallback}> = []; + static final onceListeners:Array<{type:WsEventType, callback:EventCallback}> = []; public static function init(main:Main, player:Player):Void { JsApi.main = main; @@ -147,11 +148,26 @@ class JsApi { * `});` */ @:expose - public static function once(type:WsEventType, callback:OnceEventFunc):Void { + public static function once(type:WsEventType, callback:EventCallback):Void { onceListeners.unshift({type: type, callback: callback}); } - public static function fireOnceEvent(event:WsEvent):Void { + public static function on(type:WsEventType, callback:EventCallback):Void { + onListeners.unshift({type: type, callback: callback}); + } + + public static function off(type:WsEventType, callback:EventCallback):Void { + final listener = onListeners.find(item -> { + return item.type == type && item.callback == callback; + }); + onListeners.remove(listener); + } + + public static function fireEvents(event:WsEvent):Void { + for (listener in onListeners.reversed()) { + if (listener.type != event.type) continue; + listener.callback(event); + } for (listener in onceListeners.reversed()) { if (listener.type != event.type) continue; listener.callback(event); diff --git a/src/client/Main.hx b/src/client/Main.hx index 6ec8727..61b3c3a 100644 --- a/src/client/Main.hx +++ b/src/client/Main.hx @@ -25,8 +25,6 @@ import js.html.URL; import js.html.VideoElement; import js.html.WebSocket; -using ClientTools; - class Main { public static var instance(default, null):Main; static inline var SETTINGS_VERSION = 5; @@ -457,7 +455,7 @@ class Main { final t = t.charAt(0).toLowerCase() + t.substr(1); trace('Event: ${data.type}', Reflect.field(data, t)); } - JsApi.fireOnceEvent(data); + JsApi.fireEvents(data); switch (data.type) { case Connected: onConnected(data); @@ -509,6 +507,26 @@ class Main { } serverMessage(text); + case Progress: + final data = data.progress; + final text = switch data.type { + case Caching: + final caching = Lang.get("caching"); + final name = data.data; + '$caching $name'; + case Downloading: Lang.get("downloading"); + case Uploading: Lang.get("uploading"); + } + final percent = (data.ratio * 100).toFixed(1); + var text = '$text...'; + if (percent > 0) text += ' $percent%'; + showProgressInfo(text); + if (data.ratio == 1) { + Timer.delay(() -> { + hideDynamicChin(); + }, 500); + } + case AddVideo: player.addVideoItem(data.addVideo.item, data.addVideo.atEnd); if (player.itemsLength() == 1) player.setVideo(0); @@ -934,7 +952,7 @@ class Main { return msgBuf.lastElementChild?.className.startsWith("server-msg"); } - public function serverMessage(text:String, isText = true, withTimestamp = true):Void { + public function serverMessage(text:String, isText = true, withTimestamp = true):Element { final div = document.createDivElement(); final time = Date.now().toString().split(" ")[1]; div.className = "server-whisper"; @@ -947,6 +965,7 @@ class Main { else textDiv.innerHTML = text; addMessageDiv(div); scrollChatToEnd(); + return div; } public function serverHtmlMessage(el:Element):Void { @@ -1071,6 +1090,18 @@ class Main { }, {once: true}); } + public function showProgressInfo(text:String):Void { + final chin = ge("#dynamic-chin"); + var div = chin.querySelector("#progress-info"); + if (div == null) { + div = document.createDivElement(); + div.id = "progress-info"; + chin.prepend(div); + } + div.textContent = text; + showDynamicChin(); + } + public function showServerUnpause():Void { if (showingServerPause) return; showingServerPause = true; @@ -1096,6 +1127,12 @@ class Main { JsApi.once(SetLeader, event -> removeLeader()); } + showDynamicChin(); + } + + function showDynamicChin():Void { + final chin = ge("#dynamic-chin"); + if (chin.style.display == "") return; chin.style.display = ""; chin.style.transition = "none"; chin.classList.remove("collapsed"); diff --git a/src/client/Utils.hx b/src/client/Utils.hx index 4d85697..a120166 100644 --- a/src/client/Utils.hx +++ b/src/client/Utils.hx @@ -5,7 +5,9 @@ import js.Browser.document; import js.Browser.navigator; import js.Browser.window; import js.html.Element; +import js.html.FileReader; import js.html.URL; +import js.lib.ArrayBuffer; class Utils { public static function nativeTrace(msg:Dynamic, ?infos:haxe.PosInfos):Void { @@ -127,25 +129,51 @@ class Utils { #end } + public static function browseFile( + onFileLoad:(buffer:ArrayBuffer, name:String) -> Void + ):Void { + browseFileImpl(onFileLoad, true, false); + } + public static function browseFileUrl( onFileLoad:(url:String, name:String) -> Void, - isBinary = true, revoke = false ):Void { - final input = document.createElement("input"); + browseFileImpl(onFileLoad, false, revoke); + } + + static function browseFileImpl( + onFileLoad:(data:Dynamic, name:String) -> Void, + isBinary:Bool, + revokeAfterLoad:Bool + ):Void { + final input = document.createInputElement(); input.style.visibility = "hidden"; - input.setAttribute("type", "file"); + input.type = "file"; input.id = "browse"; - input.onclick = function(e) { + input.onclick = e -> { e.cancelBubble = true; e.stopPropagation(); } - input.onchange = function() { - final file:Dynamic = (input : Dynamic).files[0]; - final url = URL.createObjectURL(file); - onFileLoad(url, file.name); - document.body.removeChild(input); - if (revoke) URL.revokeObjectURL(url); + input.onchange = e -> { + final file = input.files[0] ?? return; + if (!isBinary) { + final url = URL.createObjectURL(file); + onFileLoad(url, file.name); + document.body.removeChild(input); + if (revokeAfterLoad) URL.revokeObjectURL(url); + return; + } + final reader = new FileReader(); + reader.onload = e -> { + final result:ArrayBuffer = reader.result; + onFileLoad(result, file.name); + document.body.removeChild(input); + } + reader.onerror = e -> { + document.body.removeChild(input); + } + reader.readAsArrayBuffer(file); } document.body.appendChild(input); input.click(); @@ -156,10 +184,10 @@ class Utils { type: mime }); final url = URL.createObjectURL(blob); - final a = document.createElement("a"); - untyped a.download = name; - untyped a.href = url; - a.onclick = function(e) { + final a = document.createAnchorElement(); + a.download = name; + a.href = url; + a.onclick = e -> { e.cancelBubble = true; e.stopPropagation(); } diff --git a/src/client/players/Raw.hx b/src/client/players/Raw.hx index f054f14..10a54e8 100644 --- a/src/client/players/Raw.hx +++ b/src/client/players/Raw.hx @@ -97,7 +97,7 @@ class Raw implements IPlayer { public function loadVideo(item:VideoItem):Void { final url = main.tryLocalIp(item.url); - final isHls = item.url.contains("m3u8") || item.title.endsWith("m3u8"); + final isHls = url.contains("m3u8") || item.title.endsWith("m3u8"); if (isHls && !isHlsLoaded) { loadHlsPlugin(() -> loadVideo(item)); return; diff --git a/src/import.hx b/src/import.hx index 75f7907..4fbd165 100644 --- a/src/import.hx +++ b/src/import.hx @@ -1,3 +1,5 @@ +using ClientTools; using Lambda; using StringTools; using tools.ArrayTools; +using tools.MathTools; diff --git a/src/server/Cache.hx b/src/server/Cache.hx index 450a893..fa5889c 100644 --- a/src/server/Cache.hx +++ b/src/server/Cache.hx @@ -1,5 +1,6 @@ package server; +import haxe.io.Path; import js.lib.Promise; import js.node.ChildProcess; import js.node.Fs.Fs; @@ -16,7 +17,8 @@ class Cache { public final isYtReady = false; /** In bytes **/ - public var storageLimit = 3 * 1024 * 1024 * 1024; + var storageLimit = 3 * 1024 * 1024 * 1024; + final freeSpaceBlock = 10 * 1024 * 1024; // 10MB public function new(main:Main, cacheDir:String) { this.main = main; @@ -55,16 +57,22 @@ class Cache { return; } final outName = videoId + ".mp4"; - if (cachedFiles.contains(outName) && FileSystem.exists('$cacheDir/$outName')) { + if (cachedFiles.contains(outName) && isFileExists(outName)) { callback(outName); return; } final ytdl:Dynamic = untyped require("@distube/ytdl-core"); - log(client, 'Caching $url to $outName...'); - // final opts = {playerClients: ["IOS", "WEB_CREATOR"]}; + trace('Caching $url to $outName...'); + main.send(client, { + type: Progress, + progress: { + type: Caching, + ratio: 0, + data: outName + } + }); final promise:Promise<YouTubeVideoInfo> = ytdl.getInfo(url); promise.then(info -> { - // trace(info.formats.filter(item -> item.audioCodec != null)); trace('Get info with ${info.formats.length} formats'); final audioFormat:YoutubeVideoFormat = try { ytdl.chooseFormat(info.formats.filter(item -> { @@ -73,26 +81,23 @@ class Cache { } catch (e) { log(client, "Error: audio format not found"); trace(e); - trace(info.formats); + trace(info.formats.filter(item -> item.hasAudio)); return; } final videoFormat = getBestYoutubeVideoFormat(info.formats) ?? { log(client, "Error: video format not found"); - trace(info.formats); + trace(info.formats.filter(item -> item.hasVideo)); return; } - trace("Picked audio and video formats"); final dlVideo:Readable<Dynamic> = ytdl(url, { format: videoFormat, - // playerClients: opts.playerClients }); dlVideo.pipe(Fs.createWriteStream('$cacheDir/input-video')); dlVideo.on("error", err -> log(client, "Error during video download: " + err)); final dlAudio:Readable<Dynamic> = ytdl(url, { format: audioFormat, - // playerClients: opts.playerClients }); dlAudio.pipe(Fs.createWriteStream('$cacheDir/input-audio')); dlAudio.on("error", err -> log(client, "Error during audio download: " + err)); @@ -100,8 +105,13 @@ class Cache { var count = 0; function onComplete(type:String):Void { count++; - log(client, '$type track downloaded ($count/2)'); + trace('$type track downloaded ($count/2)'); if (count < 2) return; + var size = FileSystem.stat('$cacheDir/input-video').size; + size += FileSystem.stat('$cacheDir/input-audio').size; + // clean some space for full mp4 + removeOlderCache(size + freeSpaceBlock); + final args = '-y -i input-video -i input-audio -c copy -map 0:v -map 1:a ./$outName'.split(" "); final process = ChildProcess.spawn("ffmpeg", args, { cwd: cacheDir, @@ -117,40 +127,111 @@ class Cache { } final inVideo = '$cacheDir/input-video'; final inAudio = '$cacheDir/input-audio'; - if (FileSystem.exists(inVideo)) FileSystem.deleteFile(inVideo); - if (FileSystem.exists(inAudio)) FileSystem.deleteFile(inAudio); + FileSystem.deleteFile(inVideo); + FileSystem.deleteFile(inAudio); - if (!cachedFiles.contains(outName)) { - cachedFiles.unshift(outName); - } - removeOlderCache(); + add(outName); callback(outName); }); } dlVideo.on("finish", () -> onComplete("Video")); dlAudio.on("finish", () -> onComplete("Audio")); - // dlVideo.on('progress', (c, d, t) -> { - // final progress = Std.int((d / t * 100) * 10) / 10; - // trace(progress); - // }); + var isAudioStart = true; + dlAudio.on("progress", (chunkLength:Int, downloaded:Int, contentLength:Int) -> { + if (isAudioStart) { + isAudioStart = false; + removeOlderCache(contentLength); + } + }); + var isVideoStart = true; + dlVideo.on("progress", (chunkLength:Int, downloaded:Int, contentLength:Int) -> { + if (isVideoStart) { + isVideoStart = false; + removeOlderCache(contentLength); + } + final ratio = (downloaded / contentLength).clamp(0, 1); + main.send(client, { + type: Progress, + progress: { + type: Downloading, + ratio: ratio + } + }); + }); }).catchError(err -> { log(client, "" + err); }); } - function removeOlderCache():Void { - while (getUsedSpace() > storageLimit) { - final name = cachedFiles.pop(); - final path = '$cacheDir/$name'; + public function setStorageLimit(bytes:Int) { + storageLimit = cast bytes; + storageLimit = storageLimit.limitMin(0); + final statfs = (Fs : Dynamic).statfs ?? return; + statfs("/", (err, stats) -> { + if (err != null) { + trace(err); + return; + } + final availSpace = (stats.bsize * stats.bavail - freeSpaceBlock).limitMin(0); + removeOlderCache(); + final freeSpace = getFreeSpace(); + if (availSpace < freeSpace) { + // shrink limit lower than disk space + storageLimit += availSpace - freeSpace; + storageLimit = storageLimit.limitMin(0); + removeOlderCache(); + } + }); + } + + public function add(name:String) { + if (!cachedFiles.contains(name)) { + cachedFiles.unshift(name); + } + } + + public function removeOlderCache(addFileSize = 0):Void { + var space = getUsedSpace(addFileSize); + while (space > storageLimit) { + final name = cachedFiles.pop() ?? break; + final path = getFilePath(name); if (FileSystem.exists(path)) FileSystem.deleteFile(path); + space = getUsedSpace(addFileSize); } } - function getUsedSpace():Int { - var total = 0; + public function getFreeFileName(baseName = "video"):String { + var i = 1; + while (true) { + final n = i == 1 ? "" : '$i'; + final name = '$baseName$n.mp4'; + if (!isFileExists(name)) return name; + i++; + } + } + + public function getFilePath(name:String):String { + return '$cacheDir/$name'; + } + + public function getFileUrl(name:String):String { + final folder = Path.withoutDirectory(cacheDir); + return '/$folder/$name'; + } + + public function isFileExists(name:String):Bool { + return FileSystem.exists(getFilePath(name)); + } + + public function getFreeSpace():Int { + return storageLimit - getUsedSpace(); + } + + public function getUsedSpace(addFileSize = 0):Int { + var total = addFileSize.limitMin(0); for (name in cachedFiles.reversed()) { - final path = '$cacheDir/$name'; + final path = getFilePath(name); if (!FileSystem.exists(path)) { cachedFiles.remove(name); continue; @@ -161,7 +242,7 @@ class Cache { } function getBestYoutubeVideoFormat(formats:Array<YoutubeVideoFormat>):Null<YoutubeVideoFormat> { - final qPriority = [1080, 720, 480, 360, 240]; + final qPriority = [1080, 720, 480, 360, 240, 144]; for (q in qPriority) { final quality = '${q}p'; for (format in formats) { diff --git a/src/server/HttpServer.hx b/src/server/HttpServer.hx index 7622708..6602e86 100644 --- a/src/server/HttpServer.hx +++ b/src/server/HttpServer.hx @@ -1,8 +1,10 @@ package server; +import Types.UploadResponse; +import haxe.Json; import haxe.io.Path; import js.node.Buffer; -import js.node.Fs; +import js.node.Fs.Fs; import js.node.Http; import js.node.Https; import js.node.Path as JsPath; @@ -12,6 +14,14 @@ import js.node.http.ServerResponse; import js.node.url.URL; import sys.FileSystem; +@:structInit +private class HttpServerConfig { + public final dir:String; + public final customDir:String = null; + public final allowLocalRequests = false; + public final cache:Cache = null; +} + class HttpServer { static final mimeTypes = [ "html" => "text/html", @@ -36,31 +46,49 @@ class HttpServer { "wasm" => "application/wasm" ]; - static var dir:String; - static var customDir:String; - static var hasCustomRes = false; - static var allowedLocalFiles:Map<String, Bool> = []; - static var allowLocalRequests = false; - static final CHUNK_SIZE = 1024 * 1024 * 5; // 5 MB + final main:Main; + final dir:String; + final customDir:String; + final hasCustomRes = false; + final allowedLocalFiles:Map<String, Bool> = []; + final allowLocalRequests = false; + final cache:Cache = null; + final CHUNK_SIZE = 1024 * 1024 * 5; // 5 MB + final uploadingFiles:Map<String, Int> = []; + final uploadingFilesLastChunks:Map<String, Buffer> = []; + + public function new(main:Main, config:HttpServerConfig):Void { + this.main = main; + dir = config.dir; + customDir = config.customDir; + allowLocalRequests = config.allowLocalRequests; + cache = config.cache; - public static function init(dir:String, ?customDir:String, allowLocalRequests:Bool):Void { - HttpServer.dir = dir; - if (customDir == null) return; - HttpServer.customDir = customDir; - hasCustomRes = FileSystem.exists(customDir); - HttpServer.allowLocalRequests = allowLocalRequests; + if (customDir != null) hasCustomRes = FileSystem.exists(customDir); } - public static function serveFiles(req:IncomingMessage, res:ServerResponse):Void { + public function serveFiles(req:IncomingMessage, res:ServerResponse):Void { final url = try { new URL(safeDecodeURI(req.url), "http://localhost"); - } catch (e) new URL("/", "http://localhost"); + } catch (e) { + new URL("/", "http://localhost"); + } var filePath = getPath(dir, url); final ext = Path.extension(filePath).toLowerCase(); res.setHeader("Accept-Ranges", "bytes"); res.setHeader("Content-Type", getMimeType(ext)); + if (cache != null && req.method == "POST") { + switch url.pathname { + case "/upload-last-chunk": + uploadFileLastChunk(req, res); + case "/upload": + uploadFile(req, res); + } + return; + } + if (allowLocalRequests && req.socket.remoteAddress == req.socket.localAddress || allowedLocalFiles[url.pathname]) { if (isMediaExtension(ext)) { @@ -103,14 +131,104 @@ class HttpServer { }); } - static function getPath(dir:String, url:URL):String { + function uploadFileLastChunk(req:IncomingMessage, res:ServerResponse) { + final name = cache.getFreeFileName(req.headers["content-name"]); + final filePath = cache.getFilePath(name); + final body:Array<Any> = []; + req.on("data", chunk -> body.push(chunk)); + req.on("end", () -> { + final buffer = Buffer.concat(body); + uploadingFilesLastChunks[filePath] = buffer; + res.writeHead(200, { + 'Content-Type': 'application/json', + }); + final json:UploadResponse = { + info: "File last chunk uploaded" + } + res.end(Json.stringify(json)); + }); + } + + function uploadFile(req:IncomingMessage, res:ServerResponse) { + final name = cache.getFreeFileName(req.headers["content-name"]); + final clientName = req.headers["client-name"]; + final filePath = cache.getFilePath(name); + final size = Std.parseInt(req.headers["content-length"]) ?? return; + var written = 0; + + inline function end(json:UploadResponse):Void { + uploadingFiles.remove(name); + uploadingFilesLastChunks.remove(name); + + res.statusCode = 200; + res.end(Json.stringify(json)); + } + + if (cache.getFreeSpace() < size) { + end({ + info: "Error: Not enough free space on server or file size is out of cache storage limit.", + errorId: "freeSpace" + }); + return; + } + + final stream = Fs.createWriteStream(filePath); + req.pipe(stream); + + inline function onStart() { + cache.removeOlderCache(size); + cache.add(name); + uploadingFiles[filePath] = size; + } + var isStart = true; + req.on("data", chunk -> { + var url:String = null; + if (isStart) { + isStart = false; + onStart(); + url = cache.getFileUrl(name); + } + written += chunk.length; + final ratio = (written / size).clamp(0, 1); + final percent = (ratio * 100).toFixed(2); + final client = main.clients.getByName(clientName) ?? return; + main.send(client, { + type: Progress, + progress: { + type: Uploading, + ratio: ratio, + data: url + } + }); + }); + stream.on("close", () -> { + end({ + info: "File write stream closed.", + }); + }); + stream.on("error", err -> { + trace(err); + end({ + info: "File write stream error.", + }); + }); + req.on("error", err -> { + trace("Request Error:", err); + stream.destroy(); + end({ + info: "File request error.", + }); + }); + } + + function getPath(dir:String, url:URL):String { var filePath = dir + url.pathname; filePath = filePath.urlDecode(); if (!FileSystem.isDirectory(filePath)) return filePath; return Path.addTrailingSlash(filePath) + "index.html"; } - static function readFileError(err:Dynamic, res:ServerResponse, filePath:String):Void { + function readFileError(err:Dynamic, res:ServerResponse, filePath:String):Void { res.setHeader("Content-Type", getMimeType("html")); if (err.code == "ENOENT") { res.statusCode = 404; @@ -122,9 +240,13 @@ class HttpServer { } } - static function serveMedia(req:IncomingMessage, res:ServerResponse, filePath:String):Bool { + function serveMedia(req:IncomingMessage, res:ServerResponse, filePath:String):Bool { if (!Fs.existsSync(filePath)) return false; - final videoSize = Fs.statSync(filePath).size; + var videoSize:Int = cast Fs.statSync(filePath).size; + // use future content length to start playing it before uploaded + if (uploadingFiles.exists(filePath)) { + videoSize = uploadingFiles[filePath]; + } final rangeHeader:String = req.headers["range"]; if (rangeHeader == null) { res.statusCode = 200; @@ -142,23 +264,33 @@ class HttpServer { res.setHeader("Content-Range", 'bytes $start-$end/$videoSize'); res.setHeader("Content-Length", '$contentLength'); - // HTTP Status 206 for Partial Content - res.statusCode = 206; - // create video read stream for this particular chunk - final videoStream = Fs.createReadStream(filePath, {start: cast start, end: cast end}); + res.statusCode = 206; // partial content + + // check for last chunk cache for instant play while uploading + final buffer = uploadingFilesLastChunks[filePath]; + if (buffer != null && end == videoSize - 1 && contentLength < buffer.byteLength) { + final bufferStart = (buffer.byteLength - contentLength).limitMin(0); + res.end(buffer.slice(bufferStart)); + return true; + } + // stream the video chunk to the client + final videoStream = Fs.createReadStream( + filePath, + {start: start, end: end} + ); videoStream.pipe(res); res.on("error", () -> videoStream.destroy()); res.on("close", () -> videoStream.destroy()); return true; } - static function parseRangeHeader(rangeHeader:String, videoSize:Float):{start:Float, end:Float} { + function parseRangeHeader(rangeHeader:String, videoSize:Int):{start:Int, end:Int} { final ranges = ~/[-=]/g.split(rangeHeader); - var start = Std.parseFloat(ranges[1]); + var start = Std.parseInt(ranges[1]); if (Utils.isOutOfRange(start, 0, videoSize - 1)) start = 0; - var end = Std.parseFloat(ranges[2]); - if (Math.isNaN(end)) end = start + CHUNK_SIZE; + var end = Std.parseInt(ranges[2]); + if (end == null) end = start + CHUNK_SIZE; if (Utils.isOutOfRange(end, start, videoSize - 1)) end = videoSize - 1; return { start: start, @@ -166,14 +298,14 @@ class HttpServer { }; } - static function isMediaExtension(ext:String):Bool { + function isMediaExtension(ext:String):Bool { return ext == "mp4" || ext == "webm" || ext == "mp3" || ext == "wav"; } - static final matchLang = ~/^[A-z]+/; - static final matchVarString = ~/\${([A-z_]+)}/g; + final matchLang = ~/^[A-z]+/; + final matchVarString = ~/\${([A-z_]+)}/g; - static function localizeHtml(data:String, lang:String):String { + function localizeHtml(data:String, lang:String):String { if (lang != null && matchLang.match(lang)) { lang = matchLang.matched(0); } else lang = "en"; @@ -184,7 +316,7 @@ class HttpServer { return data; } - static function proxyUrl(req:IncomingMessage, res:ServerResponse):Bool { + function proxyUrl(req:IncomingMessage, res:ServerResponse):Bool { final url = req.url.replace("/proxy?url=", ""); final proxy = proxyRequest(url, req, res, proxyRes -> { final url = proxyRes.headers["location"] ?? return false; @@ -201,7 +333,7 @@ class HttpServer { return true; } - static function proxyRequest( + function proxyRequest( url:String, req:IncomingMessage, res:ServerResponse, @@ -209,7 +341,9 @@ class HttpServer { ):Null<ClientRequest> { final url = try { new URL(safeDecodeURI(url)); - } catch (e) return null; + } catch (e) { + return null; + } if (url.host == req.headers["host"]) return null; final options = { host: url.hostname, @@ -222,7 +356,7 @@ class HttpServer { final request = url.protocol == "https:" ? Https.request : Http.request; final proxy = request(options, proxyRes -> { if (cancelProxyRequest(proxyRes)) return; - proxyRes.headers["Content-Type"] = "application/octet-stream"; + proxyRes.headers["content-type"] = "application/octet-stream"; res.writeHead(proxyRes.statusCode, proxyRes.headers); proxyRes.pipe(res); }); @@ -232,18 +366,18 @@ class HttpServer { return proxy; } - static function isChildOf(parent:String, child:String):Bool { + function isChildOf(parent:String, child:String):Bool { final rel = JsPath.relative(parent, child); return rel.length > 0 && !rel.startsWith('..') && !JsPath.isAbsolute(rel); } - static function getMimeType(ext:String):String { + function getMimeType(ext:String):String { return mimeTypes[ext] ?? return "application/octet-stream"; } - static final ctrlCharacters = ~/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/g; + final ctrlCharacters = ~/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/g; - static function safeDecodeURI(data:String):String { + function safeDecodeURI(data:String):String { try { data = decodeURI(data); } catch (err) { @@ -253,7 +387,7 @@ class HttpServer { return data; } - static inline function decodeURI(data:String):String { + inline function decodeURI(data:String):String { return js.Syntax.code("decodeURI({0})", data); } } diff --git a/src/server/Main.hx b/src/server/Main.hx index c863cce..4f0fd03 100644 --- a/src/server/Main.hx +++ b/src/server/Main.hx @@ -25,8 +25,6 @@ import json2object.JsonParser; import sys.FileSystem; import sys.io.File; -using ClientTools; - private typedef MainOptions = { loadState:Bool } @@ -52,11 +50,14 @@ class Main { final playersCacheSupport:Array<PlayerType> = []; var port:Int; final userList:UserList; - final clients:Array<Client> = []; + + public final clients:Array<Client> = []; + final freeIds:Array<Int> = []; final wsEventParser = new JsonParser<WsEvent>(); final consoleInput:ConsoleInput; final cache:Cache; + final cacheDir:String; final videoList = new VideoList(); final videoTimer = new VideoTimer(); final messages:Array<Message> = []; @@ -84,6 +85,8 @@ class Main { verbose = args.exists("verbose"); statePath = '$rootDir/user/state.json'; logsDir = '$rootDir/user/logs'; + cacheDir = '$rootDir/user/res/cache'; + // process.on("exit", exit); process.on("SIGINT", exit); // ctrl+c process.on("SIGUSR1", exit); // kill pid @@ -100,15 +103,16 @@ class Main { logError("unhandledRejection", reason); exit(); }); + logger = new Logger(logsDir, 10, verbose); consoleInput = new ConsoleInput(this); consoleInput.initConsoleInput(); - cache = new Cache(this, '$rootDir/user/res/cache'); + cache = new Cache(this, cacheDir); if (cache.isYtReady) playersCacheSupport.push(YoutubeType); initIntergationHandlers(); loadState(); config = loadUserConfig(); - cache.storageLimit = cast config.cacheStorageLimitGiB * 1024 * 1024 * 1024; + cache.setStorageLimit(cast config.cacheStorageLimitGiB * 1024 * 1024 * 1024); userList = loadUsers(); config.isVerbose = verbose; config.salt = generateConfigSalt(); @@ -154,11 +158,16 @@ class Main { } final dir = '$rootDir/res'; - HttpServer.init(dir, '$rootDir/user/res', config.localAdmins); + final httpServer = new HttpServer(this, { + dir: dir, + customDir: '$rootDir/user/res', + allowLocalRequests: config.localAdmins, + cache: cache, + }); Lang.init('$dir/langs'); final server = Http.createServer((req, res) -> { - HttpServer.serveFiles(req, res); + httpServer.serveFiles(req, res); }); wss = new WSServer({server: server}); wss.on("connection", onConnect); @@ -330,7 +339,7 @@ class Main { if (isHeroku && process.env["APP_URL"] != null) { var url = process.env["APP_URL"]; if (!url.startsWith("http")) url = 'http://$url'; - new Timer(10 * 60 * 1000).run = function() { + new Timer(10 * 60 * 1000).run = () -> { if (clients.length == 0) return; trace('Ping $url'); Http.get(url, r -> {}); @@ -644,6 +653,7 @@ class Main { broadcast(data); case ServerMessage: + case Progress: case AddVideo: if (isPlaylistLockedFor(client)) return; if (!checkPermission(client, AddVideoPerm)) return; @@ -682,7 +692,7 @@ class Main { addVideo(); } else { cache.cacheYoutubeVideo(client, item.url, (name) -> { - item = item.withUrl('/cache/$name'); + item = item.withUrl(cache.getFileUrl(name)); if (item.duration > 1) item.duration -= 1; addVideo(); }); @@ -973,17 +983,17 @@ class Main { }); } - function send(client:Client, data:WsEvent):Void { + public function send(client:Client, data:WsEvent):Void { client.ws.send(Json.stringify(data), null); } - function broadcast(data:WsEvent):Void { + public function broadcast(data:WsEvent):Void { final json = Json.stringify(data); for (client in clients) client.ws.send(json, null); } - function broadcastExcept(skipped:Client, data:WsEvent):Void { + public function broadcastExcept(skipped:Client, data:WsEvent):Void { final json = Json.stringify(data); for (client in clients) { if (client == skipped) continue; diff --git a/src/server/Utils.hx b/src/server/Utils.hx index 8fcc4c6..eb28115 100644 --- a/src/server/Utils.hx +++ b/src/server/Utils.hx @@ -70,7 +70,7 @@ class Utils { r.setEncoding("utf8"); final data = new StringBuf(); r.on("data", chunk -> data.add(chunk)); - r.on("end", _ -> callback(data.toString())); + r.on("end", () -> callback(data.toString())); }).on("error", onError).on("timeout", onError); } @@ -90,8 +90,8 @@ class Utils { return "127.0.0.1"; } - public static function isOutOfRange(value:Float, min:Float, max:Float):Bool { - return value == null || Math.isNaN(value) || value < min || value > max; + public static function isOutOfRange(value:Int, min:Int, max:Int):Bool { + return value == null || value < min || value > max; } public static function sortedPush(ids:Array<Int>, id:Int):Void { diff --git a/src/tools/MathTools.hx b/src/tools/MathTools.hx new file mode 100644 index 0000000..087748a --- /dev/null +++ b/src/tools/MathTools.hx @@ -0,0 +1,55 @@ +package tools; + +class MathTools { + public static inline function clamp<T:Float>(v:T, min:T, max:T):T { + return v < min ? min : v > max ? max : v; + } + + public static inline function lerp(ratio:Float, a:Float, b:Float):Float { + return a + ratio * (b - a); + } + + public static inline function sign(v:Float):Int { + if (v == 0) return 0; + return v < 0 ? -1 : 1; + } + + public static inline function abs<T:Float>(v:T):T { + return cast Math.abs(v); + } + + public static inline function pow<T:Float>(v:T, exp:T):T { + return cast Math.pow(v, exp); + } + + public static inline function limitMin<T:Float>(a:T, b:T):T { + return a < b ? b : a; + } + + public static inline function limitMax<T:Float>(a:T, b:T):T { + return a > b ? b : a; + } + + public static inline function wrapAround<T:Float>(v:T, min:T, max:T):T { + if (min == max) return min; + final range = max - min + 1; + return min + (((v - min) % range) + range) % range; + } + + public static function toFixed(v:Float, digits = 2):Float { + if (digits > 8) throw 'digits is $digits, but cannot be bigger than 8 (for value $v)'; + final ratio = Math.pow(10, digits); + return Std.int(v * ratio) / ratio; + } + + public static function toBitString(value:Int):String { + var result = ""; + var mask = 1; + for (i in 0...32) { // 32-bit integer + result = (value & mask != 0 ? "1" : "0") + result; + mask <<= 1; + } + final i = result.indexOf("1"); + return i > 0 ? result.substr(i) : result; + } +} diff --git a/src/utils/YoutubeUtils.hx b/src/utils/YoutubeUtils.hx index 0bb8016..9df9a51 100644 --- a/src/utils/YoutubeUtils.hx +++ b/src/utils/YoutubeUtils.hx @@ -46,6 +46,8 @@ typedef YoutubeVideoFormat = { ?container:String, ?videoCodec:String, ?audioCodec:String, + ?hasVideo:Bool, + ?hasAudio:Bool, } typedef YouTubeVideoInfo = { |
