diff options
| -rw-r--r-- | README.md | 10 | ||||
| -rw-r--r-- | build/server.js | 1735 | ||||
| -rw-r--r-- | default-config.json | 1 | ||||
| -rw-r--r-- | res/client.js | 263 | ||||
| -rw-r--r-- | res/css/des.css | 27 | ||||
| -rw-r--r-- | res/index.html | 22 | ||||
| -rw-r--r-- | res/langs/en.json | 4 | ||||
| -rw-r--r-- | res/langs/ru.json | 4 | ||||
| -rw-r--r-- | src/Types.hx | 24 | ||||
| -rw-r--r-- | src/client/Buttons.hx | 34 | ||||
| -rw-r--r-- | src/client/ClientSettings.hx | 3 | ||||
| -rw-r--r-- | src/client/IPlayer.hx | 2 | ||||
| -rw-r--r-- | src/client/JsApi.hx | 5 | ||||
| -rw-r--r-- | src/client/Main.hx | 74 | ||||
| -rw-r--r-- | src/client/Player.hx | 43 | ||||
| -rw-r--r-- | src/client/players/Iframe.hx | 7 | ||||
| -rw-r--r-- | src/client/players/Raw.hx | 5 | ||||
| -rw-r--r-- | src/client/players/Youtube.hx | 55 | ||||
| -rw-r--r-- | src/server/Cache.hx | 165 | ||||
| -rw-r--r-- | src/server/Main.hx | 55 | ||||
| -rw-r--r-- | src/server/ServerState.hx | 3 | ||||
| -rw-r--r-- | src/server/YoutubeFallback.hx | 142 | ||||
| -rw-r--r-- | src/utils/YoutubeUtils.hx | 6 | ||||
| -rw-r--r-- | test/tests/TestServer.hx | 6 |
24 files changed, 1207 insertions, 1488 deletions
@@ -23,7 +23,7 @@ Default channel example: https://synctube.onrender.com/ ### Setup
- Open `4200` port in your router settings (port is customizable)
-- `npm install ws` in this project folder ([NodeJS 14+](https://nodejs.org) required)
+- `npm ci` in this project folder ([NodeJS 14+](https://nodejs.org) required)
- Run `node build/server.js`
- Open showed "Local" link for yourself and send "Global" link to friends
@@ -42,6 +42,14 @@ or - (Docker container hides real local/global ips, so you need to checkout it manually)
+
+### Optional dependencies
+If you want to enable `Cache on server` feature for Youtube player, you can also run:
+```shell
+npm i @distube/ytdl-core@latest
+```
+And install `ffmpeg` on your server system. Default cache size is 3.0 GiB.
+
### Configuration
It's just works, but you can also check [user/ folder](/user/README.md) for server settings and additional customization.
diff --git a/build/server.js b/build/server.js index 2646c9f..12effdf 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 }>, ?getYoutubeVideoInfo : Null<{ url : String, ?response : Null<utils.YouTubeVideoInfo> }>, ?getTime : Null<{ time : Float, ?rate : Null<Float>, ?paused : Null<Bool> }>, ?dump : Null<{ data : String }>, ?connected : Null<{ videoList : Array<VideoItem>, uuid : String, 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 }>, ?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<{ time : Float, ?rate : Null<Float>, ?paused : Null<Bool> }>, ?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","getYoutubeVideoInfo","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,true,false,true,true]); + 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.value = this.getAuto(); var _g = 0; while(_g < o.length) { @@ -553,68 +553,65 @@ JsonParser_$1.prototype = $extend(json2object_reader_BaseParser.prototype,{ case "getTime": this.value.getTime = this.loadObjectField(($_=new JsonParser_$11(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"getTime",assigned,this.value.getTime,pos); break; - case "getYoutubeVideoInfo": - this.value.getYoutubeVideoInfo = this.loadObjectField(($_=new JsonParser_$13(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"getYoutubeVideoInfo",assigned,this.value.getYoutubeVideoInfo,pos); - break; case "kickClient": - this.value.kickClient = this.loadObjectField(($_=new JsonParser_$15(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"kickClient",assigned,this.value.kickClient,pos); + this.value.kickClient = this.loadObjectField(($_=new JsonParser_$13(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"kickClient",assigned,this.value.kickClient,pos); break; case "login": - this.value.login = this.loadObjectField(($_=new JsonParser_$17(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"login",assigned,this.value.login,pos); + this.value.login = this.loadObjectField(($_=new JsonParser_$15(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"login",assigned,this.value.login,pos); break; case "logout": - this.value.logout = this.loadObjectField(($_=new JsonParser_$19(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"logout",assigned,this.value.logout,pos); + this.value.logout = this.loadObjectField(($_=new JsonParser_$17(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"logout",assigned,this.value.logout,pos); break; case "message": - this.value.message = this.loadObjectField(($_=new JsonParser_$21(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"message",assigned,this.value.message,pos); + this.value.message = this.loadObjectField(($_=new JsonParser_$19(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"message",assigned,this.value.message,pos); break; case "pause": - this.value.pause = this.loadObjectField(($_=new JsonParser_$23(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"pause",assigned,this.value.pause,pos); + this.value.pause = this.loadObjectField(($_=new JsonParser_$21(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"pause",assigned,this.value.pause,pos); break; case "play": - this.value.play = this.loadObjectField(($_=new JsonParser_$23(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"play",assigned,this.value.play,pos); + this.value.play = this.loadObjectField(($_=new JsonParser_$21(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"play",assigned,this.value.play,pos); break; case "playItem": - this.value.playItem = this.loadObjectField(($_=new JsonParser_$25(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"playItem",assigned,this.value.playItem,pos); + this.value.playItem = this.loadObjectField(($_=new JsonParser_$23(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"playItem",assigned,this.value.playItem,pos); break; case "removeVideo": - this.value.removeVideo = this.loadObjectField(($_=new JsonParser_$27(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"removeVideo",assigned,this.value.removeVideo,pos); + this.value.removeVideo = this.loadObjectField(($_=new JsonParser_$25(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"removeVideo",assigned,this.value.removeVideo,pos); break; case "rewind": - this.value.rewind = this.loadObjectField(($_=new JsonParser_$23(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"rewind",assigned,this.value.rewind,pos); + this.value.rewind = this.loadObjectField(($_=new JsonParser_$21(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"rewind",assigned,this.value.rewind,pos); break; case "serverMessage": - this.value.serverMessage = this.loadObjectField(($_=new JsonParser_$29(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"serverMessage",assigned,this.value.serverMessage,pos); + this.value.serverMessage = this.loadObjectField(($_=new JsonParser_$27(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"serverMessage",assigned,this.value.serverMessage,pos); break; case "setLeader": - this.value.setLeader = this.loadObjectField(($_=new JsonParser_$31(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"setLeader",assigned,this.value.setLeader,pos); + this.value.setLeader = this.loadObjectField(($_=new JsonParser_$29(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"setLeader",assigned,this.value.setLeader,pos); break; case "setNextItem": - this.value.setNextItem = this.loadObjectField(($_=new JsonParser_$25(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"setNextItem",assigned,this.value.setNextItem,pos); + this.value.setNextItem = this.loadObjectField(($_=new JsonParser_$23(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"setNextItem",assigned,this.value.setNextItem,pos); break; case "setRate": - this.value.setRate = this.loadObjectField(($_=new JsonParser_$33(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"setRate",assigned,this.value.setRate,pos); + this.value.setRate = this.loadObjectField(($_=new JsonParser_$31(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"setRate",assigned,this.value.setRate,pos); break; case "setTime": - this.value.setTime = this.loadObjectField(($_=new JsonParser_$23(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"setTime",assigned,this.value.setTime,pos); + this.value.setTime = this.loadObjectField(($_=new JsonParser_$21(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"setTime",assigned,this.value.setTime,pos); break; case "skipVideo": - this.value.skipVideo = this.loadObjectField(($_=new JsonParser_$27(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"skipVideo",assigned,this.value.skipVideo,pos); + this.value.skipVideo = this.loadObjectField(($_=new JsonParser_$25(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"skipVideo",assigned,this.value.skipVideo,pos); break; case "toggleItemType": - this.value.toggleItemType = this.loadObjectField(($_=new JsonParser_$25(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"toggleItemType",assigned,this.value.toggleItemType,pos); + this.value.toggleItemType = this.loadObjectField(($_=new JsonParser_$23(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"toggleItemType",assigned,this.value.toggleItemType,pos); break; case "togglePlaylistLock": - this.value.togglePlaylistLock = this.loadObjectField(($_=new JsonParser_$35(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"togglePlaylistLock",assigned,this.value.togglePlaylistLock,pos); + this.value.togglePlaylistLock = this.loadObjectField(($_=new JsonParser_$33(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"togglePlaylistLock",assigned,this.value.togglePlaylistLock,pos); break; case "type": - this.value.type = this.loadObjectField(($_=new JsonParser_$36(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"type",assigned,this.value.type,pos); + this.value.type = this.loadObjectField(($_=new JsonParser_$34(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"type",assigned,this.value.type,pos); break; case "updateClients": - this.value.updateClients = this.loadObjectField(($_=new JsonParser_$38(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"updateClients",assigned,this.value.updateClients,pos); + this.value.updateClients = this.loadObjectField(($_=new JsonParser_$36(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"updateClients",assigned,this.value.updateClients,pos); break; case "updatePlaylist": - this.value.updatePlaylist = this.loadObjectField(($_=new JsonParser_$40(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"updatePlaylist",assigned,this.value.updatePlaylist,pos); + this.value.updatePlaylist = this.loadObjectField(($_=new JsonParser_$38(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))); @@ -623,7 +620,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_$11([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), getYoutubeVideoInfo : new JsonParser_$13([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), kickClient : new JsonParser_$15([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), login : new JsonParser_$17([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), logout : new JsonParser_$19([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), message : new JsonParser_$21([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), pause : new JsonParser_$23([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), play : new JsonParser_$23([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), playItem : new JsonParser_$25([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), removeVideo : new JsonParser_$27([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), rewind : new JsonParser_$23([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), serverMessage : new JsonParser_$29([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), setLeader : new JsonParser_$31([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), setNextItem : new JsonParser_$25([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), setRate : new JsonParser_$33([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), setTime : new JsonParser_$23([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), skipVideo : new JsonParser_$27([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), toggleItemType : new JsonParser_$25([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), togglePlaylistLock : new JsonParser_$35([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), type : new JsonParser_$36([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), updateClients : new JsonParser_$38([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), updatePlaylist : new JsonParser_$40([],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_$11([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), kickClient : new JsonParser_$13([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), login : new JsonParser_$15([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), logout : new JsonParser_$17([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), message : new JsonParser_$19([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), pause : new JsonParser_$21([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), play : new JsonParser_$21([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), playItem : new JsonParser_$23([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), removeVideo : new JsonParser_$25([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), rewind : new JsonParser_$21([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), serverMessage : new JsonParser_$27([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), setLeader : new JsonParser_$29([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), setNextItem : new JsonParser_$23([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), setRate : new JsonParser_$31([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), setTime : new JsonParser_$21([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), skipVideo : new JsonParser_$25([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), toggleItemType : new JsonParser_$23([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), togglePlaylistLock : new JsonParser_$33([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), type : new JsonParser_$34([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), updateClients : new JsonParser_$36([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), updatePlaylist : new JsonParser_$38([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$1 }); @@ -653,13 +650,13 @@ JsonParser_$11.prototype = $extend(json2object_reader_BaseParser.prototype,{ ++_g; switch(field.name) { case "paused": - this.value.paused = this.loadObjectField(($_=new JsonParser_$56(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"paused",assigned,this.value.paused,pos); + this.value.paused = this.loadObjectField(($_=new JsonParser_$55(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"paused",assigned,this.value.paused,pos); break; case "rate": - this.value.rate = this.loadObjectField(($_=new JsonParser_$79(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"rate",assigned,this.value.rate,pos); + this.value.rate = this.loadObjectField(($_=new JsonParser_$57(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"rate",assigned,this.value.rate,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_$44(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 +665,7 @@ JsonParser_$11.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { paused : new JsonParser_$56([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), rate : new JsonParser_$79([],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)))}; + return { paused : new JsonParser_$55([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), rate : new JsonParser_$57([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), time : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$11 }); @@ -682,7 +679,7 @@ JsonParser_$13.__name__ = true; JsonParser_$13.__super__ = json2object_reader_BaseParser; JsonParser_$13.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { - this.errors.push(json2object_Error.IncorrectType(variable,"{ url : String, ?response : Null<utils.YouTubeVideoInfo> }",pos)); + this.errors.push(json2object_Error.IncorrectType(variable,"{ name : String }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } ,loadJsonNull: function(pos,variable) { @@ -690,27 +687,22 @@ JsonParser_$13.prototype = $extend(json2object_reader_BaseParser.prototype,{ } ,loadJsonObject: function(o,pos,variable) { var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["response","url"],[true,false]); + this.objectSetupAssign(assigned,["name"],[false]); this.value = this.getAuto(); var _g = 0; while(_g < o.length) { var field = o[_g]; ++_g; - switch(field.name) { - case "response": - this.value.response = this.loadObjectField(($_=new JsonParser_$59(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"response",assigned,this.value.response,pos); - break; - case "url": - this.value.url = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"url",assigned,this.value.url,pos); - break; - default: + if(field.name == "name") { + this.value.name = this.loadObjectField(($_=new JsonParser_$42(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))); } } this.objectErrors(assigned,pos); } ,getAuto: function() { - return { response : new JsonParser_$59([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), url : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { name : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$13 }); @@ -724,7 +716,7 @@ JsonParser_$15.__name__ = true; JsonParser_$15.__super__ = json2object_reader_BaseParser; JsonParser_$15.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { - this.errors.push(json2object_Error.IncorrectType(variable,"{ name : String }",pos)); + this.errors.push(json2object_Error.IncorrectType(variable,"{ ?passHash : Null<String>, ?isUnknownClient : Null<Bool>, ?clients : Null<Array<ClientData>>, clientName : String }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } ,loadJsonNull: function(pos,variable) { @@ -732,22 +724,33 @@ JsonParser_$15.prototype = $extend(json2object_reader_BaseParser.prototype,{ } ,loadJsonObject: function(o,pos,variable) { var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["name"],[false]); + this.objectSetupAssign(assigned,["clientName","clients","isUnknownClient","passHash"],[false,true,true,true]); this.value = this.getAuto(); var _g = 0; while(_g < o.length) { var field = o[_g]; ++_g; - if(field.name == "name") { - this.value.name = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"name",assigned,this.value.name,pos); - } else { + switch(field.name) { + case "clientName": + this.value.clientName = this.loadObjectField(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clientName",assigned,this.value.clientName,pos); + break; + case "clients": + this.value.clients = this.loadObjectField(($_=new JsonParser_$53(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clients",assigned,this.value.clients,pos); + break; + case "isUnknownClient": + this.value.isUnknownClient = this.loadObjectField(($_=new JsonParser_$55(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isUnknownClient",assigned,this.value.isUnknownClient,pos); + break; + case "passHash": + this.value.passHash = this.loadObjectField(($_=new JsonParser_$47(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))); } } this.objectErrors(assigned,pos); } ,getAuto: function() { - return { name : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { clientName : new JsonParser_$42([],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))), isUnknownClient : new JsonParser_$55([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), passHash : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$15 }); @@ -761,7 +764,7 @@ JsonParser_$17.__name__ = true; JsonParser_$17.__super__ = json2object_reader_BaseParser; JsonParser_$17.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { - this.errors.push(json2object_Error.IncorrectType(variable,"{ ?passHash : Null<String>, ?isUnknownClient : Null<Bool>, ?clients : Null<Array<ClientData>>, clientName : String }",pos)); + this.errors.push(json2object_Error.IncorrectType(variable,"{ oldClientName : String, clients : Array<ClientData>, clientName : String }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } ,loadJsonNull: function(pos,variable) { @@ -769,7 +772,7 @@ JsonParser_$17.prototype = $extend(json2object_reader_BaseParser.prototype,{ } ,loadJsonObject: function(o,pos,variable) { var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["clientName","clients","isUnknownClient","passHash"],[false,true,true,true]); + this.objectSetupAssign(assigned,["clientName","clients","oldClientName"],[false,false,false]); this.value = this.getAuto(); var _g = 0; while(_g < o.length) { @@ -777,16 +780,13 @@ JsonParser_$17.prototype = $extend(json2object_reader_BaseParser.prototype,{ ++_g; switch(field.name) { case "clientName": - this.value.clientName = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clientName",assigned,this.value.clientName,pos); + this.value.clientName = this.loadObjectField(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clientName",assigned,this.value.clientName,pos); break; case "clients": - this.value.clients = this.loadObjectField(($_=new JsonParser_$54(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clients",assigned,this.value.clients,pos); + this.value.clients = this.loadObjectField(($_=new JsonParser_$48(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clients",assigned,this.value.clients,pos); break; - case "isUnknownClient": - this.value.isUnknownClient = this.loadObjectField(($_=new JsonParser_$56(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isUnknownClient",assigned,this.value.isUnknownClient,pos); - break; - case "passHash": - this.value.passHash = this.loadObjectField(($_=new JsonParser_$48(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"passHash",assigned,this.value.passHash,pos); + case "oldClientName": + this.value.oldClientName = this.loadObjectField(($_=new JsonParser_$42(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))); @@ -795,7 +795,7 @@ JsonParser_$17.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { clientName : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), clients : new JsonParser_$54([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isUnknownClient : new JsonParser_$56([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), passHash : new JsonParser_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { clientName : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), clients : new JsonParser_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), oldClientName : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$17 }); @@ -809,7 +809,7 @@ JsonParser_$19.__name__ = true; JsonParser_$19.__super__ = json2object_reader_BaseParser; JsonParser_$19.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { - this.errors.push(json2object_Error.IncorrectType(variable,"{ oldClientName : String, clients : Array<ClientData>, clientName : String }",pos)); + this.errors.push(json2object_Error.IncorrectType(variable,"{ text : String, clientName : String }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } ,loadJsonNull: function(pos,variable) { @@ -817,7 +817,7 @@ JsonParser_$19.prototype = $extend(json2object_reader_BaseParser.prototype,{ } ,loadJsonObject: function(o,pos,variable) { var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["clientName","clients","oldClientName"],[false,false,false]); + this.objectSetupAssign(assigned,["clientName","text"],[false,false]); this.value = this.getAuto(); var _g = 0; while(_g < o.length) { @@ -825,13 +825,10 @@ JsonParser_$19.prototype = $extend(json2object_reader_BaseParser.prototype,{ ++_g; switch(field.name) { case "clientName": - this.value.clientName = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clientName",assigned,this.value.clientName,pos); + this.value.clientName = this.loadObjectField(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clientName",assigned,this.value.clientName,pos); break; - case "clients": - this.value.clients = this.loadObjectField(($_=new JsonParser_$49(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clients",assigned,this.value.clients,pos); - break; - case "oldClientName": - this.value.oldClientName = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"oldClientName",assigned,this.value.oldClientName,pos); + case "text": + this.value.text = this.loadObjectField(($_=new JsonParser_$42(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 +837,7 @@ JsonParser_$19.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { clientName : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), clients : new JsonParser_$49([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), oldClientName : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { clientName : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), text : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$19 }); @@ -854,7 +851,7 @@ JsonParser_$21.__name__ = true; JsonParser_$21.__super__ = json2object_reader_BaseParser; JsonParser_$21.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { - this.errors.push(json2object_Error.IncorrectType(variable,"{ text : String, clientName : String }",pos)); + this.errors.push(json2object_Error.IncorrectType(variable,"{ time : Float }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } ,loadJsonNull: function(pos,variable) { @@ -862,27 +859,22 @@ JsonParser_$21.prototype = $extend(json2object_reader_BaseParser.prototype,{ } ,loadJsonObject: function(o,pos,variable) { var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["clientName","text"],[false,false]); + this.objectSetupAssign(assigned,["time"],[false]); this.value = this.getAuto(); var _g = 0; while(_g < o.length) { var field = o[_g]; ++_g; - switch(field.name) { - case "clientName": - this.value.clientName = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clientName",assigned,this.value.clientName,pos); - break; - case "text": - this.value.text = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"text",assigned,this.value.text,pos); - break; - default: + if(field.name == "time") { + this.value.time = this.loadObjectField(($_=new JsonParser_$44(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))); } } this.objectErrors(assigned,pos); } ,getAuto: function() { - return { clientName : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), text : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { time : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$21 }); @@ -896,7 +888,7 @@ JsonParser_$23.__name__ = true; JsonParser_$23.__super__ = json2object_reader_BaseParser; JsonParser_$23.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { - this.errors.push(json2object_Error.IncorrectType(variable,"{ time : Float }",pos)); + this.errors.push(json2object_Error.IncorrectType(variable,"{ pos : Int }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } ,loadJsonNull: function(pos,variable) { @@ -904,14 +896,14 @@ JsonParser_$23.prototype = $extend(json2object_reader_BaseParser.prototype,{ } ,loadJsonObject: function(o,pos,variable) { var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["time"],[false]); + this.objectSetupAssign(assigned,["pos"],[false]); this.value = this.getAuto(); var _g = 0; while(_g < o.length) { var field = o[_g]; ++_g; - if(field.name == "time") { - this.value.time = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"time",assigned,this.value.time,pos); + if(field.name == "pos") { + this.value.pos = this.loadObjectField(($_=new JsonParser_$51(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))); } @@ -919,7 +911,7 @@ JsonParser_$23.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { time : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { pos : new JsonParser_$51([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$23 }); @@ -933,7 +925,7 @@ JsonParser_$25.__name__ = true; JsonParser_$25.__super__ = json2object_reader_BaseParser; JsonParser_$25.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { - this.errors.push(json2object_Error.IncorrectType(variable,"{ pos : Int }",pos)); + this.errors.push(json2object_Error.IncorrectType(variable,"{ url : String }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } ,loadJsonNull: function(pos,variable) { @@ -941,14 +933,14 @@ JsonParser_$25.prototype = $extend(json2object_reader_BaseParser.prototype,{ } ,loadJsonObject: function(o,pos,variable) { var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["pos"],[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 == "pos") { - this.value.pos = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"pos",assigned,this.value.pos,pos); + if(field.name == "url") { + this.value.url = this.loadObjectField(($_=new JsonParser_$42(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))); } @@ -956,7 +948,7 @@ JsonParser_$25.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { pos : new JsonParser_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { url : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$25 }); @@ -970,7 +962,7 @@ JsonParser_$27.__name__ = true; JsonParser_$27.__super__ = json2object_reader_BaseParser; JsonParser_$27.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,"{ textId : String }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } ,loadJsonNull: function(pos,variable) { @@ -978,14 +970,14 @@ JsonParser_$27.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,["textId"],[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_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"url",assigned,this.value.url,pos); + if(field.name == "textId") { + this.value.textId = this.loadObjectField(($_=new JsonParser_$42(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))); } @@ -993,7 +985,7 @@ JsonParser_$27.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { url : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { textId : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$27 }); @@ -1007,7 +999,7 @@ JsonParser_$29.__name__ = true; JsonParser_$29.__super__ = json2object_reader_BaseParser; JsonParser_$29.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,"{ clientName : String }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } ,loadJsonNull: function(pos,variable) { @@ -1015,14 +1007,14 @@ JsonParser_$29.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,["clientName"],[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_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"textId",assigned,this.value.textId,pos); + if(field.name == "clientName") { + this.value.clientName = this.loadObjectField(($_=new JsonParser_$42(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))); } @@ -1030,7 +1022,7 @@ JsonParser_$29.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { textId : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { clientName : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$29 }); @@ -1060,10 +1052,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_$43(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"atEnd",assigned,this.value.atEnd,pos); break; case "item": - this.value.item = this.loadObjectField(($_=new JsonParser_$43(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"item",assigned,this.value.item,pos); + this.value.item = this.loadObjectField(($_=new JsonParser_$41(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))); @@ -1072,7 +1064,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_$43([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { atEnd : new JsonParser_$43([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), item : new JsonParser_$41([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$3 }); @@ -1086,7 +1078,7 @@ JsonParser_$31.__name__ = true; JsonParser_$31.__super__ = json2object_reader_BaseParser; JsonParser_$31.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,"{ rate : Float }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } ,loadJsonNull: function(pos,variable) { @@ -1094,14 +1086,14 @@ JsonParser_$31.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,["rate"],[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_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clientName",assigned,this.value.clientName,pos); + if(field.name == "rate") { + this.value.rate = this.loadObjectField(($_=new JsonParser_$44(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))); } @@ -1109,7 +1101,7 @@ JsonParser_$31.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { clientName : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { rate : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$31 }); @@ -1123,43 +1115,6 @@ JsonParser_$33.__name__ = true; JsonParser_$33.__super__ = json2object_reader_BaseParser; JsonParser_$33.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_$45(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_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; - } - ,__class__: JsonParser_$33 -}); -var JsonParser_$35 = 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,{ - onIncorrectType: function(pos,variable) { this.errors.push(json2object_Error.IncorrectType(variable,"{ isOpen : Bool }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } @@ -1175,7 +1130,7 @@ JsonParser_$35.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_$43(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))); } @@ -1183,19 +1138,19 @@ JsonParser_$35.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_$43([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,__class__: JsonParser_$35 + ,__class__: JsonParser_$33 }); -var JsonParser_$36 = function(errors,putils,errorType) { +var JsonParser_$34 = 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,{ +JsonParser_$34.__name__ = true; +JsonParser_$34.__super__ = json2object_reader_BaseParser; +JsonParser_$34.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { this.value = "Connected"; this.errors.push(json2object_Error.IncorrectType(variable,"WsEventType",pos)); @@ -1205,19 +1160,19 @@ JsonParser_$36.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","GetYoutubeVideoInfo"],"Connected"); + 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"); } - ,__class__: JsonParser_$36 + ,__class__: JsonParser_$34 }); -var JsonParser_$38 = function(errors,putils,errorType) { +var JsonParser_$36 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$38.__name__ = true; -JsonParser_$38.__super__ = json2object_reader_BaseParser; -JsonParser_$38.prototype = $extend(json2object_reader_BaseParser.prototype,{ +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,"{ clients : Array<ClientData> }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1234,7 +1189,7 @@ JsonParser_$38.prototype = $extend(json2object_reader_BaseParser.prototype,{ var field = o[_g]; ++_g; if(field.name == "clients") { - this.value.clients = this.loadObjectField(($_=new JsonParser_$49(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clients",assigned,this.value.clients,pos); + this.value.clients = this.loadObjectField(($_=new JsonParser_$48(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))); } @@ -1242,19 +1197,19 @@ JsonParser_$38.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { clients : new JsonParser_$49([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { clients : new JsonParser_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,__class__: JsonParser_$38 + ,__class__: JsonParser_$36 }); -var JsonParser_$40 = function(errors,putils,errorType) { +var JsonParser_$38 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$40.__name__ = true; -JsonParser_$40.__super__ = json2object_reader_BaseParser; -JsonParser_$40.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$38.__name__ = true; +JsonParser_$38.__super__ = json2object_reader_BaseParser; +JsonParser_$38.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); @@ -1271,7 +1226,7 @@ JsonParser_$40.prototype = $extend(json2object_reader_BaseParser.prototype,{ var field = o[_g]; ++_g; if(field.name == "videoList") { - this.value.videoList = this.loadObjectField(($_=new JsonParser_$41(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"videoList",assigned,this.value.videoList,pos); + this.value.videoList = this.loadObjectField(($_=new JsonParser_$39(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))); } @@ -1279,19 +1234,19 @@ JsonParser_$40.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { videoList : new JsonParser_$41([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { videoList : new JsonParser_$39([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,__class__: JsonParser_$40 + ,__class__: JsonParser_$38 }); -var JsonParser_$41 = 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_$41.__name__ = true; -JsonParser_$41.__super__ = json2object_reader_BaseParser; -JsonParser_$41.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,"Array<VideoItem>",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1300,21 +1255,21 @@ JsonParser_$41.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.value = null; } ,loadJsonArray: function(a,pos,variable) { - this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$43(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); + this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$41(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); } - ,__class__: JsonParser_$41 + ,__class__: JsonParser_$39 }); -var JsonParser_$43 = 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_$43.__name__ = true; -JsonParser_$43.__super__ = json2object_reader_BaseParser; -JsonParser_$43.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,"{ ?voiceOverTrack : Null<String>, url : String, title : String, ?subs : Null<String>, isTemp : Bool, isIframe : Bool, duration : Float, author : String }",pos)); + 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); } ,loadJsonNull: function(pos,variable) { @@ -1322,7 +1277,7 @@ JsonParser_$43.prototype = $extend(json2object_reader_BaseParser.prototype,{ } ,loadJsonObject: function(o,pos,variable) { var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["author","duration","isIframe","isTemp","subs","title","url","voiceOverTrack"],[false,false,false,false,true,false,false,true]); + this.objectSetupAssign(assigned,["author","doCache","duration","isTemp","playerType","subs","title","url","voiceOverTrack"],[false,false,false,false,false,true,false,false,true]); this.value = this.getAuto(); var _g = 0; while(_g < o.length) { @@ -1330,28 +1285,31 @@ JsonParser_$43.prototype = $extend(json2object_reader_BaseParser.prototype,{ ++_g; switch(field.name) { case "author": - this.value.author = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"author",assigned,this.value.author,pos); + this.value.author = this.loadObjectField(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"author",assigned,this.value.author,pos); break; - case "duration": - this.value.duration = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"duration",assigned,this.value.duration,pos); + case "doCache": + this.value.doCache = this.loadObjectField(($_=new JsonParser_$43(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"doCache",assigned,this.value.doCache,pos); break; - case "isIframe": - this.value.isIframe = this.loadObjectField(($_=new JsonParser_$46(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isIframe",assigned,this.value.isIframe,pos); + case "duration": + this.value.duration = this.loadObjectField(($_=new JsonParser_$44(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_$43(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isTemp",assigned,this.value.isTemp,pos); + break; + case "playerType": + this.value.playerType = this.loadObjectField(($_=new JsonParser_$45(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"playerType",assigned,this.value.playerType,pos); break; case "subs": - this.value.subs = this.loadObjectField(($_=new JsonParser_$48(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"subs",assigned,this.value.subs,pos); + this.value.subs = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"subs",assigned,this.value.subs,pos); break; case "title": - this.value.title = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"title",assigned,this.value.title,pos); + this.value.title = this.loadObjectField(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"title",assigned,this.value.title,pos); break; case "url": - this.loadObjectFieldReflect(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"url",assigned,pos); + this.loadObjectFieldReflect(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"url",assigned,pos); break; case "voiceOverTrack": - this.value.voiceOverTrack = this.loadObjectField(($_=new JsonParser_$48(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"voiceOverTrack",assigned,this.value.voiceOverTrack,pos); + this.value.voiceOverTrack = this.loadObjectField(($_=new JsonParser_$47(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))); @@ -1360,19 +1318,19 @@ JsonParser_$43.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { author : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), duration : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isIframe : new JsonParser_$46([],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))), subs : new JsonParser_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), title : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), url : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), voiceOverTrack : new JsonParser_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { author : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), doCache : new JsonParser_$43([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), duration : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isTemp : new JsonParser_$43([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), playerType : new JsonParser_$45([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), subs : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), title : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), url : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), voiceOverTrack : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,__class__: JsonParser_$43 + ,__class__: JsonParser_$41 }); -var JsonParser_$44 = function(errors,putils,errorType) { +var JsonParser_$42 = 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_$42.__name__ = true; +JsonParser_$42.__super__ = json2object_reader_BaseParser; +JsonParser_$42.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); @@ -1383,18 +1341,37 @@ JsonParser_$44.prototype = $extend(json2object_reader_BaseParser.prototype,{ ,loadJsonString: function(s,pos,variable) { this.value = s; } - ,__class__: JsonParser_$44 + ,__class__: JsonParser_$42 }); -var JsonParser_$45 = function(errors,putils,errorType) { +var JsonParser_$43 = function(errors,putils,errorType) { + if(errorType == null) { + errorType = 0; + } + json2object_reader_BaseParser.call(this,errors,putils,errorType); + this.value = false; +}; +JsonParser_$43.__name__ = true; +JsonParser_$43.__super__ = json2object_reader_BaseParser; +JsonParser_$43.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); + } + ,loadJsonBool: function(b,pos,variable) { + this.value = b; + } + ,__class__: JsonParser_$43 +}); +var JsonParser_$44 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); this.value = 0; }; -JsonParser_$45.__name__ = true; -JsonParser_$45.__super__ = json2object_reader_BaseParser; -JsonParser_$45.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,"Float",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1402,36 +1379,39 @@ JsonParser_$45.prototype = $extend(json2object_reader_BaseParser.prototype,{ ,loadJsonNumber: function(f,pos,variable) { this.value = this.loadJsonFloat(f,pos,variable,this.value); } - ,__class__: JsonParser_$45 + ,__class__: JsonParser_$44 }); -var JsonParser_$46 = function(errors,putils,errorType) { +var JsonParser_$45 = 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_$45.__name__ = true; +JsonParser_$45.__super__ = json2object_reader_BaseParser; +JsonParser_$45.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); + this.value = "RawType"; + this.errors.push(json2object_Error.IncorrectType(variable,"PlayerType",pos)); + this.objectThrow(pos,variable); } - ,loadJsonBool: function(b,pos,variable) { - this.value = b; + ,loadJsonNull: function(pos,variable) { + this.value = null; } - ,__class__: JsonParser_$46 + ,loadJsonString: function(s,pos,variable) { + this.value = this.loadString(s,pos,variable,["RawType","YoutubeType","IframeType"],"RawType"); + } + ,__class__: JsonParser_$45 }); -var JsonParser_$48 = 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_$48.__name__ = true; -JsonParser_$48.__super__ = json2object_reader_BaseParser; -JsonParser_$48.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); @@ -1442,17 +1422,17 @@ JsonParser_$48.prototype = $extend(json2object_reader_BaseParser.prototype,{ ,loadJsonString: function(s,pos,variable) { this.value = s; } - ,__class__: JsonParser_$48 + ,__class__: JsonParser_$47 }); -var JsonParser_$49 = function(errors,putils,errorType) { +var JsonParser_$48 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$49.__name__ = true; -JsonParser_$49.__super__ = json2object_reader_BaseParser; -JsonParser_$49.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,"Array<ClientData>",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1461,9 +1441,9 @@ JsonParser_$49.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.value = null; } ,loadJsonArray: function(a,pos,variable) { - this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$51(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_$49 + ,__class__: JsonParser_$48 }); var JsonParser_$5 = function(errors,putils,errorType) { if(errorType == null) { @@ -1491,10 +1471,10 @@ JsonParser_$5.prototype = $extend(json2object_reader_BaseParser.prototype,{ ++_g; switch(field.name) { case "name": - this.value.name = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"name",assigned,this.value.name,pos); + this.value.name = this.loadObjectField(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"name",assigned,this.value.name,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_$44(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))); @@ -1503,19 +1483,19 @@ JsonParser_$5.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { name : new JsonParser_$44([],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)))}; + return { name : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), time : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$5 }); -var JsonParser_$51 = function(errors,putils,errorType) { +var JsonParser_$50 = 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_$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,"{ name : String, group : Int }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1533,10 +1513,10 @@ JsonParser_$51.prototype = $extend(json2object_reader_BaseParser.prototype,{ ++_g; switch(field.name) { case "group": - this.value.group = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"group",assigned,this.value.group,pos); + this.value.group = this.loadObjectField(($_=new JsonParser_$51(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"group",assigned,this.value.group,pos); break; case "name": - this.value.name = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"name",assigned,this.value.name,pos); + this.value.name = this.loadObjectField(($_=new JsonParser_$42(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))); @@ -1545,20 +1525,20 @@ JsonParser_$51.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { group : new JsonParser_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), name : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { group : new JsonParser_$51([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), name : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,__class__: JsonParser_$51 + ,__class__: JsonParser_$50 }); -var JsonParser_$52 = function(errors,putils,errorType) { +var JsonParser_$51 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); this.value = 0; }; -JsonParser_$52.__name__ = true; -JsonParser_$52.__super__ = json2object_reader_BaseParser; -JsonParser_$52.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$51.__name__ = true; +JsonParser_$51.__super__ = json2object_reader_BaseParser; +JsonParser_$51.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); @@ -1566,17 +1546,17 @@ JsonParser_$52.prototype = $extend(json2object_reader_BaseParser.prototype,{ ,loadJsonNumber: function(f,pos,variable) { this.value = this.loadJsonInt(f,pos,variable,this.value); } - ,__class__: JsonParser_$52 + ,__class__: JsonParser_$51 }); -var JsonParser_$54 = function(errors,putils,errorType) { +var JsonParser_$53 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$54.__name__ = true; -JsonParser_$54.__super__ = json2object_reader_BaseParser; -JsonParser_$54.prototype = $extend(json2object_reader_BaseParser.prototype,{ +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); @@ -1585,19 +1565,19 @@ JsonParser_$54.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.value = null; } ,loadJsonArray: function(a,pos,variable) { - this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$51(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_$54 + ,__class__: JsonParser_$53 }); -var JsonParser_$56 = function(errors,putils,errorType) { +var JsonParser_$55 = 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_$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,"Bool",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); @@ -1608,125 +1588,40 @@ JsonParser_$56.prototype = $extend(json2object_reader_BaseParser.prototype,{ ,loadJsonBool: function(b,pos,variable) { this.value = b; } - ,__class__: JsonParser_$56 + ,__class__: JsonParser_$55 }); -var JsonParser_$59 = 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_$59.__name__ = true; -JsonParser_$59.__super__ = json2object_reader_BaseParser; -JsonParser_$59.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.errors.push(json2object_Error.IncorrectType(variable,"{ videoDetails : utils.YoutubeVideoDetails, ?liveData : Null<{ manifestUrl : String }>, ?formats : Null<Array<utils.YoutubeVideoFormat>>, ?adaptiveFormats : Null<Array<utils.YoutubeVideoFormat>> }",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,["adaptiveFormats","formats","liveData","videoDetails"],[true,true,true,false]); - this.value = this.getAuto(); - var _g = 0; - while(_g < o.length) { - var field = o[_g]; - ++_g; - switch(field.name) { - case "adaptiveFormats": - this.value.adaptiveFormats = this.loadObjectField(($_=new JsonParser_$63(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"adaptiveFormats",assigned,this.value.adaptiveFormats,pos); - break; - case "formats": - this.value.formats = this.loadObjectField(($_=new JsonParser_$63(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"formats",assigned,this.value.formats,pos); - break; - case "liveData": - this.value.liveData = this.loadObjectField(($_=new JsonParser_$65(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"liveData",assigned,this.value.liveData,pos); - break; - case "videoDetails": - this.value.videoDetails = this.loadObjectField(($_=new JsonParser_$67(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"videoDetails",assigned,this.value.videoDetails,pos); - break; - default: - this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); - } - } - this.objectErrors(assigned,pos); - } - ,getAuto: function() { - return { adaptiveFormats : new JsonParser_$63([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), formats : new JsonParser_$63([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), liveData : new JsonParser_$65([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), videoDetails : new JsonParser_$67([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; - } - ,__class__: JsonParser_$59 -}); -var JsonParser_$63 = 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,{ - onIncorrectType: function(pos,variable) { - this.errors.push(json2object_Error.IncorrectType(variable,"Array<utils.YoutubeVideoFormat>",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_$73(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); - } - ,__class__: JsonParser_$63 -}); -var JsonParser_$65 = function(errors,putils,errorType) { - if(errorType == null) { - errorType = 0; - } - json2object_reader_BaseParser.call(this,errors,putils,errorType); -}; -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,"{ manifestUrl : String }",pos)); + this.errors.push(json2object_Error.IncorrectType(variable,"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,["manifestUrl"],[false]); - this.value = this.getAuto(); - var _g = 0; - while(_g < o.length) { - var field = o[_g]; - ++_g; - if(field.name == "manifestUrl") { - this.value.manifestUrl = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"manifestUrl",assigned,this.value.manifestUrl,pos); - } else { - this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); - } - } - this.objectErrors(assigned,pos); - } - ,getAuto: function() { - return { manifestUrl : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + ,loadJsonNumber: function(f,pos,variable) { + this.value = this.loadJsonFloat(f,pos,variable,this.value); } - ,__class__: JsonParser_$65 + ,__class__: JsonParser_$57 }); -var JsonParser_$67 = function(errors,putils,errorType) { +var JsonParser_$59 = 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,{ +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,"{ viewCount : String, videoId : String, title : String, thumbnail : { thumbnails : Array<{ width : Int, url : String, height : Int }> }, shortDescription : String, lengthSeconds : String, keywords : Array<String>, isUnpluggedCorpus : Bool, isPrivate : Bool, isOwnerViewing : Bool, isLiveContent : Bool, isCrawlable : Bool, channelId : String, author : String, allowRatings : Bool }",pos)); + this.errors.push(json2object_Error.IncorrectType(variable,"{ youtubePlaylistLimit : Int, youtubeApiKey : String, userVideoLimit : Int, 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); } ,loadJsonNull: function(pos,variable) { @@ -1734,57 +1629,72 @@ JsonParser_$67.prototype = $extend(json2object_reader_BaseParser.prototype,{ } ,loadJsonObject: function(o,pos,variable) { var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["allowRatings","author","channelId","isCrawlable","isLiveContent","isOwnerViewing","isPrivate","isUnpluggedCorpus","keywords","lengthSeconds","shortDescription","thumbnail","title","videoId","viewCount"],[false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]); + this.objectSetupAssign(assigned,["allowProxyIps","cacheStorageLimitGiB","channelName","emotes","filters","isVerbose","localAdmins","localNetworkOnly","maxLoginLength","maxMessageLength","permissions","port","requestLeaderOnPause","salt","serverChatHistory","templateUrl","totalVideoLimit","userVideoLimit","youtubeApiKey","youtubePlaylistLimit"],[false,false,false,false,false,true,false,false,false,false,false,false,false,true,false,false,false,false,false,false]); this.value = this.getAuto(); var _g = 0; while(_g < o.length) { var field = o[_g]; ++_g; switch(field.name) { - case "allowRatings": - this.value.allowRatings = this.loadObjectField(($_=new JsonParser_$46(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"allowRatings",assigned,this.value.allowRatings,pos); + case "allowProxyIps": + this.value.allowProxyIps = this.loadObjectField(($_=new JsonParser_$43(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"allowProxyIps",assigned,this.value.allowProxyIps,pos); break; - case "author": - this.value.author = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"author",assigned,this.value.author,pos); + case "cacheStorageLimitGiB": + this.value.cacheStorageLimitGiB = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"cacheStorageLimitGiB",assigned,this.value.cacheStorageLimitGiB,pos); break; - case "channelId": - this.value.channelId = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"channelId",assigned,this.value.channelId,pos); + case "channelName": + this.value.channelName = this.loadObjectField(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"channelName",assigned,this.value.channelName,pos); break; - case "isCrawlable": - this.value.isCrawlable = this.loadObjectField(($_=new JsonParser_$46(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isCrawlable",assigned,this.value.isCrawlable,pos); + case "emotes": + this.value.emotes = this.loadObjectField(($_=new JsonParser_$64(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"emotes",assigned,this.value.emotes,pos); break; - case "isLiveContent": - this.value.isLiveContent = this.loadObjectField(($_=new JsonParser_$46(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isLiveContent",assigned,this.value.isLiveContent,pos); + case "filters": + this.value.filters = this.loadObjectField(($_=new JsonParser_$65(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"filters",assigned,this.value.filters,pos); break; - case "isOwnerViewing": - this.value.isOwnerViewing = this.loadObjectField(($_=new JsonParser_$46(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isOwnerViewing",assigned,this.value.isOwnerViewing,pos); + case "isVerbose": + this.value.isVerbose = this.loadObjectField(($_=new JsonParser_$55(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isVerbose",assigned,this.value.isVerbose,pos); break; - case "isPrivate": - this.value.isPrivate = this.loadObjectField(($_=new JsonParser_$46(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isPrivate",assigned,this.value.isPrivate,pos); + case "localAdmins": + this.value.localAdmins = this.loadObjectField(($_=new JsonParser_$43(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"localAdmins",assigned,this.value.localAdmins,pos); break; - case "isUnpluggedCorpus": - this.value.isUnpluggedCorpus = this.loadObjectField(($_=new JsonParser_$46(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isUnpluggedCorpus",assigned,this.value.isUnpluggedCorpus,pos); + case "localNetworkOnly": + this.value.localNetworkOnly = this.loadObjectField(($_=new JsonParser_$43(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"localNetworkOnly",assigned,this.value.localNetworkOnly,pos); break; - case "keywords": - this.value.keywords = this.loadObjectField(($_=new JsonParser_$68(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"keywords",assigned,this.value.keywords,pos); + case "maxLoginLength": + this.value.maxLoginLength = this.loadObjectField(($_=new JsonParser_$51(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"maxLoginLength",assigned,this.value.maxLoginLength,pos); break; - case "lengthSeconds": - this.value.lengthSeconds = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"lengthSeconds",assigned,this.value.lengthSeconds,pos); + case "maxMessageLength": + this.value.maxMessageLength = this.loadObjectField(($_=new JsonParser_$51(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"maxMessageLength",assigned,this.value.maxMessageLength,pos); break; - case "shortDescription": - this.value.shortDescription = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"shortDescription",assigned,this.value.shortDescription,pos); + case "permissions": + this.value.permissions = this.loadObjectField(($_=new JsonParser_$67(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"permissions",assigned,this.value.permissions,pos); break; - case "thumbnail": - this.value.thumbnail = this.loadObjectField(($_=new JsonParser_$69(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"thumbnail",assigned,this.value.thumbnail,pos); + case "port": + this.value.port = this.loadObjectField(($_=new JsonParser_$51(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"port",assigned,this.value.port,pos); break; - case "title": - this.value.title = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"title",assigned,this.value.title,pos); + case "requestLeaderOnPause": + this.value.requestLeaderOnPause = this.loadObjectField(($_=new JsonParser_$43(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"requestLeaderOnPause",assigned,this.value.requestLeaderOnPause,pos); break; - case "videoId": - this.value.videoId = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"videoId",assigned,this.value.videoId,pos); + case "salt": + this.value.salt = this.loadObjectField(($_=new JsonParser_$47(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"salt",assigned,this.value.salt,pos); + break; + case "serverChatHistory": + this.value.serverChatHistory = this.loadObjectField(($_=new JsonParser_$51(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"serverChatHistory",assigned,this.value.serverChatHistory,pos); + break; + case "templateUrl": + this.value.templateUrl = this.loadObjectField(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"templateUrl",assigned,this.value.templateUrl,pos); + break; + case "totalVideoLimit": + this.value.totalVideoLimit = this.loadObjectField(($_=new JsonParser_$51(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"totalVideoLimit",assigned,this.value.totalVideoLimit,pos); break; - case "viewCount": - this.value.viewCount = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"viewCount",assigned,this.value.viewCount,pos); + case "userVideoLimit": + this.value.userVideoLimit = this.loadObjectField(($_=new JsonParser_$51(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"userVideoLimit",assigned,this.value.userVideoLimit,pos); + break; + case "youtubeApiKey": + this.value.youtubeApiKey = this.loadObjectField(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"youtubeApiKey",assigned,this.value.youtubeApiKey,pos); + break; + case "youtubePlaylistLimit": + this.value.youtubePlaylistLimit = this.loadObjectField(($_=new JsonParser_$51(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))); @@ -1793,79 +1703,63 @@ JsonParser_$67.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { allowRatings : new JsonParser_$46([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), author : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), channelId : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isCrawlable : new JsonParser_$46([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isLiveContent : new JsonParser_$46([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isOwnerViewing : new JsonParser_$46([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isPrivate : new JsonParser_$46([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isUnpluggedCorpus : new JsonParser_$46([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), keywords : new JsonParser_$68([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), lengthSeconds : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), shortDescription : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), thumbnail : new JsonParser_$69([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), title : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), videoId : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), viewCount : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { allowProxyIps : new JsonParser_$43([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), cacheStorageLimitGiB : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), channelName : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), emotes : new JsonParser_$64([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), filters : new JsonParser_$65([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isVerbose : new JsonParser_$55([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), localAdmins : new JsonParser_$43([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), localNetworkOnly : new JsonParser_$43([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), maxLoginLength : new JsonParser_$51([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), maxMessageLength : new JsonParser_$51([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), permissions : new JsonParser_$67([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), port : new JsonParser_$51([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), requestLeaderOnPause : new JsonParser_$43([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), salt : new JsonParser_$47([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), serverChatHistory : new JsonParser_$51([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), templateUrl : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), totalVideoLimit : new JsonParser_$51([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), userVideoLimit : new JsonParser_$51([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), youtubeApiKey : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), youtubePlaylistLimit : new JsonParser_$51([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,__class__: JsonParser_$67 + ,__class__: JsonParser_$59 }); -var JsonParser_$68 = function(errors,putils,errorType) { +var JsonParser_$60 = 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,{ +JsonParser_$60.__name__ = true; +JsonParser_$60.__super__ = json2object_reader_BaseParser; +JsonParser_$60.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { - this.errors.push(json2object_Error.IncorrectType(variable,"Array<String>",pos)); + this.errors.push(json2object_Error.IncorrectType(variable,"Array<Message>",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_$44(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); + this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$63(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); } - ,__class__: JsonParser_$68 + ,__class__: JsonParser_$60 }); -var JsonParser_$69 = 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_$69.__name__ = true; -JsonParser_$69.__super__ = json2object_reader_BaseParser; -JsonParser_$69.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,"{ thumbnails : Array<{ width : Int, url : String, height : Int }> }",pos)); + this.errors.push(json2object_Error.IncorrectType(variable,"Array<PlayerType>",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,["thumbnails"],[false]); - this.value = this.getAuto(); - var _g = 0; - while(_g < o.length) { - var field = o[_g]; - ++_g; - if(field.name == "thumbnails") { - this.value.thumbnails = this.loadObjectField(($_=new JsonParser_$70(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"thumbnails",assigned,this.value.thumbnails,pos); - } else { - this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); - } - } - this.objectErrors(assigned,pos); - } - ,getAuto: function() { - return { thumbnails : new JsonParser_$70([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + ,loadJsonArray: function(a,pos,variable) { + this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$45(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); } - ,__class__: JsonParser_$69 + ,__class__: JsonParser_$61 }); -var JsonParser_$7 = 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_$7.__name__ = true; -JsonParser_$7.__super__ = json2object_reader_BaseParser; -JsonParser_$7.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,"{ videoList : Array<VideoItem>, uuid : String, itemPos : Int, isUnknownClient : Bool, isPlaylistOpen : Bool, history : Array<Message>, globalIp : String, config : Config, clients : Array<ClientData>, clientName : String }",pos)); + this.errors.push(json2object_Error.IncorrectType(variable,"{ time : String, text : String, name : String }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } ,loadJsonNull: function(pos,variable) { @@ -1873,42 +1767,21 @@ JsonParser_$7.prototype = $extend(json2object_reader_BaseParser.prototype,{ } ,loadJsonObject: function(o,pos,variable) { var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["clientName","clients","config","globalIp","history","isPlaylistOpen","isUnknownClient","itemPos","uuid","videoList"],[false,false,false,false,false,false,false,false,false,false]); + this.objectSetupAssign(assigned,["name","text","time"],[false,false,false]); this.value = this.getAuto(); var _g = 0; while(_g < o.length) { var field = o[_g]; ++_g; switch(field.name) { - case "clientName": - this.value.clientName = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clientName",assigned,this.value.clientName,pos); - break; - case "clients": - this.value.clients = this.loadObjectField(($_=new JsonParser_$49(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clients",assigned,this.value.clients,pos); - break; - case "config": - this.value.config = this.loadObjectField(($_=new JsonParser_$81(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"config",assigned,this.value.config,pos); - break; - case "globalIp": - this.value.globalIp = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"globalIp",assigned,this.value.globalIp,pos); - break; - case "history": - this.value.history = this.loadObjectField(($_=new JsonParser_$82(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); - 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); - break; - case "itemPos": - this.value.itemPos = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"itemPos",assigned,this.value.itemPos,pos); + case "name": + this.value.name = this.loadObjectField(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"name",assigned,this.value.name,pos); break; - case "uuid": - this.value.uuid = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"uuid",assigned,this.value.uuid,pos); + case "text": + this.value.text = this.loadObjectField(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"text",assigned,this.value.text,pos); break; - case "videoList": - this.value.videoList = this.loadObjectField(($_=new JsonParser_$41(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"videoList",assigned,this.value.videoList,pos); + case "time": + this.value.time = this.loadObjectField(($_=new JsonParser_$42(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))); @@ -1917,87 +1790,63 @@ JsonParser_$7.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { clientName : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), clients : new JsonParser_$49([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), config : new JsonParser_$81([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), globalIp : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), history : new JsonParser_$82([],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_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), uuid : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), videoList : new JsonParser_$41([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { name : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), text : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), time : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,__class__: JsonParser_$7 + ,__class__: JsonParser_$63 }); -var JsonParser_$70 = function(errors,putils,errorType) { +var JsonParser_$64 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$70.__name__ = true; -JsonParser_$70.__super__ = json2object_reader_BaseParser; -JsonParser_$70.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$64.__name__ = true; +JsonParser_$64.__super__ = json2object_reader_BaseParser; +JsonParser_$64.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { - this.errors.push(json2object_Error.IncorrectType(variable,"Array<{ width : Int, url : String, height : Int }>",pos)); + 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_$71(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); + this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$73(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); } - ,__class__: JsonParser_$70 + ,__class__: JsonParser_$64 }); -var JsonParser_$71 = 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_$71.__name__ = true; -JsonParser_$71.__super__ = json2object_reader_BaseParser; -JsonParser_$71.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,"{ width : Int, url : String, height : Int }",pos)); + 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; } - ,loadJsonObject: function(o,pos,variable) { - var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["height","url","width"],[false,false,false]); - this.value = this.getAuto(); - var _g = 0; - while(_g < o.length) { - var field = o[_g]; - ++_g; - switch(field.name) { - case "height": - this.value.height = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"height",assigned,this.value.height,pos); - break; - case "url": - this.value.url = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"url",assigned,this.value.url,pos); - break; - case "width": - this.value.width = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"width",assigned,this.value.width,pos); - break; - default: - this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); - } - } - this.objectErrors(assigned,pos); - } - ,getAuto: function() { - return { height : new JsonParser_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), url : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), width : new JsonParser_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + ,loadJsonArray: function(a,pos,variable) { + this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$71(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); } - ,__class__: JsonParser_$71 + ,__class__: JsonParser_$65 }); -var JsonParser_$73 = 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_$73.__name__ = true; -JsonParser_$73.__super__ = json2object_reader_BaseParser; -JsonParser_$73.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,"{ width : Int, url : String, ?signatureCipher : Null<String>, qualityLabel : String, quality : String, projectionType : String, mimeType : String, lastModified : String, itag : Int, ?initRange : Null<{ start : Int, end : Int }>, ?indexRange : Null<{ start : Int, end : Int }>, height : Int, bitrate : Int, ?audioSampleRate : Null<Int>, ?audioQuality : Null<String>, ?audioChannels : Null<Int>, approxDurationMs : String }",pos)); + 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); } ,loadJsonNull: function(pos,variable) { @@ -2005,63 +1854,27 @@ JsonParser_$73.prototype = $extend(json2object_reader_BaseParser.prototype,{ } ,loadJsonObject: function(o,pos,variable) { var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["approxDurationMs","audioChannels","audioQuality","audioSampleRate","bitrate","height","indexRange","initRange","itag","lastModified","mimeType","projectionType","quality","qualityLabel","signatureCipher","url","width"],[false,true,true,true,false,false,true,true,false,false,false,false,false,false,true,false,false]); + this.objectSetupAssign(assigned,["admin","banned","guest","leader","user"],[false,false,false,false,false]); this.value = this.getAuto(); var _g = 0; while(_g < o.length) { var field = o[_g]; ++_g; switch(field.name) { - case "approxDurationMs": - this.value.approxDurationMs = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"approxDurationMs",assigned,this.value.approxDurationMs,pos); - break; - case "audioChannels": - this.value.audioChannels = this.loadObjectField(($_=new JsonParser_$75(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"audioChannels",assigned,this.value.audioChannels,pos); - break; - case "audioQuality": - this.value.audioQuality = this.loadObjectField(($_=new JsonParser_$48(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"audioQuality",assigned,this.value.audioQuality,pos); - break; - case "audioSampleRate": - this.value.audioSampleRate = this.loadObjectField(($_=new JsonParser_$75(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"audioSampleRate",assigned,this.value.audioSampleRate,pos); - break; - case "bitrate": - this.value.bitrate = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"bitrate",assigned,this.value.bitrate,pos); - break; - case "height": - this.value.height = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"height",assigned,this.value.height,pos); - break; - case "indexRange": - this.value.indexRange = this.loadObjectField(($_=new JsonParser_$77(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"indexRange",assigned,this.value.indexRange,pos); - break; - case "initRange": - this.value.initRange = this.loadObjectField(($_=new JsonParser_$77(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"initRange",assigned,this.value.initRange,pos); - break; - case "itag": - this.value.itag = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"itag",assigned,this.value.itag,pos); - break; - case "lastModified": - this.value.lastModified = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"lastModified",assigned,this.value.lastModified,pos); - break; - case "mimeType": - this.value.mimeType = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"mimeType",assigned,this.value.mimeType,pos); - break; - case "projectionType": - this.value.projectionType = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"projectionType",assigned,this.value.projectionType,pos); - break; - case "quality": - this.value.quality = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"quality",assigned,this.value.quality,pos); + case "admin": + this.value.admin = this.loadObjectField(($_=new JsonParser_$68(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"admin",assigned,this.value.admin,pos); break; - case "qualityLabel": - this.value.qualityLabel = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"qualityLabel",assigned,this.value.qualityLabel,pos); + case "banned": + this.value.banned = this.loadObjectField(($_=new JsonParser_$68(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"banned",assigned,this.value.banned,pos); break; - case "signatureCipher": - this.value.signatureCipher = this.loadObjectField(($_=new JsonParser_$48(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"signatureCipher",assigned,this.value.signatureCipher,pos); + case "guest": + this.value.guest = this.loadObjectField(($_=new JsonParser_$68(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"guest",assigned,this.value.guest,pos); break; - case "url": - this.value.url = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"url",assigned,this.value.url,pos); + case "leader": + this.value.leader = this.loadObjectField(($_=new JsonParser_$68(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"leader",assigned,this.value.leader,pos); break; - case "width": - this.value.width = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"width",assigned,this.value.width,pos); + case "user": + this.value.user = this.loadObjectField(($_=new JsonParser_$68(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))); @@ -2070,105 +1883,64 @@ JsonParser_$73.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { approxDurationMs : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), audioChannels : new JsonParser_$75([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), audioQuality : new JsonParser_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), audioSampleRate : new JsonParser_$75([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), bitrate : new JsonParser_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), height : new JsonParser_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), indexRange : new JsonParser_$77([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), initRange : new JsonParser_$77([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), itag : new JsonParser_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), lastModified : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), mimeType : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), projectionType : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), quality : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), qualityLabel : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), signatureCipher : new JsonParser_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), url : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), width : new JsonParser_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { admin : new JsonParser_$68([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), banned : new JsonParser_$68([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), guest : new JsonParser_$68([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), leader : new JsonParser_$68([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), user : new JsonParser_$68([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,__class__: JsonParser_$73 -}); -var JsonParser_$75 = function(errors,putils,errorType) { - if(errorType == null) { - errorType = 0; - } - json2object_reader_BaseParser.call(this,errors,putils,errorType); -}; -JsonParser_$75.__name__ = true; -JsonParser_$75.__super__ = json2object_reader_BaseParser; -JsonParser_$75.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); - } - ,loadJsonNull: function(pos,variable) { - this.value = null; - } - ,loadJsonNumber: function(f,pos,variable) { - this.value = this.loadJsonInt(f,pos,variable,this.value); - } - ,__class__: JsonParser_$75 + ,__class__: JsonParser_$67 }); -var JsonParser_$77 = function(errors,putils,errorType) { +var JsonParser_$68 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$77.__name__ = true; -JsonParser_$77.__super__ = json2object_reader_BaseParser; -JsonParser_$77.prototype = $extend(json2object_reader_BaseParser.prototype,{ +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,"{ start : Int, end : Int }",pos)); + this.errors.push(json2object_Error.IncorrectType(variable,"Array<Permission>",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,["end","start"],[false,false]); - this.value = this.getAuto(); - var _g = 0; - while(_g < o.length) { - var field = o[_g]; - ++_g; - switch(field.name) { - case "end": - this.value.end = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"end",assigned,this.value.end,pos); - break; - case "start": - this.value.start = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"start",assigned,this.value.start,pos); - break; - default: - this.errors.push(json2object_Error.UnknownVariable(field.name,this.putils.convertPosition(field.namePos))); - } - } - this.objectErrors(assigned,pos); - } - ,getAuto: function() { - return { end : new JsonParser_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), start : new JsonParser_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + ,loadJsonArray: function(a,pos,variable) { + this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$69(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); } - ,__class__: JsonParser_$77 + ,__class__: JsonParser_$68 }); -var JsonParser_$79 = 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_$79.__name__ = true; -JsonParser_$79.__super__ = json2object_reader_BaseParser; -JsonParser_$79.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,"Float",pos)); - json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); + this.value = "guest"; + this.errors.push(json2object_Error.IncorrectType(variable,"Permission",pos)); + this.objectThrow(pos,variable); } ,loadJsonNull: function(pos,variable) { this.value = null; } - ,loadJsonNumber: function(f,pos,variable) { - this.value = this.loadJsonFloat(f,pos,variable,this.value); + ,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_$79 + ,__class__: JsonParser_$69 }); -var JsonParser_$81 = function(errors,putils,errorType) { +var JsonParser_$7 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$81.__name__ = true; -JsonParser_$81.__super__ = json2object_reader_BaseParser; -JsonParser_$81.prototype = $extend(json2object_reader_BaseParser.prototype,{ +JsonParser_$7.__name__ = true; +JsonParser_$7.__super__ = json2object_reader_BaseParser; +JsonParser_$7.prototype = $extend(json2object_reader_BaseParser.prototype,{ onIncorrectType: function(pos,variable) { - this.errors.push(json2object_Error.IncorrectType(variable,"{ youtubePlaylistLimit : Int, youtubeApiKey : String, userVideoLimit : Int, 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, allowProxyIps : Bool }",pos)); + this.errors.push(json2object_Error.IncorrectType(variable,"{ 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 }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } ,loadJsonNull: function(pos,variable) { @@ -2176,69 +1948,45 @@ JsonParser_$81.prototype = $extend(json2object_reader_BaseParser.prototype,{ } ,loadJsonObject: function(o,pos,variable) { var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["allowProxyIps","channelName","emotes","filters","isVerbose","localAdmins","localNetworkOnly","maxLoginLength","maxMessageLength","permissions","port","requestLeaderOnPause","salt","serverChatHistory","templateUrl","totalVideoLimit","userVideoLimit","youtubeApiKey","youtubePlaylistLimit"],[false,false,false,false,true,false,false,false,false,false,false,false,true,false,false,false,false,false,false]); + this.objectSetupAssign(assigned,["clientName","clients","config","globalIp","history","isPlaylistOpen","isUnknownClient","itemPos","playersCacheSupport","uuid","videoList"],[false,false,false,false,false,false,false,false,false,false,false]); this.value = this.getAuto(); var _g = 0; while(_g < o.length) { var field = o[_g]; ++_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); - break; - case "channelName": - this.value.channelName = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"channelName",assigned,this.value.channelName,pos); - break; - case "emotes": - this.value.emotes = this.loadObjectField(($_=new JsonParser_$85(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"emotes",assigned,this.value.emotes,pos); - break; - case "filters": - this.value.filters = this.loadObjectField(($_=new JsonParser_$86(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"filters",assigned,this.value.filters,pos); - break; - case "isVerbose": - this.value.isVerbose = this.loadObjectField(($_=new JsonParser_$56(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); - 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); - break; - case "maxLoginLength": - this.value.maxLoginLength = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"maxLoginLength",assigned,this.value.maxLoginLength,pos); - break; - case "maxMessageLength": - this.value.maxMessageLength = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"maxMessageLength",assigned,this.value.maxMessageLength,pos); + case "clientName": + this.value.clientName = this.loadObjectField(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clientName",assigned,this.value.clientName,pos); break; - case "permissions": - this.value.permissions = this.loadObjectField(($_=new JsonParser_$88(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"permissions",assigned,this.value.permissions,pos); + case "clients": + this.value.clients = this.loadObjectField(($_=new JsonParser_$48(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"clients",assigned,this.value.clients,pos); break; - case "port": - this.value.port = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"port",assigned,this.value.port,pos); + case "config": + this.value.config = this.loadObjectField(($_=new JsonParser_$59(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"config",assigned,this.value.config,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); + case "globalIp": + this.value.globalIp = this.loadObjectField(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"globalIp",assigned,this.value.globalIp,pos); break; - case "salt": - this.value.salt = this.loadObjectField(($_=new JsonParser_$48(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"salt",assigned,this.value.salt,pos); + case "history": + this.value.history = this.loadObjectField(($_=new JsonParser_$60(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"history",assigned,this.value.history,pos); break; - case "serverChatHistory": - this.value.serverChatHistory = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"serverChatHistory",assigned,this.value.serverChatHistory,pos); + case "isPlaylistOpen": + this.value.isPlaylistOpen = this.loadObjectField(($_=new JsonParser_$43(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isPlaylistOpen",assigned,this.value.isPlaylistOpen,pos); break; - case "templateUrl": - this.value.templateUrl = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"templateUrl",assigned,this.value.templateUrl,pos); + case "isUnknownClient": + this.value.isUnknownClient = this.loadObjectField(($_=new JsonParser_$43(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"isUnknownClient",assigned,this.value.isUnknownClient,pos); break; - case "totalVideoLimit": - this.value.totalVideoLimit = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"totalVideoLimit",assigned,this.value.totalVideoLimit,pos); + case "itemPos": + this.value.itemPos = this.loadObjectField(($_=new JsonParser_$51(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"itemPos",assigned,this.value.itemPos,pos); break; - case "userVideoLimit": - this.value.userVideoLimit = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"userVideoLimit",assigned,this.value.userVideoLimit,pos); + case "playersCacheSupport": + this.value.playersCacheSupport = this.loadObjectField(($_=new JsonParser_$61(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"playersCacheSupport",assigned,this.value.playersCacheSupport,pos); break; - case "youtubeApiKey": - this.value.youtubeApiKey = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"youtubeApiKey",assigned,this.value.youtubeApiKey,pos); + case "uuid": + this.value.uuid = this.loadObjectField(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"uuid",assigned,this.value.uuid,pos); break; - case "youtubePlaylistLimit": - this.value.youtubePlaylistLimit = this.loadObjectField(($_=new JsonParser_$52(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"youtubePlaylistLimit",assigned,this.value.youtubePlaylistLimit,pos); + case "videoList": + this.value.videoList = this.loadObjectField(($_=new JsonParser_$39(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))); @@ -2247,42 +1995,21 @@ JsonParser_$81.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))), channelName : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), emotes : new JsonParser_$85([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), filters : new JsonParser_$86([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isVerbose : new JsonParser_$56([],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_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), maxMessageLength : new JsonParser_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), permissions : new JsonParser_$88([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), port : new JsonParser_$52([],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_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), serverChatHistory : new JsonParser_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), templateUrl : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), totalVideoLimit : new JsonParser_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), userVideoLimit : new JsonParser_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), youtubeApiKey : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), youtubePlaylistLimit : new JsonParser_$52([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; - } - ,__class__: JsonParser_$81 -}); -var JsonParser_$82 = function(errors,putils,errorType) { - if(errorType == null) { - errorType = 0; - } - json2object_reader_BaseParser.call(this,errors,putils,errorType); -}; -JsonParser_$82.__name__ = true; -JsonParser_$82.__super__ = json2object_reader_BaseParser; -JsonParser_$82.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); - } - ,loadJsonNull: function(pos,variable) { - this.value = null; + return { clientName : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), clients : new JsonParser_$48([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), config : new JsonParser_$59([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), globalIp : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), history : new JsonParser_$60([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isPlaylistOpen : new JsonParser_$43([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), isUnknownClient : new JsonParser_$43([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), itemPos : new JsonParser_$51([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), playersCacheSupport : new JsonParser_$61([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), uuid : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), videoList : new JsonParser_$39([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,loadJsonArray: function(a,pos,variable) { - this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$84(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); - } - ,__class__: JsonParser_$82 + ,__class__: JsonParser_$7 }); -var JsonParser_$84 = function(errors,putils,errorType) { +var JsonParser_$71 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$84.__name__ = true; -JsonParser_$84.__super__ = json2object_reader_BaseParser; -JsonParser_$84.prototype = $extend(json2object_reader_BaseParser.prototype,{ +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,"{ time : String, text : String, name : String }",pos)); + 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); } ,loadJsonNull: function(pos,variable) { @@ -2290,21 +2017,24 @@ JsonParser_$84.prototype = $extend(json2object_reader_BaseParser.prototype,{ } ,loadJsonObject: function(o,pos,variable) { var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["name","text","time"],[false,false,false]); + this.objectSetupAssign(assigned,["flags","name","regex","replace"],[false,false,false,false]); this.value = this.getAuto(); var _g = 0; while(_g < o.length) { var field = o[_g]; ++_g; switch(field.name) { + case "flags": + this.value.flags = this.loadObjectField(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"flags",assigned,this.value.flags,pos); + break; case "name": - this.value.name = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"name",assigned,this.value.name,pos); + this.value.name = this.loadObjectField(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"name",assigned,this.value.name,pos); break; - case "text": - this.value.text = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"text",assigned,this.value.text,pos); + case "regex": + this.value.regex = this.loadObjectField(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"regex",assigned,this.value.regex,pos); break; - case "time": - this.value.time = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"time",assigned,this.value.time,pos); + case "replace": + this.value.replace = this.loadObjectField(($_=new JsonParser_$42(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))); @@ -2313,63 +2043,21 @@ JsonParser_$84.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { name : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), text : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), time : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { flags : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), name : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), regex : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), replace : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,__class__: JsonParser_$84 -}); -var JsonParser_$85 = function(errors,putils,errorType) { - if(errorType == null) { - errorType = 0; - } - json2object_reader_BaseParser.call(this,errors,putils,errorType); -}; -JsonParser_$85.__name__ = true; -JsonParser_$85.__super__ = json2object_reader_BaseParser; -JsonParser_$85.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_$94(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); - } - ,__class__: JsonParser_$85 -}); -var JsonParser_$86 = function(errors,putils,errorType) { - if(errorType == null) { - errorType = 0; - } - json2object_reader_BaseParser.call(this,errors,putils,errorType); -}; -JsonParser_$86.__name__ = true; -JsonParser_$86.__super__ = json2object_reader_BaseParser; -JsonParser_$86.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_$92(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); - } - ,__class__: JsonParser_$86 + ,__class__: JsonParser_$71 }); -var JsonParser_$88 = function(errors,putils,errorType) { +var JsonParser_$73 = function(errors,putils,errorType) { if(errorType == null) { errorType = 0; } json2object_reader_BaseParser.call(this,errors,putils,errorType); }; -JsonParser_$88.__name__ = true; -JsonParser_$88.__super__ = json2object_reader_BaseParser; -JsonParser_$88.prototype = $extend(json2object_reader_BaseParser.prototype,{ +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)); + this.errors.push(json2object_Error.IncorrectType(variable,"{ name : String, image : String }",pos)); json2object_reader_BaseParser.prototype.onIncorrectType.call(this,pos,variable); } ,loadJsonNull: function(pos,variable) { @@ -2377,27 +2065,18 @@ JsonParser_$88.prototype = $extend(json2object_reader_BaseParser.prototype,{ } ,loadJsonObject: function(o,pos,variable) { var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["admin","banned","guest","leader","user"],[false,false,false,false,false]); + this.objectSetupAssign(assigned,["image","name"],[false,false]); this.value = this.getAuto(); var _g = 0; while(_g < o.length) { var field = o[_g]; ++_g; switch(field.name) { - case "admin": - this.value.admin = this.loadObjectField(($_=new JsonParser_$89(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"admin",assigned,this.value.admin,pos); - break; - case "banned": - this.value.banned = this.loadObjectField(($_=new JsonParser_$89(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"banned",assigned,this.value.banned,pos); - break; - case "guest": - this.value.guest = this.loadObjectField(($_=new JsonParser_$89(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"guest",assigned,this.value.guest,pos); - break; - case "leader": - this.value.leader = this.loadObjectField(($_=new JsonParser_$89(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"leader",assigned,this.value.leader,pos); + case "image": + this.value.image = this.loadObjectField(($_=new JsonParser_$42(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"image",assigned,this.value.image,pos); break; - case "user": - this.value.user = this.loadObjectField(($_=new JsonParser_$89(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"user",assigned,this.value.user,pos); + case "name": + this.value.name = this.loadObjectField(($_=new JsonParser_$42(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))); @@ -2406,30 +2085,9 @@ JsonParser_$88.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { admin : new JsonParser_$89([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), banned : new JsonParser_$89([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), guest : new JsonParser_$89([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), leader : new JsonParser_$89([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), user : new JsonParser_$89([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { image : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), name : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } - ,__class__: JsonParser_$88 -}); -var JsonParser_$89 = function(errors,putils,errorType) { - if(errorType == null) { - errorType = 0; - } - json2object_reader_BaseParser.call(this,errors,putils,errorType); -}; -JsonParser_$89.__name__ = true; -JsonParser_$89.__super__ = json2object_reader_BaseParser; -JsonParser_$89.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); - } - ,loadJsonNull: function(pos,variable) { - this.value = null; - } - ,loadJsonArray: function(a,pos,variable) { - this.value = this.loadJsonArrayValue(a,($_=new JsonParser_$90(this.errors,this.putils,2),$bind($_,$_.loadJson)),variable); - } - ,__class__: JsonParser_$89 + ,__class__: JsonParser_$73 }); var JsonParser_$9 = function(errors,putils,errorType) { if(errorType == null) { @@ -2456,7 +2114,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_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"data",assigned,this.value.data,pos); + this.value.data = this.loadObjectField(($_=new JsonParser_$42(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))); } @@ -2464,122 +2122,10 @@ JsonParser_$9.prototype = $extend(json2object_reader_BaseParser.prototype,{ this.objectErrors(assigned,pos); } ,getAuto: function() { - return { data : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; + return { data : new JsonParser_$42([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; } ,__class__: JsonParser_$9 }); -var JsonParser_$90 = function(errors,putils,errorType) { - if(errorType == null) { - errorType = 0; - } - json2object_reader_BaseParser.call(this,errors,putils,errorType); -}; -JsonParser_$90.__name__ = true; -JsonParser_$90.__super__ = json2object_reader_BaseParser; -JsonParser_$90.prototype = $extend(json2object_reader_BaseParser.prototype,{ - onIncorrectType: function(pos,variable) { - this.value = "guest"; - this.errors.push(json2object_Error.IncorrectType(variable,"Permission",pos)); - this.objectThrow(pos,variable); - } - ,loadJsonNull: function(pos,variable) { - this.value = null; - } - ,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_$90 -}); -var JsonParser_$92 = function(errors,putils,errorType) { - if(errorType == null) { - errorType = 0; - } - json2object_reader_BaseParser.call(this,errors,putils,errorType); -}; -JsonParser_$92.__name__ = true; -JsonParser_$92.__super__ = json2object_reader_BaseParser; -JsonParser_$92.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); - } - ,loadJsonNull: function(pos,variable) { - this.value = null; - } - ,loadJsonObject: function(o,pos,variable) { - var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["flags","name","regex","replace"],[false,false,false,false]); - this.value = this.getAuto(); - var _g = 0; - while(_g < o.length) { - var field = o[_g]; - ++_g; - switch(field.name) { - case "flags": - this.value.flags = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"flags",assigned,this.value.flags,pos); - break; - case "name": - this.value.name = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"name",assigned,this.value.name,pos); - break; - case "regex": - this.value.regex = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"regex",assigned,this.value.regex,pos); - break; - case "replace": - this.value.replace = this.loadObjectField(($_=new JsonParser_$44(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))); - } - } - this.objectErrors(assigned,pos); - } - ,getAuto: function() { - return { flags : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), name : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), regex : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), replace : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; - } - ,__class__: JsonParser_$92 -}); -var JsonParser_$94 = function(errors,putils,errorType) { - if(errorType == null) { - errorType = 0; - } - json2object_reader_BaseParser.call(this,errors,putils,errorType); -}; -JsonParser_$94.__name__ = true; -JsonParser_$94.__super__ = json2object_reader_BaseParser; -JsonParser_$94.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); - } - ,loadJsonNull: function(pos,variable) { - this.value = null; - } - ,loadJsonObject: function(o,pos,variable) { - var assigned = new haxe_ds_StringMap(); - this.objectSetupAssign(assigned,["image","name"],[false,false]); - this.value = this.getAuto(); - var _g = 0; - while(_g < o.length) { - var field = o[_g]; - ++_g; - switch(field.name) { - case "image": - this.value.image = this.loadObjectField(($_=new JsonParser_$44(this.errors,this.putils,1),$bind($_,$_.loadJson)),field,"image",assigned,this.value.image,pos); - break; - case "name": - this.value.name = this.loadObjectField(($_=new JsonParser_$44(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))); - } - } - this.objectErrors(assigned,pos); - } - ,getAuto: function() { - return { image : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1))), name : new JsonParser_$44([],this.putils,0).loadJson(new hxjsonast_Json(hxjsonast_JsonValue.JNull,new hxjsonast_Position("",0,1)))}; - } - ,__class__: JsonParser_$94 -}); var Lambda = function() { }; Lambda.__name__ = true; Lambda.exists = function(it,f) { @@ -2804,7 +2350,7 @@ StringTools.hex = function(n,digits) { var _$Types_VideoItemTools = function() { }; _$Types_VideoItemTools.__name__ = true; _$Types_VideoItemTools.withUrl = function(item,url) { - return { url : url, title : item.title, author : item.author, duration : item.duration, subs : item.subs, voiceOverTrack : item.voiceOverTrack, isTemp : item.isTemp, isIframe : item.isIframe}; + return { url : url, title : item.title, author : item.author, duration : item.duration, subs : item.subs, voiceOverTrack : item.voiceOverTrack, isTemp : item.isTemp, doCache : item.doCache, playerType : item.playerType}; }; var VideoList = function() { this.items = []; @@ -3876,6 +3422,7 @@ js_Boot.__isNativeObj = function(o) { js_Boot.__resolveNativeClass = function(name) { return $global[name]; }; +var js_node_ChildProcess = require("child_process"); var js_node_Crypto = require("crypto"); var js_node_Fs = require("fs"); var js_node_Http = require("http"); @@ -3884,7 +3431,6 @@ var js_node_Os = require("os"); var js_node_Path = require("path"); var js_node_Readline = require("readline"); var js_node_url_URL = require("url").URL; -var js_node_url_URLSearchParams = require("url").URLSearchParams; var js_npm_ws_Server = require("ws").Server; var json2object_Error = $hxEnums["json2object.Error"] = { __ename__:true,__constructs__:null ,IncorrectType: ($_=function(variable,expected,pos) { return {_hx_index:0,variable:variable,expected:expected,pos:pos,__enum__:"json2object.Error",toString:$estr}; },$_._hx_name="IncorrectType",$_.__params__ = ["variable","expected","pos"],$_) @@ -4048,6 +3594,173 @@ json2object_PositionUtils.prototype = { } ,__class__: json2object_PositionUtils }; +var server_Cache = function(main,cacheDir) { + this.storageLimit = 3145728 * 1024; + this.isYtReady = false; + this.cachedFiles = []; + this.main = main; + this.cacheDir = cacheDir; + server_Utils.ensureDir(cacheDir); + this.isYtReady = this.checkYtDeps(); +}; +server_Cache.__name__ = true; +server_Cache.prototype = { + checkYtDeps: function() { + var ytdl; + try { + ytdl = require("@distube/ytdl-core"); + } catch( _g ) { + return false; + } + try { + js_node_ChildProcess.execSync("ffmpeg -version",{ stdio : "ignore", timeout : 3000}); + return true; + } catch( _g ) { + return false; + } + } + ,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"}); + } + ,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"}); + return; + } + var videoId = utils_YoutubeUtils.extractVideoId(url); + if(videoId == "") { + this.log(client,"Error: youtube video id not found in url: " + url); + return; + } + var outName = videoId + ".mp4"; + if(this.cachedFiles.indexOf(outName) != -1) { + callback(outName); + return; + } + var ytdl = require("@distube/ytdl-core"); + this.log(client,"Caching " + url + " to " + outName + "..."); + var opts = { playerClients : ["IOS","WEB_CREATOR"]}; + var promise = ytdl.getInfo(url,opts); + 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"}); + var audioFormat; + try { + var ytdl1 = ytdl.chooseFormat; + var _g = []; + var _g1 = 0; + var _g2 = info.formats; + while(_g1 < _g2.length) { + var v = _g2[_g1]; + ++_g1; + var tmp = v.audioCodec; + if(tmp != null ? StringTools.startsWith(tmp,"mp4a") : null) { + _g.push(v); + } + } + audioFormat = ytdl1(_g,{ quality : "highestaudio"}); + } 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"}); + return; + } + var videoFormat; + var tmp = _gthis.getBestYoutubeVideoFormat(info.formats); + if(tmp != null) { + 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"}); + 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, playerClients : opts.playerClients}); + dlVideo.pipe(js_node_Fs.createWriteStream("" + _gthis.cacheDir + "/input-video")); + dlVideo.on("error",function(err) { + _gthis.log(client,"Error during video download: " + err); + }); + var dlAudio = ytdl(url,{ format : audioFormat, playerClients : opts.playerClients}); + dlAudio.pipe(js_node_Fs.createWriteStream("" + _gthis.cacheDir + "/input-audio")); + dlAudio.on("error",function(err) { + _gthis.log(client,"Error during audio download: " + err); + }); + var count = 0; + var onComplete = function(type) { + count += 1; + _gthis.log(client,"" + type + " track downloaded (" + count + "/2)"); + if(count < 2) { + return; + } + 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) { + if(code != 0) { + _gthis.log(client,"Error: ffmpeg closed with code " + code); + return; + } + 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); + } + _gthis.cachedFiles.push(outName); + _gthis.removeOlderCache(); + callback(outName); + }); + }; + dlVideo.on("finish",function() { + onComplete("Video"); + }); + dlAudio.on("finish",function() { + onComplete("Audio"); + }); + }).catch(function(err) { + _gthis.log(client,"" + err); + }); + } + ,removeOlderCache: function() { + while(this.getUsedSpace() > this.storageLimit) { + var name = this.cachedFiles.shift(); + var path = "" + this.cacheDir + "/" + name; + if(sys_FileSystem.exists(path)) { + js_node_Fs.unlinkSync(path); + } + } + } + ,getUsedSpace: function() { + var total = 0; + var _g = 0; + var _g1 = this.cachedFiles; + while(_g < _g1.length) total += js_node_Fs.statSync("" + this.cacheDir + "/" + _g1[_g++]).size; + return total; + } + ,getBestYoutubeVideoFormat: function(formats) { + var qPriority = [1080,720,480,360,240]; + var _g = 0; + while(_g < qPriority.length) { + var quality = "" + qPriority[_g++] + "p"; + var _g1 = 0; + while(_g1 < formats.length) { + var format = formats[_g1]; + ++_g1; + if(format.videoCodec == null) { + continue; + } + if(format.qualityLabel == quality) { + return format; + } + } + } + return null; + } + ,__class__: server_Cache +}; var server_ConsoleInput = function(main) { var _g = new haxe_ds_StringMap(); _g.h["addAdmin"] = { args : ["name","password"], desc : "Adds channel admin"}; @@ -4535,6 +4248,7 @@ var server_Main = function(opts) { this.wsEventParser = new JsonParser_$1(); this.freeIds = []; this.clients = []; + this.playersCacheSupport = []; this.rootDir = "" + __dirname + "/.."; var _gthis = this; this.isNoState = !opts.loadState; @@ -4557,9 +4271,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"); + 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.userList = this.loadUsers(); this.config.isVerbose = this.verbose; this.config.salt = this.generateConfigSalt(); @@ -4586,7 +4305,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 : 124, 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 : 130, className : "server.Main", methodName : "new"}); attempts -= 1; _gthis.port++; preparePort(); @@ -4604,16 +4323,16 @@ 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 : 137, className : "server.Main", methodName : "runServer"}); + haxe_Log.trace("Local: http://" + this.localIp + ":" + this.port,{ fileName : "src/server/Main.hx", lineNumber : 143, className : "server.Main", methodName : "runServer"}); if(this.config.localNetworkOnly) { - haxe_Log.trace("Global network is disabled in config",{ fileName : "src/server/Main.hx", lineNumber : 139, className : "server.Main", methodName : "runServer"}); + haxe_Log.trace("Global network is disabled in config",{ fileName : "src/server/Main.hx", lineNumber : 145, 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 : 145, className : "server.Main", methodName : "runServer"}); + haxe_Log.trace("Global: http://" + _gthis.globalIp + ":" + _gthis.port,{ fileName : "src/server/Main.hx", lineNumber : 151, className : "server.Main", methodName : "runServer"}); }); } var dir = "" + this.rootDir + "/res"; @@ -4698,7 +4417,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 : 214, className : "server.Main", methodName : "getUserConfig"}); + haxe_Log.trace("Warning: config field \"" + field + "\" is unknown",{ fileName : "src/server/Main.hx", lineNumber : 220, className : "server.Main", methodName : "getUserConfig"}); } config[field] = Reflect.field(customConfig,field); } @@ -4709,14 +4428,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 : 220, className : "server.Main", methodName : "getUserConfig"}); + haxe_Log.trace("Warning: emote name \"" + emote.name + "\" has copy",{ fileName : "src/server/Main.hx", lineNumber : 226, 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 : 224, className : "server.Main", methodName : "getUserConfig"}); + haxe_Log.trace("Warning: emote url of name \"" + emote.name + "\" has copy",{ fileName : "src/server/Main.hx", lineNumber : 230, className : "server.Main", methodName : "getUserConfig"}); } emoteCopies_h[emote.image] = true; } @@ -4754,13 +4473,13 @@ 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 : 263, className : "server.Main", methodName : "saveState"}); + haxe_Log.trace("Saving state...",{ fileName : "src/server/Main.hx", lineNumber : 269, className : "server.Main", methodName : "saveState"}); var json = JSON.stringify(this.getCurrentState(),null,"\t"); js_node_Fs.writeFileSync(this.statePath,json); this.writeUsers(this.userList); } ,getCurrentState: function() { - return { videoList : this.videoList.items, isPlaylistOpen : this.videoList.isOpen, itemPos : this.videoList.pos, messages : this.messages, timer : { time : this.videoTimer.getTime(), paused : this.videoTimer.isPaused()}, flashbacks : this.flashbacks}; + return { videoList : this.videoList.items, isPlaylistOpen : this.videoList.isOpen, itemPos : this.videoList.pos, messages : this.messages, timer : { time : this.videoTimer.getTime(), paused : this.videoTimer.isPaused()}, flashbacks : this.flashbacks, cachedFiles : this.cache.cachedFiles}; } ,loadState: function() { if(this.isNoState) { @@ -4769,8 +4488,10 @@ server_Main.prototype = { if(!sys_FileSystem.exists(this.statePath)) { return; } - haxe_Log.trace("Loading state...",{ fileName : "src/server/Main.hx", lineNumber : 286, className : "server.Main", methodName : "loadState"}); + haxe_Log.trace("Loading state...",{ fileName : "src/server/Main.hx", lineNumber : 293, 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 : []; this.videoList.setItems(state.videoList); this.videoList.isOpen = state.isPlaylistOpen; this.videoList.setPos(state.itemPos); @@ -4780,15 +4501,18 @@ server_Main.prototype = { while(_g < _g1.length) this.messages.push(_g1[_g++]); this.flashbacks.length = 0; var _g = 0; - var tmp = state.flashbacks; - var _g1 = tmp != null ? tmp : []; + var _g1 = state.flashbacks; while(_g < _g1.length) this.flashbacks.push(_g1[_g++]); + this.cache.cachedFiles.length = 0; + var _g = 0; + var _g1 = state.cachedFiles; + while(_g < _g1.length) this.cache.cachedFiles.push(_g1[_g++]); this.videoTimer.start(); this.videoTimer.setTime(state.timer.time); this.videoTimer.pause(); } ,logError: function(type,data) { - haxe_Log.trace(type,{ fileName : "src/server/Main.hx", lineNumber : 304, className : "server.Main", methodName : "logError", customParams : [data]}); + haxe_Log.trace(type,{ fileName : "src/server/Main.hx", lineNumber : 317, 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; @@ -4806,7 +4530,7 @@ server_Main.prototype = { if(_gthis.clients.length == 0) { return; } - haxe_Log.trace("Ping " + url,{ fileName : "src/server/Main.hx", lineNumber : 321, className : "server.Main", methodName : "initIntergationHandlers"}); + haxe_Log.trace("Ping " + url,{ fileName : "src/server/Main.hx", lineNumber : 334, className : "server.Main", methodName : "initIntergationHandlers"}); js_node_Http.get(url,null,function(r) { }); }; @@ -4826,13 +4550,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 : 344, className : "server.Main", methodName : "addAdmin"}); + haxe_Log.trace("Admin " + name + " added.",{ fileName : "src/server/Main.hx", lineNumber : 357, 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 : 351, className : "server.Main", methodName : "removeAdmin"}); + haxe_Log.trace("Admin " + name + " removed.",{ fileName : "src/server/Main.hx", lineNumber : 364, className : "server.Main", methodName : "removeAdmin"}); } ,replayLog: function(events) { var _gthis = this; @@ -4899,7 +4623,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 : 410, className : "server.Main", methodName : "onConnect", customParams : ["" + name + " connected (" + ip + ")"]}); + haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 423, 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; @@ -4913,7 +4637,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 : 427, className : "server.Main", methodName : "onConnect"}); + haxe_Log.trace(errors,{ fileName : "src/server/Main.hx", lineNumber : 440, className : "server.Main", methodName : "onConnect"}); _gthis.serverMessage(client,errors); return; } @@ -4980,11 +4704,26 @@ server_Main.prototype = { this.serverMessage(client,"videoAlreadyExistsError"); return; } - data.addVideo.item = item; - this.videoList.addItem(item,data.addVideo.atEnd); - this.broadcast(data); - if(this.videoList.items.length == 1) { - this.restartWaitTimer(); + if(!item.doCache) { + data.addVideo.item = item; + _gthis.videoList.addItem(item,data.addVideo.atEnd); + _gthis.broadcast(data); + if(_gthis.videoList.items.length == 1) { + _gthis.restartWaitTimer(); + } + } else { + this.cache.cacheYoutubeVideo(client,item.url,function(name) { + item = _$Types_VideoItemTools.withUrl(item,"/cache/" + name); + if(item.duration > 1) { + item.duration -= 1; + } + data.addVideo.item = item; + _gthis.videoList.addItem(item,data.addVideo.atEnd); + _gthis.broadcast(data); + if(_gthis.videoList.items.length == 1) { + _gthis.restartWaitTimer(); + } + }); } break; case "BanClient": @@ -5057,14 +4796,14 @@ server_Main.prototype = { } } this.checkBan(client); - this.send(client,{ type : "Connected", connected : { uuid : client.uuid, config : this.config, history : this.messages, isUnknownClient : true, clientName : client.name, clients : this.clientList(), videoList : this.videoList.items, isPlaylistOpen : this.videoList.isOpen, itemPos : this.videoList.pos, globalIp : this.globalIp}}); + this.send(client,{ type : "Connected", connected : { uuid : client.uuid, config : this.config, history : this.messages, isUnknownClient : true, clientName : client.name, clients : this.clientList(), videoList : this.videoList.items, isPlaylistOpen : this.videoList.isOpen, itemPos : this.videoList.pos, globalIp : this.globalIp, playersCacheSupport : this.playersCacheSupport}}); this.sendClientListExcept(client); break; case "Disconnected": if(!internal) { return; } - haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 489, className : "server.Main", methodName : "onMessage", customParams : ["Client " + client.name + " disconnected"]}); + haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 503, className : "server.Main", methodName : "onMessage", customParams : ["Client " + client.name + " disconnected"]}); server_Utils.sortedPush(this.freeIds,client.id); HxOverrides.remove(this.clients,client); this.sendClientList(); @@ -5155,12 +4894,6 @@ server_Main.prototype = { } this.send(client,obj); break; - case "GetYoutubeVideoInfo": - var url = data.getYoutubeVideoInfo.url; - server_YoutubeFallback.getInfo(url,function(info) { - _gthis.send(client,{ type : data.type, getYoutubeVideoInfo : { url : url, response : info}}); - }); - break; case "KickClient": if(!this.checkPermission(client,"banClient")) { return; @@ -5205,7 +4938,7 @@ server_Main.prototype = { this.send(client,{ type : "LoginError"}); return; } - haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 577, 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 : 591, className : "server.Main", methodName : "onMessage", customParams : ["Client " + client.name + " logged as " + name]}); client.name = name; client.setGroupFlag(ClientGroup.User,true); this.checkBan(client); @@ -5218,7 +4951,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 : 598, 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 : 612, 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; @@ -5298,15 +5031,15 @@ server_Main.prototype = { if(this.videoList.items.length == 0) { return; } - var url1 = data.removeVideo.url; + var url = data.removeVideo.url; var index = this.videoList.findIndex(function(item) { - return item.url == url1; + return item.url == url; }); if(index == -1) { return; } var _this = this.videoList; - var isCurrent = _this.items[_this.pos].url == url1; + var isCurrent = _this.items[_this.pos].url == url; if(isCurrent && this.videoTimer.getTime() > 30) { var _this = this.videoList; this.saveFlashbackTime(_this.items[_this.pos]); @@ -5533,7 +5266,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 : 1010, className : "server.Main", methodName : "checkBan"}); + haxe_Log.trace("" + client.name + " ban removed",{ fileName : "src/server/Main.hx", lineNumber : 1025, className : "server.Main", methodName : "checkBan"}); this.sendClientList(); } break; @@ -5835,166 +5568,6 @@ server_VideoTimer.prototype = { } ,__class__: server_VideoTimer }; -var server_YoutubeFallback = function() { }; -server_YoutubeFallback.__name__ = true; -server_YoutubeFallback.httpsGet = function(url,options,callback) { - var request = js_node_Https.get(url,options,function(res) { - var data = ""; - res.on("data",function(chunk) { - data += chunk.toString(); - return data; - }); - res.on("end",function() { - callback(res.statusCode,data); - }); - }); - request.on("error",function(err) { - haxe_Log.trace(url,{ fileName : "src/server/YoutubeFallback.hx", lineNumber : 24, className : "server.YoutubeFallback", methodName : "httpsGet"}); - haxe_Log.trace("request error: ",{ fileName : "src/server/YoutubeFallback.hx", lineNumber : 25, className : "server.YoutubeFallback", methodName : "httpsGet", customParams : [err]}); - }); -}; -server_YoutubeFallback.resolvePlayerResponse = function(watchHtml) { - if(watchHtml == null) { - return ""; - } - var resReg = new EReg("ytInitialPlayerResponse = (.*)}}};",""); - if(resReg.match(watchHtml)) { - return resReg.matched(1) + "}}}"; - } else { - return ""; - } -}; -server_YoutubeFallback.resoleM3U8Link = function(watchHtml) { - if(watchHtml == null) { - return null; - } - var hlsReg = new EReg("hlsManifestUrl\":\"(.*/file/index\\.m3u8)",""); - if(hlsReg.match(watchHtml)) { - return hlsReg.matched(1); - } else { - return null; - } -}; -server_YoutubeFallback.buildDecoder = function(watchHtml,callback) { - if(watchHtml == null) { - callback(null); - return; - } - var jsFileUrlReg = new EReg("/s/player/[A-Za-z0-9]+/[A-Za-z0-9_.]+/[A-Za-z0-9_]+/base\\.js",""); - if(!jsFileUrlReg.match(watchHtml)) { - callback(null); - return; - } - var url = "https://www.youtube.com" + jsFileUrlReg.matched(0); - server_YoutubeFallback.httpsGet(url,{ },function(status,jsFileContent) { - var funcReg = new EReg("function.*\\.split\\(\"\"\\).*\\.join\\(\"\"\\)}",""); - if(!funcReg.match(jsFileContent)) { - callback(null); - return; - } - var decodeFunction = funcReg.matched(0); - var varNameReg = new EReg("\\.split\\(\"\"\\);([a-zA-Z0-9]+)\\.","i"); - if(!varNameReg.match(decodeFunction)) { - callback(null); - return; - } - var varStartIndex = jsFileContent.indexOf("var " + varNameReg.matched(1) + "={"); - if(varStartIndex < 0) { - callback(null); - return; - } - var varEndIndex = jsFileContent.indexOf("}};",varStartIndex); - if(varEndIndex < 0) { - callback(null); - return; - } - var varDeclares = jsFileContent.substring(varStartIndex,varEndIndex + 3); - if(varDeclares.length == 0) { - callback(null); - return; - } - callback(function(signatureCipher) { - var params = new js_node_url_URLSearchParams(signatureCipher); - var obj = Object.fromEntries(params); - var signature = obj.s; - var tmp = obj.sp; - var signatureParam = tmp != null ? tmp : "signature"; - var url = obj.url; - var decodedSignature = new Function("\n\t\t\t\t\t\"use strict\";\n\t\t\t\t\t" + varDeclares + "\n\t\t\t\t\treturn (" + decodeFunction + ")(\"" + signature + "\");\n\t\t\t\t").call(null); - return "" + url + "&" + signatureParam + "=" + encodeURIComponent(decodedSignature); - }); - }); -}; -server_YoutubeFallback.getInfo = function(url,callback) { - var videoId = utils_YoutubeUtils.extractVideoId(url); - if(videoId.length == 0) { - haxe_Log.trace("youtube videoId is not found",{ fileName : "src/server/YoutubeFallback.hx", lineNumber : 85, className : "server.YoutubeFallback", methodName : "getInfo"}); - callback(null); - return; - } - server_YoutubeFallback.httpsGet("https://www.youtube.com/watch?v=" + videoId,{ },function(status,data) { - if(status != 200 || data.length == 0) { - haxe_Log.trace("Cannot get youtube video response",{ fileName : "src/server/YoutubeFallback.hx", lineNumber : 92, className : "server.YoutubeFallback", methodName : "getInfo"}); - callback(null); - return; - } - var parsedResponse = JSON.parse(server_YoutubeFallback.resolvePlayerResponse(data)); - var tmp = parsedResponse.streamingData; - var streamingData = tmp != null ? tmp : { }; - streamingData.formats = streamingData.formats != null ? streamingData.formats : []; - streamingData.adaptiveFormats = streamingData.adaptiveFormats != null ? streamingData.adaptiveFormats : []; - var formats = streamingData.formats.concat(streamingData.adaptiveFormats); - var promises = []; - if(Lambda.exists(formats,function(it) { - return it.signatureCipher != null; - })) { - var promise = new Promise(function(resolve,reject) { - server_YoutubeFallback.buildDecoder(data,function(decoder) { - if(decoder != null) { - var result = new Array(formats.length); - var _g = 0; - var _g1 = formats.length; - while(_g < _g1) { - var i = _g++; - var item = formats[i]; - var formats1; - if(item.url != null || item.signatureCipher == null) { - formats1 = item; - } else { - item.url = decoder(item.signatureCipher); - item.signatureCipher = null; - formats1 = item; - } - result[i] = formats1; - } - formats = result; - } - resolve(null); - }); - }); - promises.push(promise); - } - Promise.all(promises).then(function(_) { - var tmp = parsedResponse.videoDetails; - var result = tmp != null ? tmp : { }; - var _g = []; - var _g1 = 0; - var _g2 = formats; - while(_g1 < _g2.length) { - var v = _g2[_g1]; - ++_g1; - if(v.url != null) { - _g.push(v); - } - } - var result1 = { videoDetails : result, formats : _g}; - if(result1.videoDetails.isLiveContent) { - result1.liveData = { manifestUrl : server_YoutubeFallback.resoleM3U8Link(data)}; - } - callback(result1); - }); - }); -}; var sys_FileSystem = function() { }; sys_FileSystem.__name__ = true; sys_FileSystem.exists = function(path) { diff --git a/default-config.json b/default-config.json index a8006f7..15dfc6c 100644 --- a/default-config.json +++ b/default-config.json @@ -13,6 +13,7 @@ "templateUrl": "https://youtube.com/playlist?list=PL9FiZUDVMu9tc_85frYognMOVFC_-VkSX", "youtubeApiKey": "AIzaSyDTk1OPRI9cDkAK_BKsBcv10DQCHse-QaA", "youtubePlaylistLimit": 50, + "cacheStorageLimitGiB": 3.0, "permissions": { "banned": [], "guest": ["writeChat", "addVideo", "removeVideo", "changeOrder", "toggleItemType", "requestLeader", "rewind"], diff --git a/res/client.js b/res/client.js index d26396f..338ed34 100644 --- a/res/client.js +++ b/res/client.js @@ -484,7 +484,7 @@ StringTools.hex = function(n,digits) { var _$Types_VideoItemTools = function() { }; _$Types_VideoItemTools.__name__ = true; _$Types_VideoItemTools.withUrl = function(item,url) { - return { url : url, title : item.title, author : item.author, duration : item.duration, subs : item.subs, voiceOverTrack : item.voiceOverTrack, isTemp : item.isTemp, isIframe : item.isIframe}; + return { url : url, title : item.title, author : item.author, duration : item.duration, subs : item.subs, voiceOverTrack : item.voiceOverTrack, isTemp : item.isTemp, doCache : item.doCache, playerType : item.playerType}; }; var VideoList = function() { this.items = []; @@ -559,6 +559,21 @@ client_Buttons.init = function(main) { client_Buttons.initSplit(); client_Buttons.setSplitSize(client_Buttons.settings.chatSize); client_Buttons.initChatInput(main); + var _g = 0; + var _g1 = client_Buttons.settings.checkboxes; + while(_g < _g1.length) { + var item = _g1[_g]; + ++_g; + if(item.checked == null) { + continue; + } + var id = "#" + item.id; + var tmp = window.document.querySelector(id); + if(tmp == null) { + continue; + } + tmp.checked = item.checked; + } var passIcon = window.document.querySelector("#guestpass_icon"); passIcon.onclick = function(e) { var icon = passIcon.firstElementChild; @@ -760,12 +775,16 @@ client_Buttons.init = function(main) { }; var mediaUrl = window.document.querySelector("#mediaurl"); mediaUrl.oninput = function() { - var value = mediaUrl.value; - var isRawSingleVideo = value != "" && main.isRawPlayerLink(value) && main.isSingleVideoLink(value); - window.document.querySelector("#mediatitleblock").style.display = isRawSingleVideo ? "" : "none"; - window.document.querySelector("#subsurlblock").style.display = isRawSingleVideo ? "" : "none"; - var tmp = value.length > 0 ? "" : "none"; - window.document.querySelector("#voiceoverblock").style.display = tmp; + var url = mediaUrl.value; + var playerType = main.getLinkPlayerType(url); + var isSingle = main.isSingleVideoUrl(url); + var isSingleRawVideo = url != "" && playerType == "RawType" && isSingle; + window.document.querySelector("#mediatitleblock").style.display = isSingleRawVideo ? "" : "none"; + window.document.querySelector("#subsurlblock").style.display = isSingleRawVideo ? "" : "none"; + var tmp = url.length > 0 && isSingle; + window.document.querySelector("#voiceoverblock").style.display = tmp ? "" : "none"; + var tmp = isSingle && main.playersCacheSupport.indexOf(playerType) != -1 ? "" : "none"; + window.document.querySelector("#cache-on-server").parentElement.style.display = tmp; var panel = window.document.querySelector("#addfromurl"); var oldH = panel.style.height; panel.style.height = ""; @@ -1043,6 +1062,25 @@ client_Buttons.initChatInput = function(main) { } return true; }); + var checkboxes = [window.document.querySelector("#add-temp"),window.document.querySelector("#cache-on-server")]; + var _g = 0; + while(_g < checkboxes.length) { + var checkbox = [checkboxes[_g]]; + ++_g; + checkbox[0].addEventListener("change",(function(checkbox) { + return function() { + var checked = checkbox[0].checked; + var item = Lambda.find(client_Buttons.settings.checkboxes,(function(checkbox) { + return function(item) { + return item.id == checkbox[0].id; + }; + })(checkbox)); + HxOverrides.remove(client_Buttons.settings.checkboxes,item); + client_Buttons.settings.checkboxes.push({ id : checkbox[0].id, checked : checked}); + client_Settings.write(client_Buttons.settings); + }; + })(checkbox)); + } }; client_Buttons.initPageFullscreen = function() { window.document.onfullscreenchange = function(e) { @@ -1175,8 +1213,11 @@ client_JsApi.getVideoItems = $hx_exports["client"]["JsApi"]["getVideoItems"] = f while(_g1 < items.length) _g.push(Reflect.copy(items[_g1++])); return _g; }; -client_JsApi.addVideoItem = $hx_exports["client"]["JsApi"]["addVideoItem"] = function(url,atEnd,isTemp,callback) { - client_JsApi.main.addVideo(url,atEnd,isTemp,callback); +client_JsApi.addVideoItem = $hx_exports["client"]["JsApi"]["addVideoItem"] = function(url,atEnd,isTemp,callback,doCache) { + if(doCache == null) { + doCache = false; + } + client_JsApi.main.addVideo(url,atEnd,isTemp,doCache,callback); }; client_JsApi.removeVideoItem = $hx_exports["client"]["JsApi"]["removeVideoItem"] = function(url) { client_JsApi.main.removeVideoItem(url); @@ -1254,7 +1295,7 @@ client_JsApi.fireVideoRemoveEvents = function(item) { }; var client_Main = function() { this.matchSimpleDate = new EReg("^-?([0-9]+d)?([0-9]+h)?([0-9]+m)?([0-9]+s?)?$",""); - this.mask = new EReg("\\${([0-9]+)-([0-9]+)}","g"); + this.urlMask = new EReg("\\${([0-9]+)-([0-9]+)}","g"); this.gotFirstPageInteraction = false; this.disabledReconnection = false; this.gotInitialConnection = false; @@ -1263,6 +1304,7 @@ var client_Main = function() { this.filters = []; this.pageTitle = window.document.title; this.clients = []; + this.playersCacheSupport = []; this.isPlaylistOpen = true; this.globalIp = ""; this.isVideoEnabled = true; @@ -1275,7 +1317,7 @@ var client_Main = function() { if(this.host == "") { this.host = "localhost"; } - client_Settings.init({ version : 4, uuid : null, name : "", hash : "", isExtendedPlayer : false, playerSize : 1, chatSize : 300, synchThreshold : 2, isSwapped : false, isUserListHidden : true, latestLinks : [], latestSubs : [], hotkeysEnabled : true, showHintList : true},$bind(this,this.settingsPatcher)); + client_Settings.init({ version : 5, uuid : null, name : "", hash : "", isExtendedPlayer : false, playerSize : 1, chatSize : 300, synchThreshold : 2, isSwapped : false, isUserListHidden : true, latestLinks : [], latestSubs : [], hotkeysEnabled : true, showHintList : true, checkboxes : []},$bind(this,this.settingsPatcher)); this.settings = client_Settings.read(); this.initListeners(); this.onTimeGet = new haxe_Timer(this.settings.synchThreshold * 1000); @@ -1330,7 +1372,9 @@ client_Main.prototype = { } this.gotFirstPageInteraction = true; this.player.unmute(); - this.player.play(); + if(!this.hasLeader()) { + this.player.play(); + } window.document.removeEventListener("click",$bind(this,this.onFirstInteraction)); } ,settingsPatcher: function(data,version) { @@ -1345,6 +1389,9 @@ client_Main.prototype = { data.showHintList = true; break; case 4: + data.checkboxes = []; + break; + case 5: throw haxe_Exception.thrown("skipped version " + version); default: throw haxe_Exception.thrown("skipped version " + version); @@ -1463,11 +1510,11 @@ client_Main.prototype = { while(_g < links.length) { var link = links[_g]; ++_g; - if(!this.mask.match(link)) { + if(!this.urlMask.match(link)) { continue; } - var start = Std.parseInt(this.mask.matched(1)); - var end = Std.parseInt(this.mask.matched(2)); + var start = Std.parseInt(this.urlMask.matched(1)); + var end = Std.parseInt(this.urlMask.matched(2)); if(Math.abs(start - end) > 100) { continue; } @@ -1475,7 +1522,7 @@ client_Main.prototype = { var i = links.indexOf(link); HxOverrides.remove(links,link); while(end != start + step) { - var x = link.replace(this.mask.r,"" + end); + var x = link.replace(this.urlMask.r,"" + end); links.splice(i,0,x); end += step; } @@ -1484,7 +1531,9 @@ client_Main.prototype = { ,addVideoUrl: function(atEnd) { var mediaUrl = window.document.querySelector("#mediaurl"); var subsUrl = window.document.querySelector("#subsurl"); - var isTemp = window.document.querySelector("#addfromurl").querySelector(".add-temp").checked; + var isTemp = window.document.querySelector("#addfromurl .add-temp").checked; + var checkboxCache = window.document.querySelector("#cache-on-server"); + var doCache = checkboxCache.checked && checkboxCache.parentElement.style.display != "none"; var url = mediaUrl.value; var subs = subsUrl.value; if(url.length == 0) { @@ -1502,19 +1551,13 @@ client_Main.prototype = { if(!atEnd) { this.sortItemsForQueueNext(links); } - this.addVideoArray(links,atEnd,isTemp); + this.addVideoArray(links,atEnd,isTemp,doCache); } - ,isRawPlayerLink: function(url) { - return this.player.isRawPlayerLink(url); + ,getLinkPlayerType: function(url) { + return this.player.getLinkPlayerType(url); } - ,isSingleVideoLink: function(url) { - if(new EReg(", ?(https?)","g").match(url)) { - return false; - } - if(this.mask.match(url)) { - return false; - } - return true; + ,isSingleVideoUrl: function(url) { + return this.player.isSingleVideoUrl(url); } ,sortItemsForQueueNext: function(items) { if(items.length == 0) { @@ -1529,16 +1572,16 @@ client_Main.prototype = { items.unshift(first); } } - ,addVideoArray: function(links,atEnd,isTemp) { + ,addVideoArray: function(links,atEnd,isTemp,doCache) { var _gthis = this; if(links.length == 0) { return; } - this.addVideo(links.shift(),atEnd,isTemp,function() { - _gthis.addVideoArray(links,atEnd,isTemp); + this.addVideo(links.shift(),atEnd,isTemp,doCache,function() { + _gthis.addVideoArray(links,atEnd,isTemp,doCache); }); } - ,addVideo: function(url,atEnd,isTemp,callback) { + ,addVideo: function(url,atEnd,isTemp,doCache,callback) { var _gthis = this; var protocol = $global.location.protocol; if(StringTools.startsWith(url,"/")) { @@ -1556,7 +1599,7 @@ client_Main.prototype = { } data.title = data.title != null ? data.title : Lang.get("rawVideo"); data.url = data.url != null ? data.url : url; - _gthis.send({ type : "AddVideo", addVideo : { item : { url : data.url, title : data.title, author : _gthis.personal.name, duration : data.duration, isTemp : isTemp, subs : data.subs, voiceOverTrack : data.voiceOverTrack, isIframe : data.isIframe == true}, atEnd : atEnd}}); + _gthis.send({ type : "AddVideo", addVideo : { item : { url : data.url, title : data.title, author : _gthis.personal.name, duration : data.duration, isTemp : isTemp, doCache : doCache, subs : data.subs, voiceOverTrack : data.voiceOverTrack, playerType : data.playerType}, atEnd : atEnd}}); if(callback != null) { callback(); } @@ -1573,7 +1616,7 @@ client_Main.prototype = { var mediaTitle = window.document.querySelector("#customembed-title"); var title = mediaTitle.value; mediaTitle.value = ""; - var isTemp = window.document.querySelector("#customembed").querySelector(".add-temp").checked; + var isTemp = window.document.querySelector("#customembed .add-temp").checked; this.player.getIframeData({ url : iframe, atEnd : atEnd},function(data) { if(data.duration == 0) { client_Main.serverMessage(Lang.get("addVideoError")); @@ -1584,7 +1627,7 @@ client_Main.prototype = { } data.title = data.title != null ? data.title : "Custom Media"; data.url = data.url != null ? data.url : iframe; - _gthis.send({ type : "AddVideo", addVideo : { item : { url : data.url, title : data.title, author : _gthis.personal.name, duration : data.duration, isTemp : isTemp, isIframe : true}, atEnd : atEnd}}); + _gthis.send({ type : "AddVideo", addVideo : { item : { url : data.url, title : data.title, author : _gthis.personal.name, duration : data.duration, isTemp : isTemp, doCache : false, playerType : "IframeType"}, atEnd : atEnd}}); }); } ,removeVideoItem: function(url) { @@ -1625,7 +1668,7 @@ client_Main.prototype = { 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 : 433, 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 : 443, className : "client.Main", methodName : "onMessage", customParams : [Reflect.field(data,t.charAt(0).toLowerCase() + HxOverrides.substr(t,1,null))]}); } client_JsApi.fireOnceEvent(data); switch(data.type) { @@ -1696,8 +1739,6 @@ client_Main.prototype = { this.player.setTime(newTime); } break; - case "GetYoutubeVideoInfo": - break; case "KickClient": var tmp = "*" + Lang.get("kicked"); window.document.title = tmp + "*"; @@ -1730,6 +1771,7 @@ client_Main.prototype = { break; case "Pause": this.player.setPauseIndicator(false); + this.updateUserList(); if((this.personal.group & 4) != 0) { return; } @@ -1738,6 +1780,7 @@ client_Main.prototype = { break; case "Play": this.player.setPauseIndicator(true); + this.updateUserList(); if((this.personal.group & 4) != 0) { return; } @@ -1828,6 +1871,7 @@ client_Main.prototype = { this.settings.uuid = connected.uuid; client_Settings.write(this.settings); this.globalIp = connected.globalIp; + this.playersCacheSupport = connected.playersCacheSupport; this.setConfig(connected.config); if(connected.isUnknownClient) { this.updateClients(connected.clients); @@ -2106,8 +2150,9 @@ client_Main.prototype = { var client = _g1[_g]; ++_g; list_b += "<div class=\"userlist_item\">"; + var iconName = this.player.isPaused() ? "pause" : "play"; if((client.group & 4) != 0) { - list_b += "<ion-icon name=\"play\"></ion-icon>"; + list_b += Std.string("<ion-icon name=\"" + iconName + "\"></ion-icon>"); } var klass = (client.group & 1) != 0 ? "userlist_banned" : ""; if((client.group & 8) != 0) { @@ -2446,10 +2491,6 @@ client_Player.prototype = { var el = this.videoItemsEl.children[pos]; this.setItemElementType(el,this.videoList.items[pos].isTemp); } - ,getCurrentItem: function() { - var _this = this.videoList; - return _this.items[_this.pos]; - } ,setPlayer: function(newPlayer) { if(this.player != newPlayer) { if(this.player != null) { @@ -2471,29 +2512,48 @@ client_Player.prototype = { player = this.rawPlayer; } player.getVideoData(req,function(data) { + data.playerType = data.playerType != null ? data.playerType : player.getPlayerType(); var voiceOverTrack = StringTools.trim(_gthis.voiceOverInput.value); - data.voiceOverTrack = voiceOverTrack; _gthis.voiceOverInput.value = ""; + data.voiceOverTrack = data.voiceOverTrack != null ? data.voiceOverTrack : voiceOverTrack; callback(data); }); } - ,isRawPlayerLink: function(url) { - if(this.streamable.isSupportedLink(url)) { - return true; - } - return !Lambda.exists(this.players,function(player) { + ,getLinkPlayerType: function(url) { + var player = Lambda.find(this.players,function(player) { return player.isSupportedLink(url); }); + if(player == null) { + return this.rawPlayer.getPlayerType(); + } + return player.getPlayerType(); + } + ,isSingleVideoUrl: function(url) { + if(this.youtube.isSupportedLink(url)) { + if(this.youtube.isPlaylistUrl(url)) { + return false; + } + } + if(new EReg(", ?(https?)","g").match(url)) { + return false; + } + if(this.main.urlMask.match(url)) { + return false; + } + return true; } ,getIframeData: function(data,callback) { - this.iframePlayer.getVideoData(data,callback); + this.iframePlayer.getVideoData(data,function(data) { + data.playerType = "IframeType"; + callback(data); + }); } ,setVideo: function(i) { if(!this.main.isSyncActive) { return; } var item = this.videoList.items[i]; - this.setSupportedPlayer(item.url,item.isIframe); + this.setSupportedPlayer(item.url,item.playerType); this.removeActiveLabel(this.videoList.pos); this.videoList.setPos(i); this.addActiveLabel(this.videoList.pos); @@ -2527,7 +2587,7 @@ client_Player.prototype = { return _gthis.isAudioTrackLoaded = true; }; this.audioTrack.onerror = function(e) { - haxe_Log.trace(e,{ fileName : "src/client/Player.hx", lineNumber : 174, className : "client.Player", methodName : "setExternalAudioTrack"}); + haxe_Log.trace(e,{ fileName : "src/client/Player.hx", lineNumber : 189, className : "client.Player", methodName : "setExternalAudioTrack"}); _gthis.audioTrack.oncanplay = null; _gthis.audioTrack.onerror = null; _gthis.isAudioTrackLoaded = false; @@ -2549,13 +2609,13 @@ client_Player.prototype = { this.audioTrack = null; this.needsVolumeReset = true; } - ,setSupportedPlayer: function(url,isIframe) { + ,setSupportedPlayer: function(url,playerType) { var currentPlayer = Lambda.find(this.players,function(p) { return p.isSupportedLink(url); }); if(currentPlayer != null) { this.setPlayer(currentPlayer); - } else if(isIframe) { + } else if(playerType == "IframeType") { this.setPlayer(this.iframePlayer); } else { this.setPlayer(this.rawPlayer); @@ -2570,7 +2630,7 @@ client_Player.prototype = { if(tmp == null) { return; } - this.setSupportedPlayer(url,tmp.isIframe); + this.setSupportedPlayer(url,tmp.playerType); this.player.loadVideo(_$Types_VideoItemTools.withUrl(tmp,url)); } ,removeVideo: function() { @@ -2626,11 +2686,6 @@ client_Player.prototype = { if(this.getTime() >= tmp.duration - 0.01) { return; } - if(this.player == this.rawPlayer && this.youtube.isSupportedLink(tmp.url)) { - if(this.getTime() >= tmp.duration - 1) { - return; - } - } if(this.main.hasLeaderOnPauseRequest() && this.videoList.items.length > 0 && this.getTime() > 1 && this.isLoaded && !this.main.hasLeader()) { client_JsApi.once("SetLeader",function(event) { if(event.setLeader.clientName != _gthis.main.personal.name) { @@ -2675,7 +2730,7 @@ client_Player.prototype = { } ,addVideoItem: function(item,atEnd) { var url = StringTools.htmlEscape(item.url,true); - var duration = item.isIframe ? "" : this.duration(item.duration); + var duration = item.playerType == "IframeType" ? "" : this.duration(item.duration); var itemEl = client_Utils.nodeFromString("<li class=\"queue_entry info\" title=\"" + Lang.get("addedBy") + ": " + item.author + "\">\n\t\t\t\t<header>\n\t\t\t\t\t<span class=\"qe_time\">" + duration + "</span>\n\t\t\t\t\t<h4><a class=\"qe_title\" href=\"" + url + "\" target=\"_blank\">" + StringTools.htmlEscape(item.title) + "</a></h4>\n\t\t\t\t</header>\n\t\t\t\t<span class=\"controls\">\n\t\t\t\t\t<button class=\"qbtn-play\" title=\"" + Lang.get("play") + "\"><ion-icon name=\"play\"></ion-icon></button>\n\t\t\t\t\t<button class=\"qbtn-next\" title=\"" + Lang.get("setNext") + "\"><ion-icon name=\"arrow-up\"></ion-icon></button>\n\t\t\t\t\t<button class=\"qbtn-tmp\"><ion-icon></ion-icon></button>\n\t\t\t\t\t<button class=\"qbtn-delete\" title=\"" + Lang.get("delete") + "\"><ion-icon name=\"close\"></ion-icon></button>\n\t\t\t\t</span>\n\t\t\t</li>"); this.videoList.addItem(item,atEnd); this.setItemElementType(itemEl,item.isTemp); @@ -2828,7 +2883,7 @@ client_Player.prototype = { while(_g < _g1.length) { var item = _g1[_g]; ++_g; - if(item.isIframe) { + if(item.playerType == "IframeType") { continue; } time += item.duration; @@ -2985,7 +3040,7 @@ client_Player.prototype = { } }; http.onError = function(msg) { - haxe_Log.trace(msg,{ fileName : "src/client/Player.hx", lineNumber : 564, className : "client.Player", methodName : "skipAd"}); + haxe_Log.trace(msg,{ fileName : "src/client/Player.hx", lineNumber : 577, className : "client.Player", methodName : "skipAd"}); }; http.request(); } @@ -3228,12 +3283,15 @@ var client_players_Iframe = function(main,player) { }; client_players_Iframe.__name__ = true; client_players_Iframe.prototype = { - isSupportedLink: function(url) { + getPlayerType: function() { + return "IframeType"; + } + ,isSupportedLink: function(url) { return true; } ,getVideoData: function(data,callback) { var iframe = window.document.createElement("div"); - iframe.innerHTML = data.url; + iframe.innerHTML = StringTools.trim(data.url); if(this.isValidIframe(iframe)) { callback({ duration : 356400}); } else { @@ -3311,7 +3369,10 @@ var client_players_Raw = function(main,player) { }; client_players_Raw.__name__ = true; client_players_Raw.prototype = { - isSupportedLink: function(url) { + getPlayerType: function() { + return "RawType"; + } + ,isSupportedLink: function(url) { return true; } ,getVideoData: function(data,callback) { @@ -3813,7 +3874,10 @@ var client_players_Youtube = function(main,player) { }; client_players_Youtube.__name__ = true; client_players_Youtube.prototype = { - isSupportedLink: function(url) { + getPlayerType: function() { + return "YoutubeType"; + } + ,isSupportedLink: function(url) { if(this.extractVideoId(url) == "") { return this.extractPlaylistId(url) != ""; } else { @@ -3826,6 +3890,13 @@ client_players_Youtube.prototype = { ,extractPlaylistId: function(url) { return utils_YoutubeUtils.extractPlaylistId(url); } + ,isPlaylistUrl: function(url) { + if(this.extractVideoId(url) == "") { + return this.extractPlaylistId(url) != ""; + } else { + return false; + } + } ,convertTime: function(duration) { var total = 0; var hours = this.matchHours.match(duration); @@ -3872,7 +3943,7 @@ client_players_Youtube.prototype = { var duration = _gthis.convertTime(item.contentDetails.duration); if(duration == 0) { var mute = _gthis.main.isAutoplayAllowed() ? "" : "&mute=1"; - callback({ duration : 356400, title : title, url : "<iframe src=\"https://www.youtube.com/embed/" + id + "?autoplay=1" + mute + "\" frameborder=\"0\"\n\t\t\t\t\t\t\tallow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\"\n\t\t\t\t\t\t\tallowfullscreen></iframe>", isIframe : true}); + callback({ duration : 356400, title : title, url : "<iframe src=\"https://www.youtube.com/embed/" + id + "?autoplay=1" + mute + "\" frameborder=\"0\"\n\t\t\t\t\t\t\tallow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\"\n\t\t\t\t\t\t\tallowfullscreen></iframe>", playerType : "IframeType"}); continue; } callback({ duration : duration, title : title, url : url}); @@ -3945,17 +4016,20 @@ client_players_Youtube.prototype = { var video = window.document.createElement("div"); video.id = "temp-videoplayer"; client_Utils.prepend(this.playerEl,video); - this.tempYoutube = new YT.Player(video.id,{ videoId : this.extractVideoId(url), playerVars : { modestbranding : 1, rel : 0, showinfo : 0}, events : { onReady : function(e) { + var tempYoutube = null; + tempYoutube = new YT.Player(video.id,{ videoId : this.extractVideoId(url), playerVars : { modestbranding : 1, rel : 0, showinfo : 0}, events : { onReady : function(e) { if(_gthis.playerEl.contains(video)) { _gthis.playerEl.removeChild(video); } - callback({ duration : _gthis.tempYoutube.getDuration()}); + callback({ duration : tempYoutube.getDuration()}); + tempYoutube.destroy(); }, onError : function(e) { - haxe_Log.trace("Error " + e.data,{ fileName : "src/client/players/Youtube.hx", lineNumber : 187, className : "client.players.Youtube", methodName : "getRemoteDataFallback"}); + haxe_Log.trace("Error " + e.data,{ fileName : "src/client/players/Youtube.hx", lineNumber : 197, className : "client.players.Youtube", methodName : "getRemoteDataFallback"}); if(_gthis.playerEl.contains(video)) { _gthis.playerEl.removeChild(video); } callback({ duration : 0}); + tempYoutube.destroy(); }}}); } ,loadVideo: function(item) { @@ -4002,54 +4076,9 @@ client_players_Youtube.prototype = { }, onPlaybackRateChange : function(e) { _gthis.player.onRateChange(); }, onError : function(e) { - haxe_Log.trace("Error " + e.data,{ fileName : "src/client/players/Youtube.hx", lineNumber : 245, className : "client.players.Youtube", methodName : "loadVideo"}); - var tmp = _gthis.player.getCurrentItem(); - if(tmp == null) { - return; - } - _gthis.rawSourceFallback(tmp.url); + haxe_Log.trace("Error " + e.data,{ fileName : "src/client/players/Youtube.hx", lineNumber : 256, className : "client.players.Youtube", methodName : "loadVideo"}); }}}); } - ,rawSourceFallback: function(url) { - var _gthis = this; - client_JsApi.once("GetYoutubeVideoInfo",function(event) { - var info = event.getYoutubeVideoInfo.response; - var tmp = _gthis.getBestStreamFormat(info); - if(tmp == null) { - haxe_Log.trace("format not found in response info:",{ fileName : "src/client/players/Youtube.hx", lineNumber : 258, className : "client.players.Youtube", methodName : "rawSourceFallback"}); - haxe_Log.trace(info,{ fileName : "src/client/players/Youtube.hx", lineNumber : 259, className : "client.players.Youtube", methodName : "rawSourceFallback"}); - return; - } - _gthis.player.changeVideoSrc(tmp.url); - }); - this.main.send({ type : "GetYoutubeVideoInfo", getYoutubeVideoInfo : { url : url}}); - } - ,getBestStreamFormat: function(info) { - info.formats = info.formats != null ? info.formats : []; - info.adaptiveFormats = info.adaptiveFormats != null ? info.adaptiveFormats : []; - var formats = info.adaptiveFormats.concat(info.formats); - haxe_Log.trace(formats,{ fileName : "src/client/players/Youtube.hx", lineNumber : 276, className : "client.players.Youtube", methodName : "getBestStreamFormat"}); - var qPriority = [1080,720,480,360,240]; - var _g = 0; - while(_g < qPriority.length) { - var quality = "" + qPriority[_g++] + "p"; - var _g1 = 0; - while(_g1 < formats.length) { - var format = formats[_g1]; - ++_g1; - if(format.audioQuality == null) { - continue; - } - if(format.width == null) { - continue; - } - if(format.qualityLabel == quality) { - return format; - } - } - } - return null; - } ,removeVideo: function() { if(this.video == null) { return; diff --git a/res/css/des.css b/res/css/des.css index bd5606d..bd354a7 100644 --- a/res/css/des.css +++ b/res/css/des.css @@ -192,8 +192,24 @@ button span { /* Input */ -label { - font-weight: bold; +.checkbox-row { + text-align: left; + padding-left: 1.7rem; +} + +.checkbox-row-item { + display: inline-flex; + align-items: center; + text-align: left; + white-space: nowrap; + padding: 0.3rem; + padding-right: .3rem; +} + +input[type="checkbox"] { + width: 1rem; + height: 1rem; + margin-right: .3rem; } input, @@ -432,13 +448,12 @@ header h4 { width: 100%; } -#addfromurl div, -#customembed div { +/* Queue */ + +.queue-buttons { text-align: right; } -/* Queue */ - .queue_temp { background-color: var(--background-chat); } diff --git a/res/index.html b/res/index.html index ec557c6..d9ddfd5 100644 --- a/res/index.html +++ b/res/index.html @@ -99,24 +99,30 @@ <div id="voiceoverblock" class="display-flex" style="display: none;"> <input id="voiceoverurl" type="text" placeholder="${voiceOverAudioTrackUrlOptional}"> </div> - <div> - <label> - <input class="add-temp" type="checkbox" checked="checked">${addAsTemporary} + <div class="checkbox-row"> + <label class="checkbox-row-item"> + <input id="add-temp" class="add-temp" type="checkbox" checked>${addAsTemporary} + </label> + <label class="checkbox-row-item"> + <input id="cache-on-server" type="checkbox">${cacheOnServer} </label> + </div> + <div class="queue-buttons"> <button id="queue_next">${queueNext}</button> <button id="queue_end">${queueLast}</button> </div> </div> </div> + <!-- Add iframe --> <div class="collapsible collapse" id="customembed" aria-expanded="false"> <div class="collapse-list"> <input id="customembed-title" type="text" placeholder="${optionalTitle}"> <textarea id="customembed-content" rows="5" - placeholder="${pasteEmbedCodeAndClick} '${queueNext}' ${or} '${queueLast}'. ${acceptableEmbedCodesAre} <iframe> ${or} <object>. ${customEmbedsCannotBeSynchronized}."></textarea> - <div> - <label> - <input class="add-temp" type="checkbox" checked="checked">${addAsTemporary} - </label> + placeholder="${pasteEmbedCodeAndClick}. ${acceptableEmbedCodesAre} <iframe> ${or} <object>. ${customEmbedsCannotBeSynchronized}."></textarea> + <label class="checkbox-row-item"> + <input id="add-temp-embed" class="add-temp" type="checkbox" checked>${addAsTemporary} + </label> + <div class="queue-buttons"> <button id="ce_queue_next">${queueNext}</button> <button id="ce_queue_end">${queueLast}</button> </div> diff --git a/res/langs/en.json b/res/langs/en.json index 488af78..881df6b 100644 --- a/res/langs/en.json +++ b/res/langs/en.json @@ -79,6 +79,7 @@ "retrievePlaylistLinks": "Retrieve playlist links", "voteForSkip": "Vote for skip", "addAsTemporary": "Add as temporary", + "cacheOnServer": "Cache on server", "mediaUrl": "Media URL", "optionalTitle": "Title (optional)", "subtitlesUrlOptional": "Subtitles URL (optional)", @@ -86,8 +87,9 @@ "addTemplateUrl": "Add template URL", "queueNext": "Queue next", "queueLast": "Queue last", + "and": "and", "or": "or", - "pasteEmbedCodeAndClick": "Paste the embed code below and click", + "pasteEmbedCodeAndClick": "Paste the embed code here", "acceptableEmbedCodesAre": "Acceptable embed codes are", "customEmbedsCannotBeSynchronized": "CUSTOM EMBEDS CANNOT BE SYNCHRONIZED", "save": "Save", diff --git a/res/langs/ru.json b/res/langs/ru.json index 49260cb..6257e87 100644 --- a/res/langs/ru.json +++ b/res/langs/ru.json @@ -79,6 +79,7 @@ "retrievePlaylistLinks": "Получить ссылки на видео из плейлиста", "voteForSkip": "Голосовать за пропуск", "addAsTemporary": "Добавить как временный", + "cacheOnServer": "Закэшировать на сервере", "mediaUrl": "Ссылка на видео", "optionalTitle": "Заголовок (опционально)", "subtitlesUrlOptional": "Ссылка на субтитры (опционально)", @@ -86,8 +87,9 @@ "addTemplateUrl": "Добавить пример ссылки", "queueNext": "След.", "queueLast": "В конец", + "and": "и", "or": "или", - "pasteEmbedCodeAndClick": "Вставьте код видео в поле ниже и нажмите", + "pasteEmbedCodeAndClick": "Вставьте код видео в это поле", "acceptableEmbedCodesAre": "Можно добавить видео с тегами", "customEmbedsCannotBeSynchronized": "СИНХРОНИЗАЦИЯ БУДЕТ НЕДОСТУПНА", "save": "Сохранить", diff --git a/src/Types.hx b/src/Types.hx index 8567f7b..0f56392 100644 --- a/src/Types.hx +++ b/src/Types.hx @@ -1,7 +1,12 @@ package; import Client.ClientData; -import utils.YoutubeUtils.YouTubeVideoInfo; + +enum abstract PlayerType(String) { + var RawType; + var YoutubeType; + var IframeType; +} typedef VideoDataRequest = { final url:String; @@ -14,7 +19,7 @@ typedef VideoData = { var ?url:String; var ?subs:String; var ?voiceOverTrack:String; - var ?isIframe:Bool; + var ?playerType:PlayerType; } typedef Config = { @@ -32,6 +37,7 @@ typedef Config = { templateUrl:String, youtubeApiKey:String, youtubePlaylistLimit:Int, + cacheStorageLimitGiB:Float, permissions:Permissions, emotes:Array<Emote>, filters:Array<Filter>, @@ -109,7 +115,8 @@ typedef VideoItem = { var ?subs:String; var ?voiceOverTrack:String; var isTemp:Bool; - var isIframe:Bool; + var doCache:Bool; + var playerType:PlayerType; } private class VideoItemTools { @@ -122,7 +129,8 @@ private class VideoItemTools { subs: item.subs, voiceOverTrack: item.voiceOverTrack, isTemp: item.isTemp, - isIframe: item.isIframe + doCache: item.doCache, + playerType: item.playerType }; } } @@ -145,7 +153,8 @@ typedef WsEvent = { videoList:Array<VideoItem>, isPlaylistOpen:Bool, itemPos:Int, - globalIp:String + globalIp:String, + playersCacheSupport:Array<PlayerType>, }, ?login:{ clientName:String, @@ -226,10 +235,6 @@ typedef WsEvent = { ?dump:{ data:String }, - ?getYoutubeVideoInfo:{ - url:String, - ?response:YouTubeVideoInfo - } } enum abstract WsEventType(String) { @@ -267,5 +272,4 @@ enum abstract WsEventType(String) { var UpdatePlaylist; var TogglePlaylistLock; var Dump; - var GetYoutubeVideoInfo; } diff --git a/src/client/Buttons.hx b/src/client/Buttons.hx index c3581e2..f5f26e8 100644 --- a/src/client/Buttons.hx +++ b/src/client/Buttons.hx @@ -22,6 +22,12 @@ class Buttons { setSplitSize(settings.chatSize); initChatInput(main); + for (item in settings.checkboxes) { + if (item.checked == null) continue; + final checkbox:InputElement = ge('#${item.id}') ?? continue; + checkbox.checked = item.checked; + } + final passIcon = ge("#guestpass_icon"); passIcon.onclick = e -> { final icon = passIcon.firstElementChild; @@ -213,12 +219,15 @@ class Buttons { final mediaUrl:InputElement = cast ge("#mediaurl"); mediaUrl.oninput = () -> { - final value = mediaUrl.value; - final isRawSingleVideo = value != "" && main.isRawPlayerLink(value) - && main.isSingleVideoLink(value); - ge("#mediatitleblock").style.display = isRawSingleVideo ? "" : "none"; - ge("#subsurlblock").style.display = isRawSingleVideo ? "" : "none"; - ge("#voiceoverblock").style.display = value.length > 0 ? "" : "none"; + final url = mediaUrl.value; + final playerType = main.getLinkPlayerType(url); + final isSingle = main.isSingleVideoUrl(url); + final isSingleRawVideo = url != "" && playerType == RawType && isSingle; + ge("#mediatitleblock").style.display = isSingleRawVideo ? "" : "none"; + ge("#subsurlblock").style.display = isSingleRawVideo ? "" : "none"; + ge("#voiceoverblock").style.display = (url.length > 0 && isSingle) ? "" : "none"; + final showCache = isSingle && main.playersCacheSupport.contains(playerType); + ge("#cache-on-server").parentElement.style.display = showCache ? "" : "none"; final panel = ge("#addfromurl"); final oldH = panel.style.height; // save for animation panel.style.height = ""; // to calculate height from content @@ -482,6 +491,19 @@ class Buttons { if (Utils.isTouch()) chatline.blur(); return true; }); + final checkboxes:Array<InputElement> = [ + ge("#add-temp"), + ge("#cache-on-server"), + ]; + for (checkbox in checkboxes) { + checkbox.addEventListener("change", () -> { + final checked = checkbox.checked; + final item = settings.checkboxes.find(item -> item.id == checkbox.id); + settings.checkboxes.remove(item); + settings.checkboxes.push({id: checkbox.id, checked: checked}); + Settings.write(settings); + }); + } } static inline function getVisualViewport():Null<VisualViewport> { diff --git a/src/client/ClientSettings.hx b/src/client/ClientSettings.hx index a004213..cb5f99f 100644 --- a/src/client/ClientSettings.hx +++ b/src/client/ClientSettings.hx @@ -14,5 +14,6 @@ typedef ClientSettings = { latestLinks:Array<String>, latestSubs:Array<String>, hotkeysEnabled:Bool, - showHintList:Bool + showHintList:Bool, + checkboxes:Array<{id:String, checked:Null<Bool>}>, } diff --git a/src/client/IPlayer.hx b/src/client/IPlayer.hx index 032ac97..e8835d1 100644 --- a/src/client/IPlayer.hx +++ b/src/client/IPlayer.hx @@ -1,10 +1,12 @@ package client; +import Types.PlayerType; import Types.VideoData; import Types.VideoDataRequest; import Types.VideoItem; interface IPlayer { + function getPlayerType():PlayerType; function isSupportedLink(url:String):Bool; function getVideoData(data:VideoDataRequest, callback:(data:VideoData) -> Void):Void; function loadVideo(item:VideoItem):Void; diff --git a/src/client/JsApi.hx b/src/client/JsApi.hx index 1532231..abf9a6a 100644 --- a/src/client/JsApi.hx +++ b/src/client/JsApi.hx @@ -72,8 +72,9 @@ class JsApi { } @:expose - static function addVideoItem(url:String, atEnd:Bool, isTemp:Bool, ?callback:() -> Void):Void { - main.addVideo(url, atEnd, isTemp, callback); + static function addVideoItem(url:String, atEnd:Bool, isTemp:Bool, ?callback:() -> + Void, doCache = false):Void { + main.addVideo(url, atEnd, isTemp, doCache, callback); } @:expose diff --git a/src/client/Main.hx b/src/client/Main.hx index 248e205..72dbf8e 100644 --- a/src/client/Main.hx +++ b/src/client/Main.hx @@ -3,6 +3,7 @@ package client; import Client.ClientData; import Types.Config; import Types.Permission; +import Types.PlayerType; import Types.VideoData; import Types.VideoDataRequest; import Types.WsEvent; @@ -25,15 +26,16 @@ import js.html.WebSocket; using ClientTools; class Main { - static inline var SETTINGS_VERSION = 4; + static inline var SETTINGS_VERSION = 5; public final settings:ClientSettings; public var isSyncActive = true; public var forceSyncNextTick = false; - public var isVideoEnabled = true; + public var isVideoEnabled(default, null) = true; public final host:String; public var globalIp(default, null) = ""; - public var isPlaylistOpen = true; + public var isPlaylistOpen(default, null) = true; + public var playersCacheSupport(default, null):Array<PlayerType> = []; final clients:Array<Client> = []; var pageTitle = document.title; @@ -74,7 +76,8 @@ class Main { latestLinks: [], latestSubs: [], hotkeysEnabled: true, - showHintList: true + showHintList: true, + checkboxes: [], } Settings.init(defaults, settingsPatcher); settings = Settings.read(); @@ -104,7 +107,7 @@ class Main { if (!player.isVideoLoaded()) return; gotFirstPageInteraction = true; player.unmute(); - player.play(); + if (!hasLeader()) player.play(); document.removeEventListener("click", onFirstInteraction); } @@ -119,6 +122,9 @@ class Main { case 3: final data:ClientSettings = data; data.showHintList = true; + case 4: + final data:ClientSettings = data; + data.checkboxes = []; case SETTINGS_VERSION, _: throw 'skipped version $version'; } @@ -236,19 +242,19 @@ class Main { return personal.hasPermission(permission, config.permissions); } - final mask = ~/\${([0-9]+)-([0-9]+)}/g; + public final urlMask = ~/\${([0-9]+)-([0-9]+)}/g; function handleUrlMasks(links:Array<String>):Void { for (link in links) { - if (!mask.match(link)) continue; - final start = Std.parseInt(mask.matched(1)); - var end = Std.parseInt(mask.matched(2)); + if (!urlMask.match(link)) continue; + final start = Std.parseInt(urlMask.matched(1)); + var end = Std.parseInt(urlMask.matched(2)); if (Math.abs(start - end) > 100) continue; final step = end > start ? -1 : 1; final i = links.indexOf(link); links.remove(link); while (end != start + step) { - links.insert(i, mask.replace(link, '$end')); + links.insert(i, urlMask.replace(link, '$end')); end += step; } } @@ -257,8 +263,11 @@ class Main { function addVideoUrl(atEnd:Bool):Void { final mediaUrl:InputElement = cast ge("#mediaurl"); final subsUrl:InputElement = cast ge("#subsurl"); - final checkbox:InputElement = cast ge("#addfromurl").querySelector(".add-temp"); - final isTemp = checkbox.checked; + final checkboxTemp:InputElement = cast ge("#addfromurl .add-temp"); + final isTemp = checkboxTemp.checked; + final checkboxCache:InputElement = cast ge("#cache-on-server"); + final doCache = checkboxCache.checked + && checkboxCache.parentElement.style.display != "none"; final url = mediaUrl.value; final subs = subsUrl.value; if (url.length == 0) return; @@ -273,17 +282,15 @@ class Main { handleUrlMasks(links); // if videos added as next, we need to load them in reverse order if (!atEnd) sortItemsForQueueNext(links); - addVideoArray(links, atEnd, isTemp); + addVideoArray(links, atEnd, isTemp, doCache); } - public function isRawPlayerLink(url:String):Bool { - return player.isRawPlayerLink(url); + public function getLinkPlayerType(url:String):PlayerType { + return player.getLinkPlayerType(url); } - public function isSingleVideoLink(url:String):Bool { - if (~/, ?(https?)/g.match(url)) return false; - if (mask.match(url)) return false; - return true; + public function isSingleVideoUrl(url:String):Bool { + return player.isSingleVideoUrl(url); } public function sortItemsForQueueNext<T>(items:Array<T>):Void { @@ -295,13 +302,14 @@ class Main { if (first != null) items.unshift(first); } - function addVideoArray(links:Array<String>, atEnd:Bool, isTemp:Bool):Void { + function addVideoArray(links:Array<String>, atEnd:Bool, isTemp:Bool, doCache:Bool):Void { if (links.length == 0) return; final link = links.shift(); - addVideo(link, atEnd, isTemp, () -> addVideoArray(links, atEnd, isTemp)); + addVideo(link, atEnd, isTemp, doCache, () -> + addVideoArray(links, atEnd, isTemp, doCache)); } - public function addVideo(url:String, atEnd:Bool, isTemp:Bool, ?callback:() -> Void):Void { + public function addVideo(url:String, atEnd:Bool, isTemp:Bool, doCache:Bool, ?callback:() -> Void):Void { final protocol = Browser.location.protocol; if (url.startsWith("/")) { final host = Browser.location.hostname; @@ -330,9 +338,10 @@ class Main { author: personal.name, duration: data.duration, isTemp: isTemp, + doCache: doCache, subs: data.subs, voiceOverTrack: data.voiceOverTrack, - isIframe: data.isIframe == true + playerType: data.playerType }, atEnd: atEnd } @@ -349,7 +358,7 @@ class Main { final mediaTitle:InputElement = cast ge("#customembed-title"); final title = mediaTitle.value; mediaTitle.value = ""; - final checkbox:InputElement = cast ge("#customembed").querySelector(".add-temp"); + final checkbox:InputElement = cast ge("#customembed .add-temp"); final isTemp = checkbox.checked; final obj:VideoDataRequest = { url: iframe, @@ -372,7 +381,8 @@ class Main { author: personal.name, duration: data.duration, isTemp: isTemp, - isIframe: true + doCache: false, + playerType: IframeType }, atEnd: atEnd } @@ -504,12 +514,14 @@ class Main { case Pause: player.setPauseIndicator(false); + updateUserList(); if (isLeader()) return; player.pause(); player.setTime(data.pause.time); case Play: player.setPauseIndicator(true); + updateUserList(); if (isLeader()) return; final synchThreshold = settings.synchThreshold; final newTime = data.play.time; @@ -596,9 +608,6 @@ class Main { case Dump: Utils.saveFile("dump.json", ApplicationJson, data.dump.data); - - case GetYoutubeVideoInfo: - // handled by event listeners like `JsApi.once` } } @@ -609,6 +618,7 @@ class Main { Settings.write(settings); globalIp = connected.globalIp; + playersCacheSupport = connected.playersCacheSupport; setConfig(connected.config); if (connected.isUnknownClient) { updateClients(connected.clients); @@ -906,7 +916,8 @@ class Main { final list = new StringBuf(); for (client in clients) { list.add('<div class="userlist_item">'); - if (client.isLeader) list.add('<ion-icon name="play"></ion-icon>'); + final iconName = player.isPaused() ? "pause" : "play"; + if (client.isLeader) list.add('<ion-icon name="$iconName"></ion-icon>'); var klass = client.isBanned ? "userlist_banned" : ""; if (client.isAdmin) klass += " userlist_owner"; list.add('<span class="$klass">${client.name}</span></div>'); @@ -1232,7 +1243,8 @@ class Main { return ~/([.*+?^${}()|[\]\\])/g.replace(regex, "\\$1"); } - public static inline function ge(id:String):Element { - return document.querySelector(id); + @:generic + public static inline function ge<T:Element>(id:String):T { + return cast document.querySelector(id); } } diff --git a/src/client/Player.hx b/src/client/Player.hx index f40c34c..70efcf9 100644 --- a/src/client/Player.hx +++ b/src/client/Player.hx @@ -1,5 +1,6 @@ package client; +import Types.PlayerType; import Types.VideoData; import Types.VideoDataRequest; import Types.VideoItem; @@ -41,7 +42,7 @@ class Player { streamable = new Streamable(main, this); players = [ youtube, - streamable + streamable, ]; iframePlayer = new Iframe(main, this); rawPlayer = new Raw(main, this); @@ -118,26 +119,40 @@ class Player { var player = players.find(player -> player.isSupportedLink(req.url)); player ??= rawPlayer; player.getVideoData(req, data -> { + data.playerType ??= player.getPlayerType(); final voiceOverTrack = voiceOverInput.value.trim(); - data.voiceOverTrack = voiceOverTrack; voiceOverInput.value = ""; + data.voiceOverTrack ??= voiceOverTrack; callback(data); }); } - public function isRawPlayerLink(url:String):Bool { - if (streamable.isSupportedLink(url)) return true; - return !players.exists(player -> player.isSupportedLink(url)); + public function getLinkPlayerType(url:String):PlayerType { + final player = players.find(player -> player.isSupportedLink(url)); + if (player == null) return rawPlayer.getPlayerType(); + return player.getPlayerType(); + } + + public function isSingleVideoUrl(url:String):Bool { + if (youtube.isSupportedLink(url)) { + if (youtube.isPlaylistUrl(url)) return false; + } + if (~/, ?(https?)/g.match(url)) return false; + if (main.urlMask.match(url)) return false; + return true; } public function getIframeData(data:VideoDataRequest, callback:(data:VideoData) -> Void):Void { - iframePlayer.getVideoData(data, callback); + iframePlayer.getVideoData(data, data -> { + data.playerType = IframeType; + callback(data); + }); } public function setVideo(i:Int):Void { if (!main.isSyncActive) return; final item = videoList.getItem(i); - setSupportedPlayer(item.url, item.isIframe); + setSupportedPlayer(item.url, item.playerType); removeActiveLabel(videoList.pos); videoList.setPos(i); @@ -190,17 +205,17 @@ class Player { needsVolumeReset = true; } - function setSupportedPlayer(url:String, isIframe:Bool):Void { + function setSupportedPlayer(url:String, playerType:PlayerType):Void { final currentPlayer = players.find(p -> p.isSupportedLink(url)); if (currentPlayer != null) setPlayer(currentPlayer); - else if (isIframe) setPlayer(iframePlayer); + else if (playerType == IframeType) setPlayer(iframePlayer); else setPlayer(rawPlayer); } public function changeVideoSrc(url:String):Void { if (!main.isVideoEnabled) return; final item:VideoItem = videoList.currentItem ?? return; - setSupportedPlayer(url, item.isIframe); + setSupportedPlayer(url, item.playerType); player.loadVideo(item.withUrl(url)); } @@ -247,10 +262,6 @@ class Player { final item = videoList.currentItem ?? return; // do not send pause if video is ended if (getTime() >= item.duration - 0.01) return; - // youtube raw fallback has around one second difference from rounded youtube duration - if (player == rawPlayer && youtube.isSupportedLink(item.url)) { - if (getTime() >= item.duration - 1) return; - } final hasAutoPause = main.hasLeaderOnPauseRequest() && videoList.length > 0 && getTime() > 1 @@ -316,7 +327,7 @@ class Player { public function addVideoItem(item:VideoItem, atEnd:Bool):Void { final url = item.url.htmlEscape(true); - final duration = item.isIframe ? "" : duration(item.duration); + final duration = item.playerType == IframeType ? "" : duration(item.duration); final itemEl = Utils.nodeFromString( '<li class="queue_entry info" title="${Lang.get("addedBy")}: ${item.author}"> <header> @@ -449,7 +460,7 @@ class Player { function totalDuration():String { var time = 0.0; for (item in videoList.getItems()) { - if (item.isIframe) continue; + if (item.playerType == IframeType) continue; time += item.duration; } return duration(time); diff --git a/src/client/players/Iframe.hx b/src/client/players/Iframe.hx index 56cf319..8a2e06e 100644 --- a/src/client/players/Iframe.hx +++ b/src/client/players/Iframe.hx @@ -1,5 +1,6 @@ package client.players; +import Types.PlayerType; import Types.VideoData; import Types.VideoDataRequest; import Types.VideoItem; @@ -18,13 +19,17 @@ class Iframe implements IPlayer { this.player = player; } + public function getPlayerType():PlayerType { + return IframeType; + } + public function isSupportedLink(url:String):Bool { return true; } public function getVideoData(data:VideoDataRequest, callback:(data:VideoData) -> Void):Void { final iframe = document.createDivElement(); - iframe.innerHTML = data.url; + iframe.innerHTML = data.url.trim(); if (isValidIframe(iframe)) { callback({duration: 99 * 60 * 60}); } else { diff --git a/src/client/players/Raw.hx b/src/client/players/Raw.hx index 5c5b7a4..7e5e50c 100644 --- a/src/client/players/Raw.hx +++ b/src/client/players/Raw.hx @@ -1,5 +1,6 @@ package client.players; +import Types.PlayerType; import Types.VideoData; import Types.VideoDataRequest; import Types.VideoItem; @@ -30,6 +31,10 @@ class Raw implements IPlayer { this.player = player; } + public function getPlayerType():PlayerType { + return RawType; + } + public function isSupportedLink(url:String):Bool { return true; } diff --git a/src/client/players/Youtube.hx b/src/client/players/Youtube.hx index 3ad9030..5a8921a 100644 --- a/src/client/players/Youtube.hx +++ b/src/client/players/Youtube.hx @@ -1,5 +1,6 @@ package client.players; +import Types.PlayerType; import Types.VideoData; import Types.VideoDataRequest; import Types.VideoItem; @@ -23,7 +24,6 @@ class Youtube implements IPlayer { var apiKey:String; var video:Element; var youtube:YoutubePlayer; - var tempYoutube:YoutubePlayer; var isLoaded = false; public function new(main:Main, player:Player) { @@ -31,6 +31,10 @@ class Youtube implements IPlayer { this.player = player; } + public function getPlayerType():PlayerType { + return YoutubeType; + } + public function isSupportedLink(url:String):Bool { return extractVideoId(url) != "" || extractPlaylistId(url) != ""; } @@ -43,6 +47,10 @@ class Youtube implements IPlayer { return YoutubeUtils.extractPlaylistId(url); } + public function isPlaylistUrl(url:String):Bool { + return extractVideoId(url) == "" && extractPlaylistId(url) != ""; + } + final matchHours = ~/([0-9]+)H/; final matchMinutes = ~/([0-9]+)M/; final matchSeconds = ~/([0-9]+)S/; @@ -93,7 +101,7 @@ class Youtube implements IPlayer { url: '<iframe src="https://www.youtube.com/embed/$id?autoplay=1$mute" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>', - isIframe: true + playerType: IframeType }); continue; } @@ -168,6 +176,7 @@ class Youtube implements IPlayer { final video = document.createDivElement(); video.id = "temp-videoplayer"; Utils.prepend(playerEl, video); + var tempYoutube:YoutubePlayer = null; tempYoutube = new YoutubePlayer(video.id, { videoId: extractVideoId(url), playerVars: { @@ -181,12 +190,14 @@ class Youtube implements IPlayer { callback({ duration: tempYoutube.getDuration() }); + tempYoutube.destroy(); }, onError: e -> { // TODO message error codes trace('Error ${e.data}'); if (playerEl.contains(video)) playerEl.removeChild(video); callback({duration: 0}); + tempYoutube.destroy(); } } }); @@ -243,49 +254,13 @@ class Youtube implements IPlayer { onError: e -> { // TODO message error codes trace('Error ${e.data}'); - final item = player.getCurrentItem() ?? return; - rawSourceFallback(item.url); + // final item = player.getCurrentItem() ?? return; + // rawSourceFallback(item.url); } } }); } - function rawSourceFallback(url:String):Void { - JsApi.once(GetYoutubeVideoInfo, event -> { - final data = event.getYoutubeVideoInfo; - final info = data.response; - final format = getBestStreamFormat(info) ?? { - trace("format not found in response info:"); - trace(info); - return; - }; - player.changeVideoSrc(format.url); - }); - main.send({ - type: GetYoutubeVideoInfo, - getYoutubeVideoInfo: { - url: url - } - }); - } - - function getBestStreamFormat(info:YouTubeVideoInfo):Null<YoutubeVideoFormat> { - info.formats ??= []; - info.adaptiveFormats ??= []; - final formats = info.adaptiveFormats.concat(info.formats); - trace(formats); - final qPriority = [1080, 720, 480, 360, 240]; - for (q in qPriority) { - final quality = '${q}p'; - for (format in formats) { - if (format.audioQuality == null) continue; // no sound - if (format.width == null) continue; // no video - if (format.qualityLabel == quality) return format; - } - } - return null; - } - public function removeVideo():Void { if (video == null) return; isLoaded = false; diff --git a/src/server/Cache.hx b/src/server/Cache.hx new file mode 100644 index 0000000..8348476 --- /dev/null +++ b/src/server/Cache.hx @@ -0,0 +1,165 @@ +package server; + +import js.lib.Promise; +import js.node.ChildProcess; +import js.node.Fs.Fs; +import js.node.stream.Readable; +import sys.FileSystem; +import utils.YoutubeUtils; + +class Cache { + final main:Main; + final cacheDir:String; + + public final cachedFiles:Array<String> = []; + + public final isYtReady = false; + + /** In bytes **/ + public var storageLimit = 3 * 1024 * 1024 * 1024; + + public function new(main:Main, cacheDir:String) { + this.main = main; + this.cacheDir = cacheDir; + Utils.ensureDir(cacheDir); + isYtReady = checkYtDeps(); + } + + function checkYtDeps():Bool { + final ytdl = try { + untyped require("@distube/ytdl-core"); + } catch (e) { + return false; + } + try { + ChildProcess.execSync("ffmpeg -version", {stdio: "ignore", timeout: 3000}); + return true; + } catch (e) { + return false; + } + } + + function log(client:Client, msg:String):Void { + main.serverMessage(client, msg); + trace(msg); + } + + public function cacheYoutubeVideo(client:Client, url:String, callback:(name:String) -> Void) { + if (!isYtReady) { + 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)."); + return; + } + final videoId = YoutubeUtils.extractVideoId(url); + if (videoId == "") { + log(client, 'Error: youtube video id not found in url: $url'); + return; + } + final outName = videoId + ".mp4"; + if (cachedFiles.contains(outName)) { + callback(outName); + return; + } + final ytdl:Dynamic = untyped require("@distube/ytdl-core"); + log(client, 'Caching $url to $outName...'); + final opts = {playerClients: ["IOS", "WEB_CREATOR"]}; + final promise:Promise<YouTubeVideoInfo> = ytdl.getInfo(url, opts); + 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 -> { + return item.audioCodec?.startsWith("mp4a"); + }), {quality: "highestaudio"}); + } catch (e) { + log(client, "Error: audio format not found"); + trace(e); + trace(info.formats); + return; + } + final videoFormat = getBestYoutubeVideoFormat(info.formats) ?? { + log(client, "Error: video format not found"); + trace(info.formats); + 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)); + + var count = 0; + function onComplete(type:String):Void { + count++; + log(client, '$type track downloaded ($count/2)'); + if (count < 2) return; + 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, + stdio: "ignore" + }); + process.on("close", (code:Int) -> { + if (code != 0) { + log(client, 'Error: ffmpeg closed with code $code'); + return; + } + final inVideo = '$cacheDir/input-video'; + final inAudio = '$cacheDir/input-audio'; + if (FileSystem.exists(inVideo)) FileSystem.deleteFile(inVideo); + if (FileSystem.exists(inAudio)) FileSystem.deleteFile(inAudio); + + cachedFiles.push(outName); + removeOlderCache(); + + 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); + // }); + }).catchError(err -> { + log(client, "" + err); + }); + } + + function removeOlderCache():Void { + while (getUsedSpace() > storageLimit) { + final name = cachedFiles.shift(); + final path = '$cacheDir/$name'; + if (FileSystem.exists(path)) FileSystem.deleteFile(path); + } + } + + function getUsedSpace():Int { + var total = 0; + for (name in cachedFiles) { + final path = '$cacheDir/$name'; + total += FileSystem.stat(path).size; + } + return total; + } + + function getBestYoutubeVideoFormat(formats:Array<YoutubeVideoFormat>):Null<YoutubeVideoFormat> { + final qPriority = [1080, 720, 480, 360, 240]; + for (q in qPriority) { + final quality = '${q}p'; + for (format in formats) { + if (format.videoCodec == null) continue; + if (format.qualityLabel == quality) return format; + } + } + return null; + } +} diff --git a/src/server/Main.hx b/src/server/Main.hx index 9c2f6e2..b257e91 100644 --- a/src/server/Main.hx +++ b/src/server/Main.hx @@ -5,6 +5,7 @@ import Types.Config; import Types.FlashbackItem; import Types.Message; import Types.Permission; +import Types.PlayerType; import Types.UserList; import Types.VideoItem; import Types.WsEvent; @@ -48,12 +49,14 @@ class Main { var wss:WSServer; final localIp:String; var globalIp:String; + final playersCacheSupport:Array<PlayerType> = []; var port:Int; final userList:UserList; final clients:Array<Client> = []; final freeIds:Array<Int> = []; final wsEventParser = new JsonParser<WsEvent>(); final consoleInput:ConsoleInput; + final cache:Cache; final videoList = new VideoList(); final videoTimer = new VideoTimer(); final messages:Array<Message> = []; @@ -99,9 +102,12 @@ class Main { logger = new Logger(logsDir, 10, verbose); consoleInput = new ConsoleInput(this); consoleInput.initConsoleInput(); + cache = new Cache(this, '$rootDir/user/res/cache'); + if (cache.isYtReady) playersCacheSupport.push(YoutubeType); initIntergationHandlers(); loadState(); config = loadUserConfig(); + cache.storageLimit = cast config.cacheStorageLimitGiB * 1024 * 1024 * 1024; userList = loadUsers(); config.isVerbose = verbose; config.salt = generateConfigSalt(); @@ -276,7 +282,8 @@ class Main { time: videoTimer.getTime(), paused: videoTimer.isPaused() }, - flashbacks: flashbacks + flashbacks: flashbacks, + cachedFiles: cache.cachedFiles } } @@ -285,6 +292,9 @@ class Main { if (!FileSystem.exists(statePath)) return; trace("Loading state..."); final state:ServerState = Json.parse(File.getContent(statePath)); + state.flashbacks ??= []; + state.cachedFiles ??= []; + videoList.setItems(state.videoList); videoList.isOpen = state.isPlaylistOpen; videoList.setPos(state.itemPos); @@ -293,7 +303,10 @@ class Main { for (message in state.messages) messages.push(message); flashbacks.resize(0); - for (flashback in state.flashbacks ?? []) flashbacks.push(flashback); + for (flashback in state.flashbacks) flashbacks.push(flashback); + + cache.cachedFiles.resize(0); + for (name in state.cachedFiles) cache.cachedFiles.push(name); videoTimer.start(); videoTimer.setTime(state.timer.time); @@ -479,7 +492,8 @@ class Main { videoList: videoList.getItems(), isPlaylistOpen: videoList.isOpen, itemPos: videoList.pos, - globalIp: globalIp + globalIp: globalIp, + playersCacheSupport: playersCacheSupport, } }); sendClientListExcept(client); @@ -623,17 +637,6 @@ class Main { broadcast(data); case ServerMessage: - case GetYoutubeVideoInfo: - final url = data.getYoutubeVideoInfo.url; - YoutubeFallback.getInfo(url, info -> { - send(client, { - type: data.type, - getYoutubeVideoInfo: { - url: url, - response: info - } - }); - }); case AddVideo: if (isPlaylistLockedFor(client)) return; if (!checkPermission(client, AddVideoPerm)) return; @@ -660,11 +663,23 @@ class Main { serverMessage(client, "videoAlreadyExistsError"); return; } - data.addVideo.item = item; - videoList.addItem(item, data.addVideo.atEnd); - broadcast(data); - // Initial timer start if VideoLoaded is not happen - if (videoList.length == 1) restartWaitTimer(); + + inline function addVideo():Void { + data.addVideo.item = item; + videoList.addItem(item, data.addVideo.atEnd); + broadcast(data); + // Initial timer start if VideoLoaded is not happen + if (videoList.length == 1) restartWaitTimer(); + } + if (!item.doCache) { + addVideo(); + } else { + cache.cacheYoutubeVideo(client, item.url, (name) -> { + item = item.withUrl('/cache/$name'); + if (item.duration > 1) item.duration -= 1; + addVideo(); + }); + } case VideoLoaded: // Called if client loads next video and can play it @@ -939,7 +954,7 @@ class Main { }); } - function serverMessage(client:Client, textId:String):Void { + public function serverMessage(client:Client, textId:String):Void { send(client, { type: ServerMessage, serverMessage: { diff --git a/src/server/ServerState.hx b/src/server/ServerState.hx index 0369353..41f86ba 100644 --- a/src/server/ServerState.hx +++ b/src/server/ServerState.hx @@ -12,5 +12,6 @@ typedef ServerState = { timer:{ time:Float, paused:Bool }, - ?flashbacks:Array<FlashbackItem> + ?flashbacks:Array<FlashbackItem>, + ?cachedFiles:Array<String>, } diff --git a/src/server/YoutubeFallback.hx b/src/server/YoutubeFallback.hx deleted file mode 100644 index 5360283..0000000 --- a/src/server/YoutubeFallback.hx +++ /dev/null @@ -1,142 +0,0 @@ -package server; - -import haxe.Json; -import js.lib.Function; -import js.lib.Object; -import js.lib.Promise; -import js.node.Https.Https; -import js.node.Https.HttpsRequestOptions; -import js.node.url.URLSearchParams; -import utils.YoutubeUtils; - -class YoutubeFallback { - static function httpsGet( - url:String, - ?options:HttpsRequestOptions, - ?callback:(status:Int, data:String) -> Void - ):Void { - final request = Https.get(url, options, res -> { - var data = ""; - res.on("data", chunk -> data += chunk.toString()); - res.on("end", () -> callback(res.statusCode, data)); - }); - request.on("error", err -> { - trace(url); - trace("request error: ", err); - }); - } - - public static function resolvePlayerResponse(watchHtml:String):String { - if (watchHtml == null) return ""; - final resReg = ~/ytInitialPlayerResponse = (.*)}}};/; - var matches = resReg.match(watchHtml); - return matches ? resReg.matched(1) + "}}}" : ""; - } - - public static function resoleM3U8Link(watchHtml:String):Null<String> { - if (watchHtml == null) return null; - final hlsReg = ~/hlsManifestUrl":"(.*\/file\/index\.m3u8)/; - return hlsReg.match(watchHtml) ? hlsReg.matched(1) : null; - } - - public static function buildDecoder(watchHtml:String, callback:(decoder:(cipher:String) -> String) -> Void):Void { - if (watchHtml == null) return callback(null); - - final jsFileUrlReg = ~/\/s\/player\/[A-Za-z0-9]+\/[A-Za-z0-9_.]+\/[A-Za-z0-9_]+\/base\.js/; - if (!jsFileUrlReg.match(watchHtml)) return callback(null); - - final url = "https://www.youtube.com" + jsFileUrlReg.matched(0); - httpsGet(url, {}, (status, jsFileContent) -> { - final funcReg = ~/function.*\.split\(""\).*\.join\(""\)}/; - if (!funcReg.match(jsFileContent)) return callback(null); - - final decodeFunction = funcReg.matched(0); - final varNameReg = ~/\.split\(""\);([a-zA-Z0-9]+)\./i; - if (!varNameReg.match(decodeFunction)) return callback(null); - - final varStartIndex = jsFileContent.indexOf("var " + varNameReg.matched(1) + "={"); - if (varStartIndex < 0) return callback(null); - - final varEndIndex = jsFileContent.indexOf("}};", varStartIndex); - if (varEndIndex < 0) return callback(null); - - final varDeclares = jsFileContent.substring(varStartIndex, varEndIndex + 3); - if (varDeclares.length == 0) return callback(null); - - callback(signatureCipher -> { - final params = new URLSearchParams(signatureCipher); - final obj = Object.fromEntries(params); - final signature = obj.s; - final signatureParam = obj.sp ?? "signature"; - final url = obj.url; - final decodedSignature = new Function(' - "use strict"; - $varDeclares - return ($decodeFunction)("$signature"); - ').call(null); - return '$url&$signatureParam=${untyped encodeURIComponent(decodedSignature)}'; - }); - }); - } - - public static function getInfo(url:String, callback:(info:Null<YouTubeVideoInfo>) -> Void):Void { - final videoId = YoutubeUtils.extractVideoId(url); - if (videoId.length == 0) { - trace("youtube videoId is not found"); - return callback(null); - } - - final url = 'https://www.youtube.com/watch?v=$videoId'; - httpsGet(url, {}, (status, data) -> { - if (status != 200 || data.length == 0) { - trace("Cannot get youtube video response"); - return callback(null); - } - - final ytInitialPlayerResponse = resolvePlayerResponse(data); - final parsedResponse = Json.parse(ytInitialPlayerResponse); - final streamingData:YouTubeVideoInfo = parsedResponse.streamingData ?? cast {}; - streamingData.formats ??= []; - streamingData.adaptiveFormats ??= []; - var formats:Array<YoutubeVideoFormat> = streamingData.formats.concat(streamingData.adaptiveFormats); - - final promises:Array<Promise<Any>> = []; - - final isEncryptedVideo = formats.exists(it -> it.signatureCipher != null); - if (isEncryptedVideo) { - final promise = new Promise((resolve, reject) -> { - buildDecoder(data, decoder -> { - if (decoder != null) { - formats = formats.map(item -> { - if (item.url != null || item.signatureCipher == null) return item; - - item.url = decoder(item.signatureCipher); - item.signatureCipher = null; - return item; - }); - } - resolve(null); - }); - }); - promises.push(promise); - } - - Promise.all(promises).then(_ -> { - final result:YouTubeVideoInfo = { - videoDetails: parsedResponse.videoDetails ?? cast {}, - formats: formats.filter(format -> format.url != null) - }; - if (result.videoDetails.isLiveContent) { - final m3u8Link = resoleM3U8Link(data); - try { - result.liveData = { - manifestUrl: m3u8Link, - // data: m3u8Parser.getResult() - }; - } - } - callback(result); - }); - }); - } -} diff --git a/src/utils/YoutubeUtils.hx b/src/utils/YoutubeUtils.hx index 7429565..0bb8016 100644 --- a/src/utils/YoutubeUtils.hx +++ b/src/utils/YoutubeUtils.hx @@ -41,7 +41,11 @@ typedef YoutubeVideoFormat = { ?indexRange:{start:Int, end:Int}, ?audioQuality:String, // AUDIO_QUALITY_LOW ?audioSampleRate:Int, - ?audioChannels:Int + ?audioChannels:Int, + + ?container:String, + ?videoCodec:String, + ?audioCodec:String, } typedef YouTubeVideoInfo = { diff --git a/test/tests/TestServer.hx b/test/tests/TestServer.hx index f1bc874..abdbf8f 100644 --- a/test/tests/TestServer.hx +++ b/test/tests/TestServer.hx @@ -96,7 +96,8 @@ class TestServer extends Test { author: "", duration: 30, isTemp: true, - isIframe: false + playerType: RawType, + doCache: false }, atEnd: true } @@ -146,7 +147,8 @@ class TestServer extends Test { author: "", duration: 30, isTemp: true, - isIframe: false + playerType: RawType, + doCache: false }, atEnd: true } |
